正确的方法是将bind()绑定到要用于传出数据包的接口。由于您随后可以使用ip route
和ip rule
命令设置路由,以根据数据包的传出接口控制数据包的路由方式。对于我的示例,我将假定以下网络:
- eth0:
- 地址:192.168.0.2/24
- 默认网关:192.168.0.1
- eth1:
- 地址:192.168.1.2/24
- 默认网关:192.168.1.1
我将创建两个路由表,一个用于eth0的出站流量,称为alternate,另一个用于eth1的表,称为main。路由表main始终存在,并且是route
and ip route
命令使用的普通表。大多数人从不处理任何其他表。要创建名为alternate的表,我们将以下行添加到/etc/iproute2/rt_tables
:
10 alternate
主表的默认优先级为254。生效该路由表的规则由ip rule
命令控制。默认情况下,该命令将打印出现有规则的列表,看起来应该像这样:
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
这基本上表示它将在表中查找路由,该表local
是内核为本地路由(例如我自己的IP地址)维护的特殊表。然后它将尝试表主表和表默认表。表的默认值通常为空白,因此如果main中没有匹配项,则没有主机路由。首先,让填充表与eth0的规则交替出现。
sudo ip route add table alternate 192.168.0.0/24 dev eth0
sudo ip route add table alternate 192.168.1.0/24 dev eth1
sudo ip route add table alternate default via 192.168.0.1
通常,您希望alternate
表格看起来与main
表格相似。唯一的区别是路由应该不同。如果您确实希望所有NFS,HTTP等流量都通过eth0上的默认网关通过,即使您的流量是发往eth1上的网络的,则您可能不想在上面添加第二行。下一步是添加何时使用此备用路由表的规则:
sudo ip rule add from 192.168.0.0/24 pref 10 table alternate
该规则表示,来自192.168.0网络上某个地址的所有流量都将使用alternate
路由表而不是普通main
表。最后一步是确保所有必须使用的客户端都eth0
绑定到该客户端。使用wget
,例如set --bind-address=192.168.0.2
,对于NFS设置clientaddr=192.168.0.2
挂载选项。如果将LibWWW与Perl一起使用,则可以在LWP :: UserAgent中设置localaddr选项以控制其绑定到的本地接口。如果碰巧有一个客户端,您将无法控制绑定,并且编译源也不是一种选择,那么您也许可以使用iptables规则来修改其地址,但这更像是一种技巧,可能无法正常工作。您将需要在nat表或mangle表的PREROUTING链中设置SNAT规则。您仍将需要上面给出的修改后的路由表才能起作用。
iftop
,它们都显示正确的通信量。非常感谢。