使用WireGuard和DNSCrypt在OpenWrt路由器上精确定位PKH阻止

与类似材料有什么区别?


  • 纯OpenWrt实现
  • 使用WireGuard
  • 路由器的配置是使用OpenWrt配置进行组织的,而不是一堆脚本
  • 在某些情况下,重新启动网络并重新启动
  • 它消耗很少的路由器资源:锁定的子网包含在iptables中,而不包含在路由表中。 什么使您即使在功能弱的设备上也可以部署此业务
  • 使用Ansible进行自动配置(路由器上不需要python)

影片版本



为什么选择OpenWrt和WireGuard?


OpenWrt已安装在许多型号的soho路由器上,可以根据您的需要进行配置和扩展。 现在,许多路由器固件都是OpenWrt的附加组件。


之所以使用Wireguard,是因为它安装简便,并且通过隧道的传输速度很高。


关于WireGuard的一些知识


在我们的例子中,服务器是ILV外部的VPS,客户端是家庭中的OpenWrt路由器。 当你想去 Pornolab 通过电报,您的路由器将通过WireGuard引导流量通过服务器。
WireGuard会建立站点到站点的连接,即 服务器和客户端都具有配置的服务器和客户端。 如果不清楚,当您看到配置时,它将变得清晰。


服务器和客户端具有自己的私钥和公钥。


在服务器上配置WireGuard


我正在Ubuntu 18.04上进行所有操作,但是在官方文档中有针对所有已知操作系统的安装说明


安装方式


sudo add-apt-repository ppa:wireguard/wireguard 

如果发生错误
 sudo: add-apt-repository: command not found 


安装software-properties-common-该软件包提供了添加和删除PPA的功能
 sudo apt install software-properties-common 


 sudo apt update sudo apt install wireguard-dkms wireguard-tools 

我们为服务器生成密钥。 为了方便起见,我们将密钥保存在WireGuard目录中。


 cd /etc/wireguard/ wg genkey | tee privatekey-server | wg pubkey > publickey-server 

因此,在privatekey-server文件中将有一个私钥,在publickey-server中将有一个公钥。
我们还将立即为客户生成一个密钥:


 wg genkey | tee privatekey-client | wg pubkey > publickey-client 


构型


该配置存储在/etc/wireguard/wg0.conf中。 服务器端看起来像这样:


 [Interface] Address = 192.168.100.1 PrivateKey = privatekey-server ListenPort = 51820 PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE 

地址 -wg接口的地址(隧道内部的地址)
私钥-私钥(私钥服务器)
ListenPort-服务正在等待连接的端口


好吧,我们会伪装,因为我们将使用此服务器访问Internet
请注意,您所用的接口名称可能有所不同:


客户部分


 [Peer] PublicKey = publickey-client AllowedIPs = 192.168.100.3/24 

PublicKey-我们路由器的公钥(publickey-client)
AllowedIP是可通过此隧道使用的子网。 服务器仅需要访问客户端地址。


这两部分都存储在一个配置中。


在重新启动时启用自动启动:


 systemctl enable wg-quick@wg0 

我们使服务器成为路由器:


 sysctl -w net.ipv4.ip_forward=1 

配置防火墙。 假设我们的服务器上只有WireGuard和ssh:


 sudo iptables -A INPUT -i lo -j ACCEPT sudo iptables -A INPUT -p udp -m udp --dport 51820 -j ACCEPT sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT sudo iptables -A INPUT -p icmp -j ACCEPT sudo iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT sudo iptables -A INPUT -j DROP 

保存iptables配置:


 sudo apt-get install iptables-persistent sudo netfilter-persistent save 

我们第一次手动提高wg界面:


 wg-quick up wg0 


WireGuard服务器已准备就绪。


UPD 06/27/19如果您的提供商仍然使用PPoE,则需要添加一条规则。 谢谢denix123


 iptables -t mangle -I POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu 

路由器设定


我在小米mi 3G和华硕RT-N16上使用OpenWrt版本18.06.1。


路由器的逻辑


我们加载列表,将它们放在iptables中,iptables用0x1标记标记这些列表中的所有地址。 此外,所有标记为0x1的数据包都进入单独的路由表,所有落入该路由表的数据包都通过wg接口。



套件安装


至于闪存上的占用空间,所有内容大约需要0.9MB。 如果您的位置非常糟糕,请用wget替换curl,并且可能不需要安装dnscrypt-proxy。


我们把包裹。 在OpenWrt中,这可以通过opkg软件包管理器轻松完成:


 opkg update opkg install ipset wireguard curl 

下载清单


通过OpenWrt的标准功能可以完成的所有操作都通过它们完成。 其他所有内容(热插拔除外)都放在一个小脚本中:


 #!/bin/sh START=99 dir=/tmp/lst mkdir -p $dir echo "Run download lists" curl -z $dir/subnet.lst https://antifilter.download/list/subnet.lst --output $dir/subnet.lst curl -z $dir/ipsum.lst https://antifilter.download/list/ipsum.lst --output $dir/ipsum.lst echo "Firewall restart" /etc/init.d/firewall restart 

禁止子网和地址的列表是通过文件获取的。 对于他们,我们在/ tmp中创建一个目录。 在/ tmp中-因为它是RAM,所以OpenWrt的这种功能非常方便。 再次在路由器的ROM上写入内容是不值得的。


我们用antifilter.download curl抽出列表,z标志意味着curl仅在远程文件与本地文件不同或本地文件不存在时才下载文件,例如加载路由器时。


subnet.lst-阻止的子网的列表;它不会经常更改。
ipsum.lst是被阻止地址的列表,由掩码进行汇总。 而不是15万条记录,我们得到了1.5万条-方便。


在拥有文件之后,我们将重新启动防火墙,这对于使ipset正常运行并将列表添加到iptables是必要的,我们将在/ etc / config / firewall中配置ipset。


我们在/etc/init.d/中添加的脚本称为hirkn。 使它可执行


 chmod +x /etc/init.d/hirkn 

现在我们不仅有一个脚本,而且还有一个完整的服务。 为了使它在启动时启动,我们在/etc/rc.d中进行符号链接。 我们需要它在所有其他服务之后启动,因此我们使用S99前缀


 ln -s /etc/init.d/hirkn /etc/rc.d/S99hirkn 

列表需要不时更新,我们在cron中添加记录:


 crontab -e 

 0 4 * * * /etc/init.d/hirkn 

每天更新一次似乎足够了。 请记住,将列表添加到ipset时,网络断开,在我的情况下为2秒。
UPD :如果您不想休息,则sigo73Grayver在注释中建议了如何执行此操作。


同时打开表冠,默认情况下它被禁用:


 /etc/init.d/cron enable /etc/init.d/cron start 

路由表配置


只需添加以下行,即可为通过隧道的流量创建路由表:


 99 vpn 

到/ etc / iproute2 / rt_tables文件。


您可以使用以下命令通过wg接口为“ vpn”表创建默认路由:


 ip route add table vpn default dev wg0 

但是,当您重新启动网络时,路由消失了,因此我们在/etc/hotplug.d/iface/目录中创建了30-rknroute文件,其内容简单:


 #!/bin/sh ip route add table vpn default dev wg0 

这意味着当您打开/关闭接口时,将添加我们的路由。 因此,此路由将始终被注册。


网络配置


我们需要为标记为0x1的数据包配置WireGuard和规则。


WireGuard配置位于/ etc / config / network中


“服务器”部分:


 config interface 'wg0' option private_key 'privatekey-client' list addresses '192.168.100.3/24' option listen_port '51820' option proto 'wireguard' 

private_key是我们在配置服务器时生成的privatekey-client
列出地址 -wg接口地址
listen_port -WireGuard接受连接的端口。 但是连接将通过服务器上的端口进行,因此在这里我们不会为其打开防火墙上的端口
原型 -指定协议,以便openwrt可以理解这是WireGuard配置


“客户”部分:


 config wireguard_wg0 option public_key 'publickey-server' option allowed_ips '0.0.0.0/0' option route_allowed_ips '0' option endpoint_host 'wg-server-ip' option persistent_keepalive '25' option endpoint_port '51820' 

public_key-公共密钥服务器密钥
allowed_ips-流量可以通过隧道进入的子网,在我们的情况下,不需要限制,因此为0.0.0.0/0
route_allowed_ips-一个标志,该标志通过wg接口为allowed_ips参数为列出的网络建立路由。 在我们的情况下,这是没有必要的,iptables可以完成这项工作
endpoint_host-我们的wg服务器的ip / URL
sistence_keepalive-发送数据包以支持连接之后的时间间隔
Endpoint_port-服务器上的Wireguard端口


我们还将在网络配置中添加一条规则,该规则会将所有标记为0x1的流量发送到路由表“ vpn”:


 config rule option priority '100' option lookup 'vpn' option mark '0x1' 

防火墙配置


我们添加了两个标记包的规则,它们不适合openwrt UCI语法,因此我们将它们“按原样”添加到/etc/firewall.user中。
UPDGrayver 建议它们非常合适。 我们在设置ipset之后设置它们


防火墙配置在/ etc / config / firewall中


添加一个区域用于线卫。 在openwrt中,区域是iptables中的自定义链。 因此,将创建具有一个/多个接口的区域,并且规则已经挂在其上。 wg的区域如下所示:


 config zone option name 'wg' option family 'ipv4' option masq '1' option output 'ACCEPT' option forward 'REJECT' option input 'REJECT' option mtu_fix '1' option network 'wg0' 

我们仅允许流量退出接口并启用伪装。


现在,您需要启用从lan区域到wg区域的转发:


 config forwarding option src 'lan' option dest 'wg' 

好吧,最后一件事是使用ipset在iptables中创建列表:


 config ipset option name 'vpn_subnets' option storage 'hash' option loadfile '/tmp/lst/subnet.lst' option match 'dst_net' config ipset option name 'vpn_ipsum' option storage 'hash' option loadfile '/tmp/lst/ipsum.lst' option match 'dst_net' 

loadfile-我们从中获取列表的文件
名称 -我们列表的名称
storagematch-在这里我们指定如何存储以及什么类型的数据。 我们将存储“子网”类型


UPD :如果要使用单个IP地址的列表,则需要增加ipset列表的大小。 在配置ipset中添加


  option hashsize '1000000' option maxelem '1000000' 

否则你会得到一个错误


 ipset v6.38: Hash is full, cannot add more elements 

UPD :添加两个用于标记包装的规则


 config rule option name 'mark_subnet' option src 'lan' option proto 'all' option ipset 'vpn_subnets' option set_mark '0x1' option target 'MARK' config rule option name 'mark_ipsum' option src 'lan' option proto 'all' option ipset 'vpn_ipsum' option set_mark '0x1' option target 'MARK' 

这些规则意味着从vpn_subnets和vpn_ipsum列表进入子网的所有数据包都必须标记为0x1。


之后,我们重新启动网络:


 /etc/init.d/network restart 


并运行脚本:


 /etc/init.d/hirkn 


编写完脚本后,一切都会为您工作。 检查路由器客户端上的路由:


 mtr/traceroute telegram.org/linkedin.com 


奖励配置DNSCrypt


怎么了 您的提供商可以小心地替换被阻止资源的ip地址,从而使用存根将您重定向到您的ip,那么,在这种情况下,我们的IP旁路将无济于事。 对于替换,不一定总是使用提供程序的dns服务器,您的请求可以被拦截,答复将被替换。 好的,顺便说一下,不仅提供者可以做到这一点。


 opkg install dnscrpt-proxy 

像这样配置/ etc / config / dnscrypt-proxy配置:


 config dnscrypt-proxy ns1 option address '127.0.0.1' option port '5353' option resolver 'cpunks-ru' 

因此,我们在本地主机上可用的端口5353上提供了dnscrypt服务。


解析器是支持加密的DNS服务器。 在路由器上,文件/usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv包含发布已安装dnscrypt版本时的可用服务器列表。 通常,这里是https://dnscrypt.info/public-servers/所有可用的dnscrypt服务器。 您可以选择其他解析器和/或添加服务器以实现容错功能。 请记住,为了使DNSCrypt与选定的解析器一起使用,必须在dnscrypt-resolvers.csv中指定它。


我们将dnsmasq配置为与dnscrypt一起使用。 在/ etc / config / dhcp中,将以下行注释掉:


 option resolvfile '/tmp/resolv.conf.auto' 

这样就不会涉及提供商dns服务器。


并添加:


  list server '/pool.ntp.org/208.67.222.222' list server '127.0.0.1#5353' 

列表服务器的“ domain / ip_dns”条目指示要使用哪个dns服务器来解析指定的域。 因此,我们不使用dnscrypt进行ntp同步-对于dnscrypt服务而言,拥有当前时间很重要。


路由器加载时,hirkn脚本的运行速度比dnscrypt启动的速度快,因此antifilter.download域无法解析,并且列表也不会下载。 您可以提出一些延迟或提出其他建议,但到目前为止,我仍然没有理由。
UPD :需要添加一行


 START=99 

隐藏脚本


结果,我们在配置中得到了这样的插入:


  #option resolvfile '/tmp/resolv.conf.auto' list server '/pool.ntp.org/208.67.222.222' list server '127.0.0.1#5353' 

UPD :在某些设备上,无论如何,DNSCrypt都会在脚本之后启动。 解决此问题的最简单方法是将行添加到/ etc / config / dhcp


  list server '/antifilter.download/208.67.222.222' 

禁用对WAN接口使用提供程序DNS
在/ etc / config / network中添加该行


 option peerdns '0' 

到wan接口。
我们得到这个配置


 config interface 'wan' option ifname 'eth0.2' option proto 'dhcp' option peerdns '0' 

重新启动网络


 /etc/init.d/network restart 

添加到启动并启动dnscrypt:


 /etc/init.d/dnscrypt-proxy enable /etc/init.d/dnscrypt-proxy start 

重新启动dnsmasq:


 /etc/init.d/dnsmasq restart 


不使用DNSCrypt和使用DNSCrypt的工作插图


通过Ansible自动部署


剧本和模板在github上 。 它使用模块 ,路由器上不需要python,并且支持uci。 我试图确保您的OpenWrt配置保持不变,但还是要小心。


安装gekmihesg / ansible-openwrt模块:


 ansible-galaxy install gekmihesg.openwrt 

复制剧本和tempeyta:


 cd /etc/ansible git clone https://github.com/itdoginfo/ansible-openwrt-hirkn mv ansible-openwrt-hirkn/* . rm -rf ansible-openwrt-hirkn 

将路由器添加到主机:


 [openwrt] 192.168.1.1 

将您的变量替换为hirkn.yml:


  vars: ansible_template_dir: /etc/ansible/templates/ wg_server_address: wg_server_ip/url wg_private_key: privatekey-client wg_public_key: publickey-server wg_listen_port: 51820 wg_client_port: 51820 wg_client_address: 192.168.100.3/24 

确保设置:


wg_server_address -IP / URL Wireguard服务器
wg_private_keywg_public_key-客户端和公共服务器的私钥
其余的不能更改或更改,具体取决于WireGuard服务器的配置方式


启动剧本


 ansible-playbook playbooks/hirkn.yml 

完成剧本后,路由器将立即开始通过Wireguard服务器绕过锁。


为什么不使用BGP?


在openwrt下,有两个实现BGP的实用程序-quagga和bird。 Quagg我无法从反过滤器收集数据。 伯德距离该服务仅几步之遥,但是不幸的是,我不明白如何强制将默认接口添加到接收的子网中。 (我将很高兴知道该如何实现)。


在有关此类文章的评论中,我看到人们的路由器在将列表放入路由表中的过程中,已经“考虑周全”。 通过ipset实现后,当您向他提供15,000个子网的列表时,我的小米mi 3G会思考2秒(Asus rt-n16持续5秒)。 经过进一步的工作,我没有注意到处理器上的负载。


所有材料并非呼吁采取行动,而是为了熟悉Linux OS的功能而提出的。

Source: https://habr.com/ru/post/zh-CN440030/


All Articles