从 OpenVPN 切换到 WireGuard,将网络合并为一个 L2 网络

从 OpenVPN 切换到 WireGuard,将网络合并为一个 L2 网络

我想分享一下我的经验,将三个地理位置偏远的公寓中的网络(每个公寓都使用 OpenWRT 路由器作为网关)合并为一个公共网络。 当选择在具有子网路由的 L3 和具有桥接的 L2 之间组合网络的方法时,当所有网络节点都位于同一子网中时,优先考虑第二种方法,该方法更难以配置,但提供了更大的机会,因为计划在正在创建的网络中透明地使用网络唤醒和 DLNA 技术。

第 1 部分:背景

最初选择 OpenVPN 作为实现此任务的协议,因为首先,它可以创建一个可以毫无问题地添加到网桥的分接设备,其次,OpenVPN 支持通过 TCP 协议进行操作,这也很重要,因为没有的公寓有专用的 IP 地址,我无法使用 STUN,因为我的提供商出于某种原因阻止了来自其网络的传入 UDP 连接,而 TCP 协议允许我使用 SSH 将 VPN 服务器端口转发到租用的 VPS。 是的,这种方法会带来很大的负载,因为数据被加密两次,但我不想将 VPS 引入我的专用网络,因为仍然存在第三方控制它的风险,因此,拥有这样的设备在我的家庭网络上是非常不可取的,因此决定支付大量开销来支付安全费用。

为了转发计划部署服务器的路由器上的端口,使用了 sshtunnel 程序。 我不会描述其复杂的配置 - 它很容易完成,我只是注意到它的任务是将 TCP 端口 1194 从路由器转发到 VPS。 接下来,在连接到 br-lan 网桥的 tap0 设备上配置 OpenVPN 服务器。 检查了笔记本电脑与新创建的服务器的连接后,很明显,端口转发的想法是合理的,我的笔记本电脑成为了路由器网络的成员,尽管它实际上并不在其中。

只剩下一件小事要做:需要在不同的公寓中分配 IP 地址,这样它们就不会发生冲突,并将路由器配置为 OpenVPN 客户端。
选择以下路由器 IP 地址和 DHCP 服务器范围:

  • 192.168.10.1 有范围 192.168.10.2 - 192.168.10.80 对于服务器
  • 192.168.10.100 有范围 192.168.10.101 - 192.168.10.149 用于2号公寓的路由器
  • 192.168.10.150 有范围 192.168.10.151 - 192.168.10.199 用于3号公寓的路由器

还需要通过将以下行添加到其配置中,将这些地址准确地分配给 OpenVPN 服务器的客户端路由器:

ifconfig-pool-persist /etc/openvpn/ipp.txt 0

并将以下行添加到 /etc/openvpn/ipp.txt 文件中:

flat1_id 192.168.10.100
flat2_id 192.168.10.150

其中 flat1_id 和 flat2_id 是创建用于连接 OpenVPN 的证书时指定的设备名称

接下来,在路由器上配置 OpenVPN 客户端,并将两台路由器上的 tap0 设备添加到 br-lan 网桥。 在这个阶段,一切似乎都很好,因为所有三个网络都可以互相看到并作为一个整体工作。 然而,出现了一个不太令人愉快的细节:有时设备可能会收到并非来自路由器的 IP 地址,从而产生随之而来的所有后果。 由于某种原因,其中一间公寓的路由器没有时间及时响应 DHCPDISCOVER,并且设备收到了非预期的地址。 我意识到我需要在每个路由器上的 tap0 中过滤此类请求,但事实证明,如果该设备是网桥的一部分,则 iptables 无法与该设备一起工作,并且 ebtables 必须来帮助我。 令我遗憾的是,它不在我的固件中,我必须为每个设备重建图像。 通过这样做并将这些行添加到每个路由器的 /etc/rc.local 中,问题得到解决:

ebtables -A INPUT --in-interface tap0 --protocol ipv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
ebtables -A INPUT --in-interface tap0 --protocol ipv4 --ip-protocol udp --ip-source-port 67:68 -j DROP
ebtables -A FORWARD --out-interface tap0 --protocol ipv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
ebtables -A FORWARD --out-interface tap0 --protocol ipv4 --ip-protocol udp --ip-source-port 67:68 -j DROP

这种配置持续了三年。

第 2 部分:WireGuard 简介

最近,互联网上的人们越来越多地开始谈论WireGuard,称赞其配置简单、传输速度快、ping值低且安全性相当。 搜索更多相关信息后发现,它既不支持桥接成员工作,也不支持通过 TCP 协议工作,这让我觉得对我来说,除了 OpenVPN 之外还没有其他选择。 所以我推迟了了解 WireGuard。

几天前,消息以各种方式在 IT 相关资源中传播开来,称 WireGuard 最终将被纳入 Linux 内核,从 5.6 版本开始。 新闻文章一如既往地赞扬了 WireGuard。 我再次投入到寻找替代旧式 OpenVPN 的方法中。 这次我遇到了 本文。 它讨论了使用 GRE 在 L3 上创建以太网隧道。 这篇文章给了我希望。 目前还不清楚如何处理 UDP 协议。 通过搜索,我找到了有关使用 socat 与 SSH 隧道结合转发 UDP 端口的文章,但是,他们指出这种方法仅适用于单连接模式,也就是说,多个 VPN 客户端的工作是不可能的。 我想到了在VPS上安装VPN服务器并为客户端设置GRE的想法,但事实证明,GRE不支持加密,这将导致如果第三方获得对服务器的访问权限,我的网络之间的所有流量都将掌握在他们手中,这根本不适合我。

我们再次决定采用冗余加密,使用 VPN over VPN,使用以下方案:

XNUMX 级 VPN:
VPS 这是 服务器 内部地址 192.168.30.1
MS 这是 客户 内部地址为 192.168.30.2 的 VPS
MK2 这是 客户 内部地址为 192.168.30.3 的 VPS
MK3 这是 客户 内部地址为 192.168.30.4 的 VPS

二级VPN:
MS 这是 服务器 外部地址 192.168.30.2 和内部地址 192.168.31.1
MK2 这是 客户 MS 地址为 192.168.30.2,内部 IP 为 192.168.31.2
MK3 这是 客户 MS 地址为 192.168.30.2,内部 IP 为 192.168.31.3

* MS — 1 号公寓的路由器服务器, MK2 - 2号公寓的路由器, MK3 - 3号公寓的路由器
* 设备配置已在文末剧透中公布。

因此,网络节点 192.168.31.0/24 之间正在运行 ping,是时候继续设置 GRE 隧道了。 在此之前,为了不丢失对路由器的访问,值得设置 SSH 隧道以将端口 22 转发到 VPS,这样,例如,可以通过 VPS 的端口 10022 访问公寓 2 的路由器,并且公寓 11122 的路由器可通过公寓 3 的路由器的端口 XNUMX 进行访问。最好使用相同的 sshtunnel 配置转发,因为如果隧道失败,它将恢复隧道。

隧道已配置,您可以通过转发端口连接到 SSH:

ssh root@МОЙ_VPS -p 10022

接下来您应该禁用 OpenVPN:

/etc/init.d/openvpn stop

现在让我们在公寓 2 的路由器上设置 GRE 隧道:

ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.2
ip link set grelan0 up

并将创建的接口添加到桥中:

brctl addif br-lan grelan0

让我们在服务器路由器上执行类似的过程:

ip link add grelan0 type gretap remote 192.168.31.2 local 192.168.31.1
ip link set grelan0 up

并将创建的接口添加到桥中:

brctl addif br-lan grelan0

从这一刻起,ping开始成功连接到新网络,我心满意足地去喝咖啡了。 然后,为了评估网络在线路另一端的工作情况,我尝试通过 SSH 连接到公寓 2 中的一台计算机,但 ssh 客户端冻结且不提示输入密码。 我正在尝试通过端口 22 上的 telnet 连接到这台计算机,我看到一行,从中我可以了解到连接正在建立,SSH 服务器正在响应,但由于某种原因它只是不提示我登录在。

$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1

我尝试通过 VNC 连接到它,但看到黑屏。 我说服自己问题出在远程计算机上,因为我可以使用内部地址轻松地从这间公寓连接到路由器。 然而,我决定通过路由器连接到这台计算机的SSH,并惊讶地发现连接成功,并且远程计算机工作正常,但它也无法连接到我的计算机。

我从网桥上移除了 grelan0 设备,并在公寓 2 的路由器上运行 OpenVPN,并确保网络再次按预期工作并且连接不会丢失。 通过搜索,我发现一些论坛,人们抱怨同样的问题,建议他们提高 MTU。 说到做到。 然而,直到 MTU 设置得足够高(对于 gretap 设备为 7000),才会观察到 TCP 连接丢失或传输速率较低。 由于 gretap 的 MTU 较高,因此第 8000 层和第 7500 层 WireGuard 连接的 MTU 分别设置为 XNUMX 和 XNUMX。

我在 3 号公寓的路由器上进行了类似的设置,唯一的区别是第二个名为 grelan1 的 gretap 接口被添加到服务器路由器中,该接口也被添加到 br-lan 网桥中。

一切正常。 现在您可以将 gretap 程序集置于启动状态。 为了这:

我将这些行放在公寓 2 的路由器上的 /etc/rc.local 中:

ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.2
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0

将其添加到公寓 3 中路由器上的 /etc/rc.local 中:

ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.3
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0

在服务器路由器上:

ip link add grelan0 type gretap remote 192.168.31.2 local 192.168.31.1
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0

ip link add grelan1 type gretap remote 192.168.31.3 local 192.168.31.1
ip link set dev grelan1 mtu 7000
ip link set grelan1 up
brctl addif br-lan grelan1

重新启动客户端路由器后,我发现由于某种原因它们无法连接到服务器。 连接到他们的 SSH(幸运的是,我之前为此配置了 sshtunnel)后,发现 WireGuard 由于某种原因正在为端点创建路由,但它是不正确的。 因此,对于 192.168.30.2,路由表指示通过 pppoe-wan 接口的路由,即通过 Internet,尽管到它的路由应该通过 wg0 接口路由。 删除该路由后,连接恢复。 我无法在任何地方找到有关如何强制 WireGuard 不创建这些路由的说明。 而且,我什至不明白这是OpenWRT的功能还是WireGuard本身的功能。 无需长时间处理此问题,我只需在删除此路由的定时脚本中向两个路由器添加一行:

route del 192.168.30.2

总结

我还没有完全放弃OpenVPN,因为我有时需要从笔记本电脑或手机连接到新网络,并且在它们上设置gretap设备通常是不可能的,但尽管如此,我在速度上还是有优势的公寓之间的数据传输,例如使用 VNC 不再不方便。 Ping 略有下降,但变得更加稳定:

使用 OpenVPN 时:

[r0ck3r@desktop ~]$ ping -c 20 192.168.10.110
PING 192.168.10.110 (192.168.10.110) 56(84) bytes of data.
64 bytes from 192.168.10.110: icmp_seq=1 ttl=64 time=133 ms
...
64 bytes from 192.168.10.110: icmp_seq=20 ttl=64 time=125 ms

--- 192.168.10.110 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19006ms
rtt min/avg/max/mdev = 124.722/126.152/136.907/3.065 ms

使用 WireGuard 时:

[r0ck3r@desktop ~]$ ping -c 20 192.168.10.110
PING 192.168.10.110 (192.168.10.110) 56(84) bytes of data.
64 bytes from 192.168.10.110: icmp_seq=1 ttl=64 time=124 ms
...
64 bytes from 192.168.10.110: icmp_seq=20 ttl=64 time=124 ms
--- 192.168.10.110 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19003ms
rtt min/avg/max/mdev = 123.954/124.423/126.708/0.675 ms

受 VPS 高 ping 影响较大,约为 61.5 毫秒

不过,速度却有了显着的提升。 因此,在配有服务器路由器的公寓中,我的互联网连接速度为 30 Mbit/秒,而在其他公寓中为 5 Mbit/秒。 与此同时,在使用 OpenVPN 时,根据 iperf 读数,我无法在网络之间实现超过 3,8 Mbit/秒的数据传输速度,而 WireGuard 将其“提升”到同样的 5 Mbit/秒。

VPS 上的 WireGuard 配置[Interface] Address = 192.168.30.1/24
ListenPort = 51820
PrivateKey = <ЗАКРЫТЫЙ_КЛЮЧ_ДЛЯ_VPS>

[Peer] PublicKey = <ОТКРЫТЫЙ_КЛЮЧ_VPN_1_МС>
AllowedIPs = 192.168.30.2/32

[Peer] PublicKey = <ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК2>
AllowedIPs = 192.168.30.3/32

[Peer] PublicKey = <ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК3>
AllowedIPs = 192.168.30.4/32

MS 上的 WireGuard 配置(添加到 /etc/config/network)

#VPN первого уровня - клиент
config interface 'wg0'
        option proto 'wireguard'
        list addresses '192.168.30.2/24'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МС'
        option auto '1'
        option mtu '8000'

config wireguard_wg0
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
        option endpoint_port '51820'
        option route_allowed_ips '1'
        option persistent_keepalive '25'
        list allowed_ips '192.168.30.0/24'
        option endpoint_host 'IP_АДРЕС_VPS'

#VPN второго уровня - сервер
config interface 'wg1'
        option proto 'wireguard'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
        option listen_port '51821'
        list addresses '192.168.31.1/24'
        option auto '1'
        option mtu '7500'

config wireguard_wg1
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК2'
        list allowed_ips '192.168.31.2'

config wireguard_wg1ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.3

        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК3'
        list allowed_ips '192.168.31.3'

MK2 上的 WireGuard 配置(添加到 /etc/config/network)

#VPN первого уровня - клиент
config interface 'wg0'
        option proto 'wireguard'
        list addresses '192.168.30.3/24'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МК2'
        option auto '1'
        option mtu '8000'

config wireguard_wg0
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
        option endpoint_port '51820'
        option persistent_keepalive '25'
        list allowed_ips '192.168.30.0/24'
        option endpoint_host 'IP_АДРЕС_VPS'

#VPN второго уровня - клиент
config interface 'wg1'
        option proto 'wireguard'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МК2'
        list addresses '192.168.31.2/24'
        option auto '1'
        option listen_port '51821'
        option mtu '7500'

config wireguard_wg1
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
        option endpoint_host '192.168.30.2'
        option endpoint_port '51821'
        option persistent_keepalive '25'
        list allowed_ips '192.168.31.0/24'

MK3 上的 WireGuard 配置(添加到 /etc/config/network)

#VPN первого уровня - клиент
config interface 'wg0'
        option proto 'wireguard'
        list addresses '192.168.30.4/24'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МК3'
        option auto '1'
        option mtu '8000'

config wireguard_wg0
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
        option endpoint_port '51820'
        option persistent_keepalive '25'
        list allowed_ips '192.168.30.0/24'
        option endpoint_host 'IP_АДРЕС_VPS'

#VPN второго уровня - клиент
config interface 'wg1'
        option proto 'wireguard'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МК3'
        list addresses '192.168.31.3/24'
        option auto '1'
        option listen_port '51821'
        option mtu '7500'

config wireguard_wg1
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
        option endpoint_host '192.168.30.2'
        option endpoint_port '51821'
        option persistent_keepalive '25'
        list allowed_ips '192.168.31.0/24'

在所描述的二级 VPN 配置中,我将 WireGuard 客户端指向端口 51821。理论上,这不是必需的,因为客户端将从任何空闲的非特权端口建立连接,但我这样做是为了可以禁止所有路由器 wg0 接口上的所有传入连接(端口 51821 的传入 UDP 连接除外)。

我希望这篇文章对某人有用。

PS 另外,我想分享我的脚本,当我的网络上出现新设备时,该脚本会在 WirePusher 应用程序中向我的手机发送推送通知。 这是脚本的链接: github.com/r0ck3r/device_discover.

更新: OpenVPN 服务器和客户端的配置

OpenVPN服务器

client-to-client

ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/vpn-server.crt
dh /etc/openvpn/server/dh.pem
key /etc/openvpn/server/vpn-server.key

dev tap
ifconfig-pool-persist /etc/openvpn/ipp.txt 0
keepalive 10 60
proto tcp4
server-bridge 192.168.10.1 255.255.255.0 192.168.10.80 192.168.10.254
status /var/log/openvpn-status.log
verb 3
comp-lzo

OpenVPN 客户端

client
tls-client
dev tap
proto tcp
remote VPS_IP 1194 # Change to your router's External IP
resolv-retry infinite
nobind

ca client/ca.crt
cert client/client.crt
key client/client.key
dh client/dh.pem

comp-lzo
persist-tun
persist-key
verb 3

我使用easy-rsa生成证书

来源: habr.com

添加评论