我有一台 Linux (Ubuntu 12.04) 机器 (c220-1),它有多个接口。这里感兴趣的两个是:
- eth2:10.10.0.131/24
- eth3:10.20.0.2/24
默认路由设置为 10.20.0.2。但是,我希望能够通过连接到 10.20.0.2 或 10.10.0.131 从单独的网络 (192.168.3.0/24) 来 ssh 进入此机器
为了能够通过 ssh 进入 10.10.0.131 并避免对称路由问题,我使用了源路由策略:
root@c220-1:~# ip route list table eth2
default via 10.10.0.1 dev eth2
我通过在 /etc/iproute2/rt_tables 中添加以下行来添加此规则
12 eth2
然后我就这么做了
root@c220-1:~# ip route add default via 10.10.0.1 table eth2
root@c220-1:~# ip rule add from 10.10.0.131 lookup eth2
这有效,我可以 ssh 到 10.10.0.131 或 10.20.0.2。但我无法再从 10.10.0.0/24 网络上的其他机器连接到 10.10.0.131。我可以双向 arping,并且可以从 c220-1 (10.10.0.131/24) ping 到 c220-2 (10.10.0.132/24)。但我无法从 c220-2 ping 到 c220-1。
如果我执行 tcpdump,我可以确认 c220-1 正在接收 ICMP 请求并发送回复:
root@c220-1:~# tcpdump -i eth2 icmp -vvv -n -e
tcpdump: listening on eth2, link-type EN10MB (Ethernet), capture size 65535 bytes
23:15:11.455818 d4:8c:b5:4d:a5:3a > 60:73:5c:68:b4:b6, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84)
10.10.0.132 > 10.10.0.131: ICMP echo request, id 8805, seq 1, length 64
23:15:11.455877 60:73:5c:68:b4:b6 > 30:f7:0d:bc:bb:52, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 16273, offset 0, flags [none], proto ICMP (1), length 84)
10.10.0.131 > 10.10.0.132: ICMP echo reply, id 8805, seq 1, length 64
23:15:12.463394 d4:8c:b5:4d:a5:3a > 60:73:5c:68:b4:b6, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84)
10.10.0.132 > 10.10.0.131: ICMP echo request, id 8805, seq 2, length 64
23:15:12.463451 60:73:5c:68:b4:b6 > 30:f7:0d:bc:bb:52, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 16274, offset 0, flags [none], proto ICMP (1), length 84)
10.10.0.131 > 10.10.0.132: ICMP echo reply, id 8805, seq 2, length 64
你可以看到请求来自d4:8c:b5:4d:a5:3a
,但答复将发往30:f7:0d:bc:bb:52
。
正如预期的那样,ICMP 回复没有出现在 c220-2 上:
root@c220-2:~# tcpdump -i eth2 icmp -vvv -n -e
tcpdump: listening on eth2, link-type EN10MB (Ethernet), capture size 65535 bytes
23:16:19.944225 d4:8c:b5:4d:a5:3a > 60:73:5c:68:b4:b6, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84)
10.10.0.132 > 10.10.0.131: ICMP echo request, id 9380, seq 1, length 64
23:16:20.952497 d4:8c:b5:4d:a5:3a > 60:73:5c:68:b4:b6, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84)
10.10.0.132 > 10.10.0.131: ICMP echo request, id 9380, seq 2, length 64
23:16:21.960458 d4:8c:b5:4d:a5:3a > 60:73:5c:68:b4:b6, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 84)
10.10.0.132 > 10.10.0.131: ICMP echo request, id 9380, seq 3, length 64
回复的目标 MAC 地址与网关的 MAC 地址 10.10.0.1 匹配:
root@c220-2:~# arping -i eth2 10.10.0.1
ARPING 10.10.0.1
60 bytes from 30:f7:0d:bc:bb:52 (10.10.0.1): index=0 time=214.100 usec
如果我完全删除源策略路由规则,那么我就能够从 c220-2 连接,但无法从 192.168.3.1/24 连接到 10.10.0.131。
我如何指定规则,以便源策略路由不会将数据包发送到 10.10.0.1,而这些数据包应该发送到本地网络上的另一台机器?
答案1
我刚刚遇到了同样的问题,发现问题在于路由表的应用操作顺序。
如果您在应用策略路由之前发出以下命令:
[root@c220-1 ~]# ip rule show
0: from all lookup 255
32766: from all lookup main
32767: from all lookup default
然后:
[root@c220-1 ~]# ip rule show
0: from all lookup 255
32765: from 10.10.0.131 lookup eth2
32766: from all lookup main
32767: from all lookup default
恕我直言,我希望任何新的路由表都能应用于包含所有第 2 层转发语句的“主”路由表和“默认”路由表之间的某个位置。
我发现有两个方法可以解决这个问题
- 重新排序路由规则,使“主”表在任何自定义路由表之前应用,或者
- 将第 2 层转发语句添加到命名路由表
我们采用了第二种方法,首先手动将路由添加到命名路由表中,并验证连接是否按预期工作:
ip route add 10.10.0.0/24 dev eth2 src 10.10.0.131 table eth2
接下来,使上述更改在重启后仍然有效
创建路线文件:
[root@c220-1 ~]# vi /etc/sysconfig/network-scripts/route.eth2
10.10.0.0/24 dev eth2 src 10.10.0.131 table eth2
default table eth2 via 10.10.0.1
创建路由规则文件:
[root@c220-1 ~]# vi /etc/sysconfig/network-scripts/rule.eth2
from 10.10.0.131 table eth2
重新启动主机并验证路由策略是否持续
[root@c220-1 ~]# ip rule show
[root@c220-1 ~]# ip route show table eth2
附加信息 我通常不会推荐一堆静态路由,但是由于基础设施的限制,我们的场景在上述基础上进行了扩展,还需要通过辅助接口(在本例中为 eth2)路由出一个额外的子网
假设我们需要通过 eth2 到达 10.10.1.0/24,我们对上述配置进行了以下更改。
更新的路线文件:
[root@c220-1 ~]# vi /etc/sysconfig/network-scripts/route.eth2
10.10.0.0/24 dev eth2 src 10.10.0.131 table eth2
10.10.1.0/24 dev eth2 via 10.10.0.1 table eth2
default table eth2 via 10.10.0.1
更新的策略路由规则:
[root@c220-1 ~]# vi /etc/sysconfig/network-scripts/rule.eth2
from 10.10.0.131 table eth2
to 10.10.1.0/24 table eth2
重新启动网络并验证路由策略:
[root@c220-1 ~]# service networking restart
[root@c220-1 ~]# ip rule show
0: from all lookup 255
32764: from all to 10.10.1.0/24 lookup eth2
32765: from 10.10.0.131 lookup eth2
32766: from all lookup main
32767: from all lookup default
[root@c220-1 ~]# ip route show table eth2
10.10.0.0/24 dev eth2 src 10.10.0.131 scope link
10.10.1.0/24 via 10.10.0.1 dev eth2
default via 192.168.152.1 dev eth2
然后我们重新启动主机以验证所有路由策略是否持久
答案2
我没有任何 Linux 机器可以测试,但我认为你应该这样做:
root@c220-1:~# ip rule add from 192.168.3.0/24 table c2202
root@c220-1:~# ip route add default via 10.10.0.1 table c2202
我将表名从 eth2 更改以避免与接口名称混淆。