我们正在为一些在云中运行的服务器设置 OpenVPN 服务器。我们被一个连接问题困扰着,VPN 服务器 LAN 上的主机可以 ping 通 VPN 客户端,但反之则不行。
VPN 客户端可以在其 VPN 地址上 ping 通 VPN 服务器,但不能在其 LAN 地址上 ping 通 VPN 服务器。
tcpdump 显示有证据表明来自客户端的 ping 数据包已到达主机并发出了回复,但由于某种原因,回复从未到达 VPN 服务器或客户端上的 tun0 接口。相反,根据 tcpdump,从 VPN 服务器的 LAN 到 VPN 客户端的 ping 请求流量在所有预期接口上均可见。
下面给出了我们迄今为止的配置和故障排除的详细描述。
问题似乎与从服务器网络上的地址转发回客户端网络有关。对我来说,真正奇怪的是 LAN 发起的 ping 可以完成完整的往返,但客户端发起的 ping 似乎在 VPN 服务器的 tun0 和 eth1 接口之间的某个地方被丢弃。
我们遗漏了什么?
情况:
3 个主机:
- VPN 客户端(tun0:10.8.0.22)
- VPN 服务器(tun0:10.8.0.1,eth1:10.11.11.2,eth0:xxxx)
- LAN 服务器(eth0:10.11.11.7)
两台服务器都是虚拟机,运行 RHEL 5.7。我认为(但不完全确定)虚拟托管环境是 VMWare。
测试
- VPN 客户端已通过 VPN 服务器的 eth0 接口与 VPN 服务器建立隧道
- VPN 客户端可以在其 tun0 接口 10.8.0.1 上 ping VPN 服务器
- VPN 服务器可以 ping 10.8.0.22
- LAN 服务器可以 ping 10.8.0.22
但:
- VPN 客户端无法在其 eth1 接口 10.11.11.2 上 ping VPN 服务器
- VPN 客户端无法在其 eth0 接口 10.11.11.7 上 ping LAN 服务器
对于 10.11.11.7 和 10.8.0.22 之间的 ping 测试:
- tcpdump 显示 ping 请求和答复穿越 VPN 服务器上的 tun0
- tcpdump 显示 ping 请求和答复穿越 VPN 服务器上的 eth1
- tcpdump 显示 ping 请求和答复穿越 LAN 服务器上的 eth0
对于 10.11.11.2 和 10.8.0.22 之间的 ping 测试:
- tcpdump 显示 ping 请求和答复穿越 VPN 服务器上的 tun0
对于 10.8.0.22 和 10.11.11.2 之间的 ping 测试:
- tcpdump 显示 ping 请求穿越 VPN 服务器上的 tun0
- tcpdump 显示 ping 回复遍历 VPN 服务器上的 eth1
- tun0 接口上没有回复的痕迹
对于 10.8.0.22 和 10.11.11.7 之间的 ping 测试:
- tcpdump 显示 ping 请求穿越 VPN 服务器上的 tun0
- tcpdump 显示 ping 请求遍历 VPN 服务器上的 eth1
- tcpdump 显示 ping 请求遍历 LAN 服务器上的 eth0
- tcpdump 显示 ping 回复遍历 LAN 服务器上的 eth0
- VPN 服务器的 tun0 或 eth1 接口上均没有回复的痕迹
VPN 服务器上已启用 ip_fowarding,VPN 服务器上除面向 Internet 的接口 eth0 之外的所有接口的 rp_filter 均已被禁用。
为了调试底层问题,客户端上的 iptables 规则已被禁用(默认为 ACCEPT)。
我已经包含了每个主机上相关接口的路由 -n 和 ifconfig 的转储。
在 OpenVPN 服务器上
$ /sbin/route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.8.0.2 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
10.11.11.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
10.8.0.0 10.8.0.2 255.255.255.0 UG 0 0 0 tun0
x.x.x.x 0.0.0.0 255.255.248.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1
0.0.0.0 x.x.x.x 0.0.0.0 UG 0 0 0 eth0
$ find /proc/sys/net -name 'rp_filter' | while read f
> do echo $f $(cat $f)
> done
/proc/sys/net/ipv4/conf/tun0/rp_filter 0
/proc/sys/net/ipv4/conf/eth1/rp_filter 0
/proc/sys/net/ipv4/conf/eth0/rp_filter 1
/proc/sys/net/ipv4/conf/lo/rp_filter 0
/proc/sys/net/ipv4/conf/default/rp_filter 0
/proc/sys/net/ipv4/conf/all/rp_filter 0
$ cat /proc/sys/net/ipv4/ip_forward
1
$ sudo /sbin/iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
$ /sbin/ifconfig -a
eth0 Link encap:Ethernet HWaddr DE:AD:BE:A6:28:21
inet addr:x.x.x.x Bcast:x.x.x.x Mask:255.255.248.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:233929 errors:0 dropped:0 overruns:0 frame:0
TX packets:24776 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:27881415 (26.5 MiB) TX bytes:30534780 (29.1 MiB)
eth1 Link encap:Ethernet HWaddr DE:AD:BE:3B:24:48
inet addr:10.11.11.2 Bcast:10.11.11.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:4929 errors:0 dropped:0 overruns:0 frame:0
TX packets:10209 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:423658 (413.7 KiB) TX bytes:863546 (843.3 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:11992 errors:0 dropped:0 overruns:0 frame:0
TX packets:11992 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:34820967 (33.2 MiB) TX bytes:34820967 (33.2 MiB)
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.8.0.1 P-t-P:10.8.0.2 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:69 errors:0 dropped:0 overruns:0 frame:0
TX packets:57 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:5796 (5.6 KiB) TX bytes:4788 (4.6 KiB)
$ uname -a
Linux vhost0273 2.6.18-274.el5 #1 SMP Fri Jul 8 17:36:59 EDT 2011 x86_64 x86_64 x86_64 GNU/Linux
$ ping -c1 10.8.0.22 -w 1
PING 10.8.0.22 (10.8.0.22) 56(84) bytes of data.
64 bytes from 10.8.0.22: icmp_seq=1 ttl=64 time=145 ms
--- 10.8.0.22 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 145.676/145.676/145.676/0.000 ms
$ ping -c1 10.11.11.7 -w 1
PING 10.11.11.7 (10.11.11.7) 56(84) bytes of data.
64 bytes from 10.11.11.7: icmp_seq=1 ttl=64 time=0.794 ms
--- 10.11.11.7 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.794/0.794/0.794/0.000 ms
在服务器局域网上的主机上:
$ /sbin/ifconfig -a
eth0 Link encap:Ethernet HWaddr DE:AD:BE:7F:45:72
inet addr:10.11.11.7 Bcast:10.11.11.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:33897 errors:0 dropped:0 overruns:0 frame:0
TX packets:38294 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2536157 (2.4 MiB) TX bytes:8910725 (8.4 MiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:77779 errors:0 dropped:0 overruns:0 frame:0
TX packets:77779 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
$ /sbin/route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.11.11.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
10.8.0.0 10.11.11.2 255.255.255.0 UG 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
0.0.0.0 10.11.11.2 0.0.0.0 UG 0 0 0 eth0
$ ping -c1 10.8.0.1 -w 1
PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data.
64 bytes from 10.8.0.1: icmp_seq=1 ttl=64 time=0.516 ms
--- 10.8.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.516/0.516/0.516/0.000 ms
$ ping -c1 10.8.0.22 -w 1
PING 10.8.0.22 (10.8.0.22) 56(84) bytes of data.
64 bytes from 10.8.0.22: icmp_seq=1 ttl=63 time=146 ms
--- 10.8.0.22 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 146.913/146.913/146.913/0.000 ms
$ ping -c1 10.11.11.2 -w 1
PING 10.11.11.2 (10.11.11.2) 56(84) bytes of data.
64 bytes from 10.11.11.2: icmp_seq=1 ttl=64 time=0.775 ms
--- 10.11.11.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.775/0.775/0.775/0.000 ms
在 VPN 客户端上
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.8.0.22 P-t-P:10.8.0.21 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
$ /sbin/route -n | grep ^10
10.8.0.21 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
10.8.0.1 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
10.0.1.0 0.0.0.0 255.255.255.0 U 2 0 0 wlan0
10.1.1.0 0.0.0.0 255.255.255.0 U 1 0 0 eth0
10.11.11.0 10.8.0.1 255.255.255.0 UG 0 0 0 tun0
$ ping 10.8.0.1
PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data.
64 bytes from 10.8.0.1: icmp_seq=1 ttl=64 time=145 ms
$ ping 10.8.0.2 -w 1
PING 10.8.0.2 (10.8.0.2) 56(84) bytes of data.
--- 10.8.0.2 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
$ ping 10.11.11.2 -w 1
PING 10.11.11.2 (10.11.11.2) 56(84) bytes of data.
--- 10.11.11.2 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms
$ ping 10.11.11.7 -w 1
PING 10.11.11.7 (10.11.11.7) 56(84) bytes of data.
--- 10.11.11.7 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 999ms
答案1
该问题的根本原因是一些隐式默认路由在 /sbin/route 显示的表中不可见,但在 /sbin/ip route 和 /sbin/ip rule 显示的表中可见。
然后显示这些表格,显然有这样的规则:
default table route_eth0 via 10.11.11.1 dev eth0
覆盖了此规则:
10.8.0.0 10.11.11.2 255.255.255.0 UG 0 0 0 eth0
通过编辑 /etc/sysconfig/network-scripts/route-eth0(大概使用 /sbin/ip route,但在这种情况下是手动完成的),我能够解决这个问题。
因此,我从中了解到,不能依赖 /sbin/route 为您提供 Linux 有效路由规则的准确图像,最好使用 /sbin/ip 来实现此目的。
感谢 ptman 对此的回答问题帮助我看到了光明。谢谢 ptman!
答案2
你的 iptables 规则怎么样?它们看起来相当空。
我使用以下规则,但我不确定它是否能解决您的确切问题:
# 允许 TUN 接口连接到 OpenVPN 服务器 iptables -A 输入 -i tun+ -j 接受 # 允许TUN接口连接通过其他接口转发 iptables -A 转发 -i tun+ -j 接受 iptables -A 转发 -o tun+ -j 接受 # 允许 TUN 接口连接出去 iptables -A 输出 -o tun+ -j 接受 # 我们希望允许从 OpenVPN 隧道进行路由 $IPTABLES -t nat -A POSTROUTING -o eth1 -s 10.8.1.0/255.255.255.0 -j MASQUERADE $IPTABLES -A FORWARD -i tun+ -o eth1 -s 10.8.1.0/255.255.255.0 -j 接受
在网关上,您需要一个路由条目来将 10.8.1.0/24 的流量引导至 openvpn 服务器。
在 openvpn 服务器上,10.8.1.0/24 子网的流量使用 openvpn 服务器的 tun 接口的 IP 地址,例如 10.8.1.2。但这应该已由 openvpn 本身配置。
更新:我不得不修改一些内容,我在这里使用了一个设置,其中有 2 个 openvpn 服务器,它们也可以相互通信。所以我混淆了一些与您的情况无关的内容。