情况 1:SSH 主机有一个网络接口
主机的路由表SSH
:
[SSH] $ ip route
default via 192.168.211.1 dev eth0
192.168.211.0/24 dev eth0 proto kernel scope link src 192.168.211.119
SSH_Client
启动从到 主机的ssh 连接SSH
,运行LAN_0
顺畅:
[SSH_CLIENT] $ ssh [email protected] -p 22
情况 2:SSH 主机有两个网络接口
主机的路由表SSH
:
[SSH] $ ip route
default via 192.168.0.1 dev eth1
192.168.0.0/24 dev eth1 proto kernel scope link src 192.168.0.113
192.168.211.0/24 dev eth0 proto kernel scope link src 192.168.211.119
SSH_Client
启动与主机的SSH
ssh连接,LAN_0
一切正常:
[SSH_Client] $ ssh [email protected]
启动与SSH_Client
主机的SSH
ssh连接LAN_211
,运行几秒钟后冻结:
[SSH_Client] $ ssh [email protected]
答案1
这是由于以下原因造成的不对称路由:弱宿主模型在Linux中使用:任何接口都可以用于属于主机的任何IP。
- 主持人客户将数据包发送到其自身 LAN 之外的地址,然后通过普富思路由器。
- 主持人SSH收到数据包eth0从 192.168.0.136 到 192.168.211.119
- 主持人SSH当回复遵循其路由表时,因此使用eth1回复客户使用源 IP 192.168.211.119:客户现在看到连接已建立。
- 猜测:路由器普富思,只有一半的流量(来自客户到SSH但不是来自SSH到客户),检测窗口外未确认的 TCP 流量,并在短时间后丢弃后续数据包。
如果主办SSH有已启用 严格反向路径转发,这根本行不通,考虑到目前的结果,这可能更好,因为SSH然后就会丢弃在 LAN 211 接口上接收的所有来自 LAN 0 的 IP 数据包。
解决方案是在主机上使用策略路由SSH纠正此多宿主 Linux 系统的行为:让它使用分配 IP 的同一侧进行应答。这是通过创建额外的路由表来实现的,其中故意只存在主表的部分(可能简化)副本,以便每个表忽略不应使用的接口。虽然通常只需要一个额外的表即可实现这一点,但使用具有两个表的对称设计更简洁。
此外,默认路由(通过普富思) 被添加回 LAN 211 特定表中。
然后,ip 规则将调用这些路由表,然后默认使用主表。
让我们使用任意选择的值 10000 和 10211 的表分别处理 LAN 0 和 LAN 211。
# ip route add table 10000 192.168.0.0/24 dev eth1
# ip route add table 10000 default via 192.168.0.1 dev eth1
# ip route add table 10211 192.168.211.0/24 dev eth0
# ip route add table 10211 default via 192.168.211.1 dev eth0
# ip rule add from 192.168.0.113 lookup 10000
# ip rule add from 192.168.211.119 lookup 10211
现在可以通过询问内核将选择哪条路径来验证每个源 IP 地址是否将使用正确的路径:
# ip rule
0: from all lookup local
32764: from 192.168.211.119 lookup 10211
32765: from 192.168.0.113 lookup 10000
32766: from all lookup main
32767: from all lookup default
# ip route get 192.168.0.136 from 192.168.0.113
192.168.0.136 from 192.168.0.113 dev eth1 table 10000 uid 0
cache
# ip route get 192.168.0.136 from 192.168.211.119
192.168.0.136 from 192.168.211.119 via 192.168.211.1 dev eth0 table 10211 uid 0
cache
这SSH主机现在可以同时接受来自两侧的连接:分别来自其两个 IP 地址,并且仍在正确的接口上正确路由每个流量。
附注:当 IP 地址尚未绑定到套接字时,这些规则将不匹配(例如:从主机发起的传出连接SSH作为标准客户端)。主要的表仍将被使用:
# ip route get 192.168.0.136
192.168.0.136 dev eth1 src 192.168.0.113 uid 0
cache
您必须自己弄清楚如何将这些设置集成到特定系统上使用的网络管理器中。这通常取决于发行版或工具。请注意,当 IP 地址被删除(然后重新添加)或接口被关闭(然后打开)时,表 10000 和 10211 将被刷新:每次发生此类事件后都必须再次更新它们,这与主表中的条目相反,内核会自动处理 LAN 路由(但不是默认路由)。
由于设置已得到纠正,原则上,也许是时候启用严格反向路径转发了(如果之前将值设置为 2 而不是 0,则需要最后两个命令:正如文档所述rp_filter
告诉更高的价值克服更低的价值):
# sysctl -w net.ipv4.conf.all.rp_filter=1
# sysctl -w net.ipv4.conf.eth0.rp_filter=1
# sysctl -w net.ipv4.conf.eth1.rp_filter=1