我有一个 OpenVPN 服务器和一个客户端,我想使用此隧道访问10.0.8.0/24
整个互联网。到目前为止,通过接口从客户端 ping 服务器tun0
是可行的,反之亦然。
但是,www.google.com
从客户端ping 通tun0
却不起作用(所有数据包都丢失了)。
我认为我应该配置服务器,以便tun0
转发来自互联网目的地的任何数据包,所以我想出了这个 iptables 配置行:
interface_connecting_to_the_internet='eth0'
interface_openvpn='tun0'
internet_ip_address=`ifconfig "$interface_connecting_to_the_internet" | sed -n s'/.*inet \([0-9.]*\).*/\1/p'`
iptables -t nat -A POSTROUTING -o "${interface_connecting_to_the_internet}" -j SNAT --to-source "${internet_ip_address}"
echo '1' > /proc/sys/net/ipv4/ip_forward
然而,这不起作用,数据包仍然丢失,我想知道我的设置可能出了什么问题。
一些细节:
服务器上的 ip route 给出:
default via 176.31.127.254 dev eth0 metric 3
10.8.0.0/24 via 10.8.0.2 dev tun0
10.8.0.2 dev tun0 proto kernel scope link src 10.8.0.1
127.0.0.0/8 via 127.0.0.1 dev lo
176.31.127.0/24 dev eth0 proto kernel scope link src 176.31.127.109
ip route 在客户端给出:
default via 192.168.1.1 dev wlan0 proto static
10.8.0.1 via 10.8.0.5 dev tun0
10.8.0.5 dev tun0 proto kernel scope link src 10.8.0.6
127.0.0.0/8 via 127.0.0.1 dev lo scope link
192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.109
- 客户端使用 wifi 适配器
wlan0
和 TUN 适配器tun0
。 - 服务器使用以太网适配器
eth0
和TUN适配器tun0
。 VPN 跨越
10.0.8.0/24
客户端和Linux都使用Linux 3.6.1。
答案1
总结一下讨论:
为了通过 VPN 从客户端 C 到达服务器 S 的特定主机 A,必须:
- 在 S 上启用 IP 转发 (
sysctl -w net.ipv4.ip_forward=1
) - 在 S: 上通过 iptables 启用伪装或 snat,
iptables -t nat -A POSTROUTING -o ext_if -j MASQUERADE
或者iptables -t nat -A POSTROUTING -o ext_if-j SNAT --to-source ext_ip
使用明显含义的ext_if
和ext_ip
。 - 在 C 上设置适当的路由,(S 表示 S 的 IP 地址在 VPN 中):
- 通过设置一条经由 S 到 A 的明确路由:
ip route add A via S dev vpn_if
- by setting a default route via S:
ip route add default via S dev vpn_if
, where one also has to set an appropriate route to S:ip route add S via previous_gateway dev prev_if
. - by using the
push "redirect-gateway def1"
on the server, in which case OpenVPN will set up routes to0.0.0.0/1
and128.0.0.0/1
on C via S, which are more specific than the default route and can easily be removed when the tunnel is stopped.
- 通过设置一条经由 S 到 A 的明确路由: