我正在对 OS X Mavericks 上的 OpenVPN 服务器设置进行故障排除。在升级到 10.9 之前,这一切都正常,我正在尝试将问题隔离到某些基本问题或我的服务器/客户端设置上。
VPN 客户端能够与整个互联网和 LAN 上除 VPN 服务器本身之外的所有设备建立 TCP 连接。此外,VPN 客户端能够成功 ping 和跟踪距离一跳的服务器。
我很茫然,希望得到任何指点。
我的服务器是 10.0.1.3,位于 10.0.1/24 接口 en0 上。我的 VPN 位于 tun0 上的 10.8.0/24 上。防火墙已禁用,但需要在基于 pf 的防火墙上启用 NAT,以便客户端访问互联网,这可以使用 pfctl pf.conf 行完成,
nat on en0 from { 10.8.0.0/24 10.0.1.0/24 } to any -> (en0)
pass all
无论是否启用防火墙,服务器和客户端之间都会出现断开的 TCP 返回链接,因此我排除了防火墙是导致问题的原因。数据包转发通过 BSD 命令启用:
/usr/sbin/sysctl -w net.inet.ip.fw.enable=1
/usr/sbin/sysctl -w net.inet.ip.forwarding=1
看来 VPN 无法通过 tun0 从服务器向 VPN 客户端正确返回 [SYN,ACK] 数据包。什么会阻止来自 VPN 客户端的数据包通过 tun0 接口到达 LAN?VPN 客户端的数据包在 en0 而不是 tun0 上返回,这导致连接中断。以下示例使用 wireshark 捕获 tun0 和 en0 上的端口 22 数据包,说明了这一点。以下是我在 wireshark 上看到的内容:
server [10.0.1.3]$ ssh [email protected] # Successful
tun0:
10.8.0.1 -> 10.8.0.10 ssh [SYN]
10.8.0.10 ssh -> 10.8.0.1 [SYN,ACK]
10.8.0.1 -> 10.8.0.10 ssh [ACK]
...
en0:
<No packets>
iPhone [10.8.0.10]$ ssh [email protected] # Unsuccessful
tun0:
10.8.0.10 -> 10.0.1.3 ssh [SYN]
10.8.0.10 [TCP Retransmission] -> 10.0.1.3 ssh [SYN]
10.8.0.10 [TCP Retransmission] -> 10.0.1.3 ssh [SYN]
10.8.0.10 [TCP Retransmission] -> 10.0.1.3 ssh [SYN]
10.8.0.10 [TCP Retransmission] -> 10.0.1.3 ssh [SYN]
...
en0:
10.0.1.3 ssh -> 10.8.0.10 [SYN,ACK]
10.0.1.3 [TCP Retransmission] ssh -> 10.8.0.10 [SYN,ACK]
10.0.1.3 [TCP Retransmission] ssh -> 10.8.0.10 [SYN,ACK]
10.0.1.3 [TCP Retransmission] ssh -> 10.8.0.10 [SYN,ACK]
10.0.1.3 [TCP Retransmission] ssh -> 10.8.0.10 [SYN,ACK]
10.0.1.3 [TCP Retransmission] ssh -> 10.8.0.10 [SYN,ACK]
...
我正在读这本书网络故障排除工具尝试追踪此问题。其使用 netstat 的第一个示例显示了如下所示的路由表,其中明确解析了 172.16.2.1 和 172.16.2.255 地址。
bsd1# netstat -rn
Routing tables
Internet:
Destination
…
172.16.1/24 172.16.2.1 xl1
172.16.2/24 link#2 xl1
172.16.2.1 0:10:7b:66:f7:62 xl1
172.16.2.255 ff:ff:ff:ff:ff:ff xl1
但我的 tun0 实际路由表如下所示:
server$ netstat -rn
default 10.0.1.1 UGSc 157 21721 en0
…
10.8/24 10.8.0.2 UGSc 1 6 tun0
10.8.0.2 10.8.0.1 UH 2 0 tun0
tun0 接口上没有明确指定 10.8.0.1 或 10.8.0.255 — 应该有吗?如果是,我该如何添加此路由?这可能是服务器返回数据包在默认 en0 接口上发送的原因吗?
任何指点都将不胜感激。
答案1
正如您在上一条评论中正确指出的那样,这是一个路由问题。我遇到过类似的情况,当访问本地网络 172.16.172.0/24 时,我希望所有 OpenVPN 客户端(在我的情况下是 tun0 上的网络 10.8.0.0/24)都使用 OpenVPN 服务器的 en0 接口地址(在我的情况下是 172.16.172.2/24)进行 NAT(或伪装)
症状是我可以访问 172.16.172.0/24 网络上的所有主机,但不能访问 172.16.172.2 本身,我不得不恢复通过其 tun0 接口地址访问 OpenVPN 服务器,但这个问题困扰着我。
经过多次尝试和错误,我找到了解决方案。pf.conf 中的 pass 行将确保从 VPN 网络到达 VPN 接口的数据包(该数据包发往 OpenVPN 服务器的内部接口)在 VPN 接口上路由回。还请注意我的 nat 行 - 如果流量发往内部接口,我实际上是在阻止 NAT。
int_if="en0"
vpn_if="tun0"
vpnnet="10.8.0.0/24"
no nat on ! $vpn_if from $vpnnet to ($int_if)
nat on ! $vpn_if from $vpnnet to any -> ($int_if)
pass in log quick on $vpn_if reply-to $vpn_if from $vpnnet to $int_if