与类似材料有什么区别?
- 纯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的标准功能可以完成的所有操作都通过它们完成。 其他所有内容(热插拔除外)都放在一个小脚本中:
禁止子网和地址的列表是通过文件获取的。 对于他们,我们在/ 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 :如果您不想休息,则sigo73和Grayver在注释中建议了如何执行此操作。
同时打开表冠,默认情况下它被禁用:
/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文件,其内容简单:
这意味着当您打开/关闭接口时,将添加我们的路由。 因此,此路由将始终被注册。
网络配置
我们需要为标记为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中。
UPD : Grayver 建议它们非常合适。 我们在设置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-我们从中获取列表的文件
名称 -我们列表的名称
storage , match-在这里我们指定如何存储以及什么类型的数据。 我们将存储“子网”类型
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
隐藏脚本
结果,我们在配置中得到了这样的插入:
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_key , wg_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的功能而提出的。