Linux

如何將預設源 IP 地址更改為不同於面向預設路由的地址?

  • March 9, 2020

背景資料

  • 我正在使用 Linux 系統為一小塊公共 IPv4 地址路由流量(通過在 中啟用 IP 轉發sysctrl.conf)。
  • eth1路由器正在使用 PPPoE連接到 ISP 。
  • 用於 ppp 的本地對等地址是由 ISP 指定的手動配置的 IP 地址。本地對等地址是10.0.0.10
  • 用於 ppp 的遠端對等地址也是 ISP 指定的手動配置的 IP 地址。本地對等地址是10.0.0.9
  • 路由器的預設路由是10.0.0.9via 10.0.0.10
  • 路由器通過 連接到乙太網交換機eth0eth0配置為使用公共地址之一。
  • 交換機連接所有其他公共主機。每個連接的主機都使用一個公共 IP 地址。
 10.0.0.9
ISP ----------+
             |   10.0.0.10                       X.X.X.X
             +------------- (eth1) ROUTER (eth0) --------------- SWTICH 
                                                                    |     
                                                                    +-- X.X.X.Y
                                                                    +-- X.X.X.Z
                                                                    ...

我的問題

除了在路由器上執行的程序外,一切都按預期工作。我在路由器上執行的任何應用程序10.0.0.10在啟動與 Internet 的連接時都用作源 IP 地址。這是可以理解的,因為eth1網際網路是可用的。但是,由於該地址不可公開路由,因此aptping和其他程序不起作用。如果我在支持它的應用程序(即ping)上明確設置源地址,應用程序確實可以工作。

我的問題

如何將路由器配置為通過eth1/路由未知數據包,同時在啟動新連接10.0.0.9時還使用公共 IP 地址作為預設源?eth0

注意:我會考慮你的路由器的區域網路是192.0.2.0/24,它在eth0上的區域網路IP是192.0.2.1/24,以便能夠給出具體的解釋和解決方案。

為了節省一些公共 IP 地址,您的 ISP 為您分配了一個私有 IP,用於內部路由。這很好,因為這個 IP 永遠不會在外面看到(如果曾經放在 ISP 路由器之外的線路上,並且如果沒有,由於不可路由,將永遠不會得到沿路徑的嚴格反向路徑轉發回复)。但這會使您的配置更加複雜,以避免在所有情況下都使用此 IP,但從您的路由器連接到 ISP。

你可能有類似的東西(可能略有不同,沒關係):

# ip route
default via 10.0.0.9 dev ppp0 
10.0.0.9 dev ppp0 proto kernel scope link src 10.0.0.10 
192.0.2.0/24 dev eth0 proto kernel scope link src 192.0.2.1 

例如,您可能有default via 10.0.0.9 dev ppp0 src 10.0.0.10 ,或者via 10.0.0.9甚至沒有出現,因為它是第 3 層連結而不是第 2 層連結,因此via不需要(但仍被接受)。只需相應地調整以下設置。

目前,核心選擇顯然最適合的 IP,即設置在同一側以訪問 Internet 的 IP,因為沒有任何其他說明(或者它明確告訴使用您不想要的 IP):

# ip route get 8.8.8.8
8.8.8.8 via 10.0.0.9 dev ppp0 src 10.0.0.10 uid 0 
   cache 

當核心檢查如何訪問網際網路並聲明特定的首選源 IP 地址時,您只需要替換路由行為。請注意,如果出現錯誤和不可預見的問題,您可能會失去連接。如果可能,具有備用(控制台)訪問權限:

# ip route replace default via 10.0.0.9 dev ppp0 src 192.0.2.1
# ip route get 8.8.8.8
8.8.8.8 via 10.0.0.9 dev ppp0 src 192.0.2.1 uid 0 
   cache 

就是這樣,您的路由器將照常路由,但是當需要選擇本地發起的傳出 IP 時,將選擇 192.0.2.1,除非另有明確說明(例如:程序明確綁定其套接字上的源 IP)。

每次鏈路關閉然後打開時,必須再次設置此路由。在連結完全建立後,您可以將其集成到一些 pppoe 腳本中。

另請注意,介面名稱ppp0可能會更改為ppp1或任何其他名稱。這取決於您在設置腳本中處理此問題。


設置相同路由設置的替代方法:

  1. 在最初設置指標時添加較低的指標

如果設置了原始指標(即它不是 0,假設它是 100),您可以添加一個具有較低指標的備用預設路由,而不是替換以前的:

   # ip route add default via 10.0.0.9 dev ppp0 src 192.0.2.1 metric 50
  1. 專用路由規則

如果您擔心 pppoe 中涉及的各種工具的互動可能會刪除上述路由,您可以將此設置安裝在備用路由表中,並在路由規則中賦予其優先級,並使用主表的部分副本來防止中斷。每次斷開/重新連接後仍然需要重做,因為路由仍然會消失。這iif lo是特殊的,真正的意思是“本地發起的傳出數據包”而不是傳入的,109 是任意選擇的表值:

   # ip rule add iif lo lookup 109 # needed only once
   # ip route add table 109 10.0.0.9 dev ppp0 proto kernel scope link src 10.0.0.10 # to keep using 10.0.0.10 for local link, just in case
   # ip route add table 109 192.0.2.0/24 dev eth0 src 192.0.2.1 # will disappear if eth0 is brought down
   # ip route add table 109 default via 10.0.0.9 dev ppp0 src 192.0.2.1 # will disappear if ppp0 is brought down

如果您在主表中添加了其他路由條目,您可能還必須在上面複製它們。

   # ip route get 8.8.8.8
   8.8.8.8 via 10.0.0.9 dev ppp0 table 109 src 192.0.2.1 uid 0 
       cache 

引用自:https://unix.stackexchange.com/questions/571950