[编辑] 这似乎是一个 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 端点上,无论距离多远,他们都可以看到彼此。但是连接到连接到 SERVER 端 openvpn Tap 接口的 Wi-Fi 的玩家遇到了问题 - 他们无法看到隧道客户端的玩家,而远程玩家也看不到他们。
为了看到对方,游戏每 1-2 秒向端口 19132 (ipv4) 发送一个 UDP 广播数据包。网络上的所有玩家都会收到这些广播,如果他们的游戏是服务器,那么他们的游戏会向请求者发送一个单播数据包。此单播响应数据包包含游戏信息,因此正在网络上搜索活动游戏的玩家将看到它们出现在他们的朋友列表中,因此他们可以加入游戏。
附件是对丢失数据包的一小段时间的分析。数据包从分路隧道的一侧进入,而不是从另一侧出来。我已经通过对隧道的每一侧运行 tcpdump 来捕获数据包,在 openvpn tap 接口本身上,因此路径中没有网桥,尽管接口都是网桥的成员。
我看到的是 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