Router

在一個 IP 上使用雙 IP Ping 主機,從其他 IP 返回回顯

  • August 29, 2021

我在設置為路由器的主機(i5 cpu、8Gb RAM、SSD 和硬碟)上執行 Fedora 33;它有 5 個 NIC。我已經設法使用 nftables 讓雙網際網路網關和雙 LAN 工作得相當好。

一個網關是帶 pppoe 的 DSL,另一個是電纜調製解調器。兩者都可以連接並且可以看到網際網路。兩個區域網路都可以看到網際網路並提供網際網路可以看到的服務。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 路由的清晰相關教程,我將不勝感激。

此答案將使用策略路由,其中​​數據包的命運不僅取決於其目的地,而且(首先)取決於其他因素(此處為源 IP 地址和/或傳入介面)。策略路由不適用於 Linux-obsoleteroute命令,而僅適用於使用ip ruleand ip route(以及ip linkip address)的較新 API。目標是將所有路由的單個視圖拆分為多個路由表,其中每個路由表都將提供打算使用的路由的特定視圖,就好像其他不感興趣的部分不存在一樣。除此之外,這允許定義同時使用的多個預設路由:每個路由表一個。

預設情況下只有這個存在,(最後一條規則的預設表為空):

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

這裡 OP 的情況可以用這種策略路由來表達,當處理一個數據包時:

  • 來自coglinkcogw介面的數據包使用 Cogeco 專用路由表的路由
  • 來自ppp0tekgw介面的數據包使用 Teksavvy 專用路由表的路由

雖然可以只添加規則來處理ppp0並保留主路由表句柄coglink,但為了對稱起見,我仍然會為兩者添加規則。


完成一些空白點並選擇任意值(以提供沒有語法錯誤的命令):

  • coglink的本地地址任意選擇為 67.193.56.92/21
  • coglink的網關被任意選擇為 67.193.56.1 而不是 67.193.xx
  • Cogeco 的路由表具有任意選擇的值 7992
  • ppp0的本地地址任意選擇為 206.248.155.133
  • 假設ppp0是第 3 層介面(即使通過乙太網,它仍然是點對點的),因此正確路由不需要網關(否則在適當的地方添加via 206.248.155.132)。
  • Teksavvy 的路由表具有任意選擇的值 5645

每個路由表將僅包括要使用的 WAN,而不是兩者,但還必須包括到將使用它的網路的路由。如果啟用了 SRPF,這些 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

這不會影響將路由器作為端節點本身的流量,它將繼續僅使用主表(它是具有較低度量的預設路由:coglink的),因為:

  • (總是這樣)傳入路由器自己的 IP 地址的流量在本地路由表中處理,該路由表首先由優先級為 0 的策略規則查找。不再查找其他表。
  • 任何添加的策略規則都不會選擇傳出流量

因此,某些極端情況僅適用於 Fedora 路由器(實際上不是路由時),例如選擇ppp0的 IP 地址作為源,目標位於 Internet 上,仍然會通過coglink選擇路由,並且無法正常工作。這就是路由器在其 ppp0 IP 地址上應答 ping 時發生的情況。

因此,為了解決問題的標題,讓路由器本身在與介面上的 IP 地址綁定並通過另一個介面路由時選擇正確的路由,可以添加額外的規則,從源地址選擇路由表:

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

通過使用來自本地系統(而不是來自lo介面)的具有特殊含義的附加選擇器,即使只知道可能的地址範圍(例如:使用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

對於其他情況(當最初未綁定套接字時),路由表的預設路由具有最低度量將選擇介面(目前為 coglink)並預設將其 IP 地址作為源。


注意事項和警告:

  • iptablesnftables提供的 NAT 規則仍然需要

使用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.
  • 即使coglink地址和預設路由的網關發生變化,這兩條資訊仍然可用……在coglink介面和路由上(如果使用 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'

它們甚至可以由處理系統網路的工具中的鉤子直接提供,例如NetworkManager

引用自:https://serverfault.com/questions/1055614