我将 10.1.1.1 和 10.2.2.2 绑定到 eth0。
# ip address show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 04:01:05:ff:42:01 brd ff:ff:ff:ff:ff:ff
inet 10.2.2.2/24 brd 10.2.2.255 scope global eth0
inet 10.1.1.1/32 scope global eth0
inet6 fe80::601:5ff:feff:4201/64 scope link
valid_lft forever preferred_lft forever
# ip route get 10.1.1.1
local 10.1.1.1 dev lo src 10.1.1.1
问题A:为什么IP绑定到eth0时会使用“dev lo”?
我想强制本地连接到 10.1.1.1 的源地址为 10.2.2.2。因此我尝试:
# ip route add 10.1.1.1/32 dev eth0 src 10.2.2.2
# ip route show
default via 10.2.2.1 dev eth0
10.1.1.1 dev eth0 scope link src 10.2.2.2
10.2.2.0/24 dev eth0 proto kernel scope link src 10.2.2.2
# ip route get 10.1.1.1
local 10.1.1.1 dev lo src 10.1.1.1
问题 B:我如何覆盖这个奇怪的“本地”路线?
背景:数据包被 IPVS 内核子系统拦截。在到达那里之前,我需要正确的源地址,否则 IPVS 不知道如何处理它。使用 iptables 进行 SNAT 不起作用,因为这发生在 POSTROUTING 阶段,而 IPVS 会跳过该阶段。另请参阅我的相关问题DR 模式下的 Linux IPVS:Director 无法访问 VIP
谢谢!
答案1
本地表(表 255)在主程序之前被查询,包含所有本地路由(因此得名)。它由内核维护(因此得名proto kernel
)。在您的机器上,它可能看起来像这样。
local 10.1.1.1 dev eth0 proto kernel scope host src 10.1.1.1
broadcast 10.2.2.0 dev eth0 proto kernel scope link src 10.2.2.2
local 10.2.2.2 dev eth0 proto kernel scope host src 10.2.2.2
broadcast 10.2.2.255 dev eth0 proto kernel scope link src 10.2.2.2
broadcast 127.0.0.0 dev lo proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope host src 127.0.0.1
源地址在其中指定。
Linux 支持多个路由表,路由涉及查询路由策略数据库 (RPDB) 的使用情况,以决定何时查询哪个表。如果某个表不包含答案,或者路由类型为throw
,则查询下一个 RPDB 规则。
$ ip ru
0: from all lookup local
32766: from all lookup main
32767: from all lookup default
您可以尝试删除表查找规则local
,并将其放在后面(ip rule del pref 0; ip rule add from all lookup local pref 1
),但不建议这样做。然后,您可以添加一条规则来查询自定义路由表(选择 255 以上的任意数字),其中将有一条唯一的路由到 10.1.1.1,源地址设置为 10.2.2.2。bind()
如果您是与 10.1.1.1 通信的相关程序的作者,更好的方法是直接致电。