[编辑] 这似乎是 OpenVPN 的一个错误 - 与 openvpn tap 隧道的服务器端桥接会导致 ARP 数据包丢失,但与客户端(连接到 vpn 的任何客户端)桥接则运行良好。我通过与客户端而不是服务器桥接解决了这个错误。错误报告过程相当繁琐,所以我需要一段时间才能将其全部写出来提交给 Openvpn 项目。
我观察到 Openvpn 持续丢弃某些数据包......
设想:
我设置了一个广域二层网络(使用 OpenVPN),以支持 Minecraft 袖珍版 (MCPE) 玩家(仅限家人)在网络好友列表中看到彼此并一起玩。有三个远程端点,均位于不同位置,还有一个中央 openvpn 服务器。每个远程端点广播桥接到 Openvpn tap 接口的 Wi-Fi。这很好用,玩家可以互相看到。
最近我想在服务器位置本地添加一个额外的 Wi-Fi 端点。因此,我在网桥上添加了一个以太网端口,并连接了一个 Wi-Fi 网桥,以便与现有的 openvpn 网桥建立第 2 层连接。乍一看,这似乎运行良好;客户端可以访问互联网,并且 L2 流量看起来很正常。
然而,当远程客户端上的玩家尝试与连接到本地 Wi-Fi 桥的玩家对战时,玩家彼此无法看到对方。
本地 Wi-Fi 桥接至 openvpn 隧道的 SERVER 端,这似乎是一个因素,但这是意料之外的。
经过几个小时的故障排除,我把问题缩小到了一个奇怪的事实 - 桥接到服务器的 openvpn tap 接口(名为 tapmc)的 Wi-Fi 无法与 VPN 另一端的玩家对战。
换句话说,如果任何两个玩家使用同一个 Wi-Fi 或客户端 openvpn Wi-Fi 端点,无论距离多远,他们都可以看到对方。但是,连接到桥接到服务器端 openvpn tap 接口的 Wi-Fi 的玩家会遇到问题 - 他们看不到隧道客户端的玩家,远程玩家也看不到他们。
为了互相看到对方,游戏每 1-2 秒向端口 19132 (ipv4) 发送一个 UDP 广播数据包。网络上的所有玩家都会收到这些广播,如果他们的游戏是服务器,那么他们的游戏会向请求者发送单播数据包。此单播响应数据包包含游戏信息,因此在网络上搜索活跃游戏的玩家将看到它们出现在他们的好友列表中,以便他们可以加入游戏。
附件是对数据包丢失的一小段时间的分析。数据包从 Tap 隧道的一侧进入,而不会从另一侧出来。我通过在 OpenVPN Tap 接口本身上对隧道的每一侧运行 tcpdump 来捕获数据包,因此路径中没有桥接器,尽管每个接口都是桥接器的成员。
我看到的情况是,PLAYER2 在网络上搜索游戏时发送搜索广播,PLAYER1 的游戏会收到该广播,该游戏希望使用单播游戏信息包进行响应,但首先需要解析 PLAYER2 的 MAC 地址,因此它发送 ARP who-has。PLAYER1 接收并响应 who-has 数据包及其所有后续重传,但这些响应不会通过 Openvpn 隧道传输到 PLAYER1。因此,L2 ARP 解析永远不会成功,单播游戏信息包永远不会发送,PLAYER2 永远不会看到 PLAYER1。
隧道中还丢失了游戏搜索广播数据包的第二份副本,但这对整个过程的影响并不大,因为两份副本中的第一份已成功传输。但为什么只有一份呢?
Openvpn 服务器配置
server 192.168.251.0 255.255.255.0
verb 3
key ***
ca ***
cert ***
dh ***
tls-auth ***
key-direction 0
keepalive 10 60
persist-key
persist-tun
client-to-client
proto udp
port ***
dev tapmc
status ***
ifconfig-pool-persist ***
user nobody
group nobody
Openvpn 客户端配置
client
nobind
dev tapmc
remote-cert-tls server
remote ***
<key>
***
</key>
<cert>
***
</cert>
<ca>
***
</ca>
<tls-auth>
***
</tls-auth>
key-direction 1
#redirect-gateway def1
Openvpn 版本:服务器:2.4.8-1,客户端:2.4.7-1
答案1
这原来是 OpenVPN 的一个 bug