在一個 IP 上使用雙 IP Ping 主機,從其他 IP 返回回顯
我在設置為路由器的主機(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-obsolete
route
命令,而僅適用於使用ip rule
andip route
(以及ip link
和ip address
)的較新 API。目標是將所有路由的單個視圖拆分為多個路由表,其中每個路由表都將提供打算使用的路由的特定視圖,就好像其他不感興趣的部分不存在一樣。除此之外,這允許定義同時使用的多個預設路由:每個路由表一個。預設情況下只有這個存在,(最後一條規則的預設表為空):
# ip rule show 0: from all lookup local 32766: from all lookup main 32767: from all lookup default
這裡 OP 的情況可以用這種策略路由來表達,當處理一個數據包時:
- 來自coglink或cogw介面的數據包使用 Cogeco 專用路由表的路由
- 來自ppp0或tekgw介面的數據包使用 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 地址作為源。
注意事項和警告:
- iptables或nftables提供的 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。