在 1 个 IP 上 ping 具有双 IP 的主机,回显从其他 IP 返回

在 1 个 IP 上 ping 具有双 IP 的主机,回显从其他 IP 返回

我在一台主机(i5 CPU、8GB RAM、SSD 和 HDD)上运行 Fedora 33,该主机设置为路由器;它有 5 个 NIC。我已设法使用 nftables 使双互联网网关和双 LAN 运行良好。

一个网关是带 pppoe 的 DSL,另一个是有线调制解调器。两个网关都连接并可以看到互联网。两个 LAN 都可以看到互联网并提供互联网可以看到的服务。IOW、NAT 和转发运行良好。

问题在于:我不知道如何设置路由表。问题在于,度量值最低的网关可以与 NAT 配合使用并转发到其 LAN,但它会关闭 NAT 并转发到其他网关和 LAN。从 LAN 机器的角度来看,我一次只能在一个网关上运行所有操作。

root@gata[~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         67.193.x.x      0.0.0.0         UG    100    0        0 coglink
0.0.0.0         206.248.x.x     0.0.0.0         UG    104    0        0 ppp0
10.0.0.0        0.0.0.0         255.0.0.0       U     103    0        0 tekgw
67.193.56.0     0.0.0.0         255.255.248.0   U     100    0        0 coglink
192.168.1.0     0.0.0.0         255.255.255.0   U     102    0        0 coggw
206.248.155.132 0.0.0.0         255.255.255.255 UH    105    0        0 ppp0

我知道可以设置路由,以便 10.0.0.0 上的机器始终使用 ppp0,而 192.168.1.0 上的机器始终使用 coglink,但在网上搜索如何做到这一点却无果而终。面向互联网的接口也是如此。如果有人能为我提供一份清晰易懂的有关多个接口 IP 路由的相关教程,我将不胜感激。

答案1

本答案将使用策略路由,其中​​数据包的命运不仅由其目的地决定,还(首先)由其他因素(此处为源 IP 地址和/或传入接口)决定。策略路由不适用于 Linux-obsolete 命令,route而仅适用于使用ip ruleip route(沿着ip linkip address)。目标是将所有路由的单一视图拆分为多个路由表,每个路由表将提供要使用的路由的特定视图,就好像不存在其他不感兴趣的部分一样。除其他事项外,这允许定义多个要同时使用的默认路由:每个路由表一个。

默认情况下,只有这一条规则存在,(其中最后一条规则的默认表为空):

# ip rule show
0:  from all lookup local
32766:  from all lookup main
32767:  from all lookup default

这里OP的情况可以用处理数据包时的这种策略路由来表达:

  • 包来自科格林克或来自考格接口使用 Cogeco 专用路由表的路由
  • 包来自点对点0或来自特克格接口使用 Teksavvy 专用路由表的路由

虽然人们可以只添加规则来处理点对点0并留下主路由表句柄科格林克为了对称起见,我仍然会为两者添加规则。


完成一些空白点并选择任意值(以提供没有语法错误的命令):

  • 科格林克的本地地址任意选择为 67.193.56.92/21
  • 科格林克的网关被任意选择为 67.193.56.1,而不是 67.193.xx
  • Cogeco 的路由表具有任意选择的值 7992
  • 点对点0的本地地址任意选择为 206.248.155.133
  • 假设点对点0是第 3 层接口(即使通过以太网,它仍然是点对点的),因此不需要网关进行正确的路由(否则在适当的位置添加via 206.248.155.132)。
  • Teksavvy 的路由表具有任意选择的值 5645

每个路由表将仅包含要使用的 WAN,而不是两者,但还必须包含将使用该 WAN 的网络的路由。如果出现以下情况,则必须复制这些 LAN 路由安全防御框架协议已启用否则这些 LAN 路由通常可以省略(只要它们在主要的路由表)。

ip route add 67.193.56.0/21 dev coglink table 7992
ip route add default via 67.193.56.1 dev coglink table 7992
ip route add 192.168.1.0/24 dev coggw table 7992
ip rule add iif coglink lookup 7992
ip rule add iif coggw lookup 7992

ip route add default dev ppp0 table 5645
ip route add 10.0.0.0/8 dev tekgw table 5645
ip rule add iif ppp0 lookup 5645
ip rule add iif tekgw lookup 5645

这不会影响以路由器作为终端节点本身的流量,它将继续仅使用主表(以及具有较低度量的默认路由:科格林克's) 因为:

  • (总是如此)进入路由器自身 IP 地址的流量在当地的优先级为 0 的策略规则首先查找路由表。不再查找其他表。
  • 传出流量不会被任何添加的策略规则选中

因此,某些特殊情况只会在 Fedora 路由器上失败(当没有实际路由时),例如选择点对点0的 IP 地址作为源,而目的地在互联网上,仍将选择通过科格林克并且无法正常工作。当路由器在其 ppp0 IP 地址上应答 ping 时,就会发生这种情况。

因此,为了解决问题的标题,为了让路由器本身在与接口上的 IP 地址绑定并通过另一个接口路由时选择正确的路由,可以添加从源地址选择路由表的附加规则:

ip rule add from 67.193.56.92 lookup 7992
ip rule add from 206.248.155.133 lookup 5645

即使只知道可能的地址范围(例如:使用命令检索whois)也足够了,只需使用iif lo具有特殊含义的附加选择器即可从本地系统(而不是来自接口)。 前两个规则可以替换为:

ip rule add from 67.193.48.0/20 iif lo lookup 7992
ip rule add from 206.248.128.0/18 iif lo lookup 5645

对于其他情况(当套接字最初未绑定时),主要的路由表中具有最低度量的默认路由将选择接口(目前科格林克) 并默认将其 IP 地址作为源。


注意事项和警告:

  • 提供的 NAT 规则iptables或者nftables仍然需要

    iptables现在看起来是这样的,因为传出接口总是被正确选择:

    iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o coglink -j MASQUERADE
    iptables -t nat -A POSTROUTING -s 10.0.0.0/8 -o ppp0 -j MASQUERADE
    

    nftables内核 >= 5.5入口接口可用于后布线

    mynat.nft(与 一起使用nft -f mynat.nft):

    table ip mynat
    delete table ip mynat
    
    table ip mynat {
            chain mypost {
                    type nat hook postrouting priority srcnat; policy accept;
                    iif "coggw" oif "coglink" masquerade
                    iif "tekgw" oifname "ppp0" masquerade
            }
    }
    

    当然,选择更简单的 NAT 规则就可以了。

  • 如果接口消失并重新出现,或者只是关闭和启动,则必须重新应用许多先前完成的设置:路由将消失并且必须重新应用,并且引用接口的路由规则在某些情况下可能会变得陈旧。

    • 因此,必须在启动时和之后与处理网络的工具进行一些集成,以保持这些路由表和路由规则正常工作。

    • 如果工具有限制,可以更改一些策略路由规则以适应。例如,在当前拓扑下,iif tekgw几乎(但不完全)等同于from 10.0.0.0/8

  • 即使科格林克地址和默认路由网关改变,这两条信息仍然可用...科格林克接口和路由(如果使用了 DHCP,可能还会在 DHCP 客户端的租约文件中)。这只是重用现有数据进行集成的一个例子。下面是一个使用 JSON 输出的示例,jq

    地址:

    ip -json -4 address show dev coglink primary | jq -r '.[].addr_info[] | "\(.local)/\(.prefixlen)"'
    

    网关:

    ip -json -4 route show default dev coglink  | jq -r '.[].gateway'
    

    它们甚至可以通过工具处理系统网络中的钩子直接提供,例如网络管理器

相关内容