我有一台 centos 6 VPS,配置了 1 个网络接口绑定 4 个 IP,例如 172.xx11、172.xx12、172.xx13、172.xx14 与 venet0:0、venet0:1、venet0:2、venet0:3 绑定。
我在服务器上运行 pptpd 服务。客户端可以使用 4 个 IP 中的每一个连接到 PPTP VPN 服务,但是当包转发到目的地时,IP 始终是服务器的主 IP,即 172.xx11。
例如,用户使用 PPTP VPN 客户端连接到 172.xx13 来请求 twitter.com 的页面,但 twitter.com 认为该请求来自 172.xx11。我应该如何设置服务器(可能是 iptables、路由)以使传入和传出的 IP 相同?
这是我为 ip 转发设置的 iptables:
-A POSTROUTING -s 192.168.24.0/255.255.255.0 -o venet0 -j MASQUERADE
这是路由命令结果:
[root@bla1 ~]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
link-local * 255.255.0.0 U 1002 0 0 venet0
default * 0.0.0.0 U 0 0 0 venet0
答案1
使用 iptables CONNMARK 标记每个发出的数据包,并在数据包从连接返回时恢复标记。您还需要设置多个路由表,每个标记一个,以便您可以根据标记路由数据包。
您可以使用“ip route nexthop”来设置路由。您还可以为每条路由指定权重,这样您就可以按照自己的意愿平衡流量。
另外,我认为你的例子不准确。实际情况是数据包从不同的 IP 地址发出,因此当它们返回时,它们将不会被发往用于建立连接的 IP。这就是为什么你需要确保一个连接的所有数据包始终使用相同的路由。
我没有脚本可以执行此操作,但我的脚本基于以下示例http://mailman.ds9a.nl/pipermail/lartc/2006q2/018964.html(复制如下)。
#by-pass rules if it is already MARKed
iptables -t mangle -A POSTROUTING -m mark --mark ! 0 -j ACCEPT
#1st packets(from a connection) will arrive here
iptables -t mangle -A POSTROUTING -o eth1 -j MARK --set-mark 0x1
iptables -t mangle -A POSTROUTING -o eth2 -j MARK --set-mark 0x2
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark
#restore mark before ROUTING decision
iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
#route commands
ip ro add default nexthop via x.x.x.x dev eth1 weight 1 nexthop via
y.y.y.y dev eth2
ip route add default table provider1 via x.x.x.x dev eth1
ip route add default table provider2 via y.y.y.y dev eth2
# and most important
ip rule add fwmark 0x1 table provider1
ip rule add fwmark 0x2 table provider2
还有其他事项需要考虑:
- 某些程序(例如 ssh)在初始设置后会创建新连接。此新连接可以具有与初始连接不同的路由,并且应用程序将看不到来自此连接的数据包。因此,您必须为此类应用程序设置特殊路由。
- 如果有许多链接,就会出现网卡不稳定的问题。最好使用 VLAN 交换机中继到调制解调器的物理连接。
- 如果您想允许来自外部的传入连接,您还需要特殊路由。
答案2
您所看到的是您设置的后路由规则的直接结果。
您要做的事情要么需要桥接(用于同一网络通信),要么需要路由(用于网络内通信)。伪装(NATting)的效果正是您所哀叹的。