总结
如何在 Linux 中设置两个默认路由(对应两个接口),以便接受来自两个接口的传入流量。
设想
我有一台主机,有两个网卡eth0
和eth1
。它连接到两个网络,例如:
开发:
eth0
、IP:、1.1.1.4
网络掩码:255.255.255.0
、网关:1.1.1.1
开发:
eth1
、IP:、2.2.2.4
网络掩码:255.255.255.0
、网关:2.2.2.1
(两个网络都连接到互联网。)
路线为(ip route show
):
default via 1.1.1.1 dev eth0 metric 1
default via 2.2.2.1 dev eth1 metric 2
1.1.1.0/24 dev eth0 src 1.1.1.4
2.2.2.0/24 dev eth1 src 2.2.2.4
(度量越低,优先级越高。)
现在,当有人2.2.2.4
从某个外部主机(比如说4.4.4.4
) ping 时,不会有回复。
我的主机上的输出tcpdump -i eth1
是:
22:41:27.431539 IP 4.4.4.4 > 2.2.2.4: ICMP echo request, id 8625, seq 4, length 64
22:41:28.439492 IP 4.4.4.4 > 2.2.2.4: ICMP echo request, id 8625, seq 5, length 64
22:41:29.447666 IP 4.4.4.4 > 2.2.2.4: ICMP echo request, id 8625, seq 6, length 64
22:41:30.455528 IP 4.4.4.4 > 2.2.2.4: ICMP echo request, id 8625, seq 7, length 64
经过一番研究,结果发现当 Linux 网络堆栈从 接收到数据包时4.4.4.4
,它会检查其路由表以查看应该使用哪个接口4.4.4.4
(eth0
在路由表中)。现在,由于数据包来自eth1
接口,Linux 会直接丢弃它(此策略可能是为了防止 IP 欺骗)。
我想要的是:
传出流量(本地发起)应
eth0
默认使用接口。应从两个接口接受传入流量。(因此
4.4.4.4
应该能够 ping1.1.1.4
和2.2.2.4
)
答案1
使用 iproute2 你可以做这样的事情:
echo "1 admin" >> /etc/iproute2/rt_tables
echo "2 users" >> /etc/iproute2/rt_tables
ip rule add from 192.168.122.40/32 dev eth0 table admin
ip rule add from 192.168.123.41/32 dev eth1 table users
ip route add default via 192.168.122.1 dev eth0 table admin
ip route add default via 192.168.123.1 dev eth1 table users
现在您将拥有两个带有两个网关的路由表。
答案2
这种现象称为单播 rpf(反向路径转发),是 Linux 中的标准反向路径过滤器。您可以禁用此功能而不会产生任何重大的负面后果(除非您是 ISP 和路由器)。
echo 0 > /proc/sys/net/ipv4/conf/default/rp_filter
那么您的示例应该能够按照您希望的方式工作。
答案3
如果您的应用程序绑定到0.0.0.0
它,还需要添加如下规则:
ip rule add from 0.0.0.0/32 to 192.168.122.0/24 dev eth0 table admin
ip rule add from 0.0.0.0/32 to 192.168.123.0/24 dev eth1 table users