我在一台主机(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 rule
和ip route
(沿着ip link
和ip 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'
它们甚至可以通过工具处理系统网络中的钩子直接提供,例如网络管理器。