Linux

如何在不硬重啟網路子系統的情況下讓 linux 尊重新的網路遮罩?

  • January 8, 2010

我不確定“榮譽”這個詞是否合適,但這是我能想到的最好的詞。我有一個場景,我在同一個網路上有兩台伺服器。它們有主 IP 和輔助 IP,都在同一個子網上。為了便於討論,它們看起來像這樣:

server1    eth0    172.16.45.3/24
server1-A  eth0:11 172.16.45.21/27
server1-B  eth0:12 172.16.45.22/27

server2    eth0    172.16.45.4/27

是的,server1 設置為 /24,是的,這是一個錯誤。

我注意到這個問題是因為來自 server1->server2 的連接的源 IP 為 172.16.45.21 而不是 172.16.45.3。由於發起連接的應用程序沒有指定源 IP,我很震驚它沒有使用 172.16.45.3。

那是我注意到不正確的網路遮罩的時候。由於目標 IP 位於已知較小的網路中,因此它使用來自相同 /27 的 IP,而不是它認為來自 /24 的 IP。哎呀。

因此,我通過執行以下命令修復了 server1:eth0 上的網路遮罩:

ifconfig eth0 netmask 255.255.255.224

ifconfig 現在看起來也很開心:

eth0      Link encap:Ethernet  HWaddr 00:22:19:54:EF:11  
         inet addr:172.16.45.3  Bcast:172.16.45.31  Mask:255.255.255.224
         inet6 addr: fe80::222:19ff:fe54:ef11/64 Scope:Link
         UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
         RX packets:1085587580 errors:0 dropped:1355 overruns:0 frame:0
         TX packets:1208356392 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:1000 
         RX bytes:365708046601 (340.5 GiB)  TX bytes:667099868812 (621.2 GiB)
         Interrupt:169 Memory:f8000000-f8012100 

此外,路由表會自行清理。

前:

server1 0 /home/jj33 ># route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.16.45.0     0.0.0.0         255.255.255.224 U     0      0        0 eth0
172.16.45.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     0      0        0 eth0
0.0.0.0         172.16.45.1     0.0.0.0         UG    0      0        0 eth0

後:

server1 0 /home/jj33 ># route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
172.16.45.0     0.0.0.0         255.255.255.224 U     0      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     0      0        0 eth0
0.0.0.0         172.16.45.1     0.0.0.0         UG    0      0        0 eth0

唯一的問題是,畢竟,作業系統似乎仍然選擇 172.16.45.21 作為出站連接到同一網路的源地址(SMTP 沒有直接解決這個問題,只是顯示源 IP 的一種方便方式連接):

server1 0 /home/jj33 ># telnet server2 25
Trying 172.16.45.4...
Connected to 172.16.45.4.
Escape character is '^]'.
220 server2.example.com ESMTP mailer ready at Wed, 23 Dec 2009 12:18:28 -0600
ehlo foo
250-server2.qcommcorp.com Hello server1-A.example.com [172.16.45.21]
250 HELP

(如果不是很明顯,我希望郵寄者說“你好 server1.example.com

$$ 172.16.45.3 $$“如果一切正常,則回應我的ehlo)。 所以,現在我的問題。如何讓我的作業系統注意到 eth0 上的網路遮罩已更改,從而使其成為與本地 /27 的出站連接的更好選擇?我認為重新啟動伺服器或重新啟動網路服務會做到這一點,但我必須等一個星期,直到我的下一個維護視窗,這似乎是我可以在不中斷服務的情況下做的事情(這是一個生產系統,這個不正確的源 IP 是小問題——核心應用執行良好)。

非常感謝任何幫助。謝謝!

2010 年 1 月 8 日更新:

所以,這個問題引起了比我預期的更多的關注,我最終獲得了允許將應用程序故障轉移到備用筒倉並在我們的標準視窗之外重新啟動受影響伺服器上的網路服務,這意味著我無法測試任何理論以下。

總的來說,儘管我相信Juliano 的回答涵蓋了最詳細的內容。我沒有複製和粘貼它,但在玩 ip 時,它通常似乎證實了他的假設。

此外,有足夠多的人傾向於使用 ip 而不是 ifconfig,以至於我花了一些時間玩它並向大家致敬,我當然應該使用 ip。感謝您的指點。

首先,不要使用ifconfigand route。這些命令在今天通常被認為是過時的;它們是很久以前編寫的,當時 Linux 有一個非常不同的網路堆棧,並且從那以後一直被修補。為了擁有多個地址而使用介面別名(例如*ethX:YY )的想法今天已經過時,它們仍然存在,主要是為了取悅 ifconfig 本身。*今天,該ip命令應該可以滿足您的所有需求。

現在,了解您的原始情況:您的 eth0 介面最初有兩個活動範圍:/24 和 /27。172.16.45.3 是 /24 範圍的主地址,而 172.16.45.21 是 /27 範圍的主地址(因為它列在最前面)。當您發出 ifconfig 命令來更改第一個地址的前綴時,它會刪除它並將其重新插入為 /27 範圍內的輔助地址。所以現在你應該有這樣的東西:

inet 172.16.45.21/27 brd 172.16.45.31 primary   eth0:11
inet 172.16.45.22/27 brd 172.16.45.31 secondary eth0:12
inet 172.16.45.3/27  brd 172.16.45.31 secondary eth0

eth0 應該是主要的,或者看起來應該是主要的都沒關係(另一個不使用 ifconfig 的原因)。它後來被插入到 /27 範圍內,因此它是輔助地址。這也意味著出站數據包將被定址到 172.16.45.21,並且如果您使用 ifconfig 關閉 eth0:11,那麼您的所有地址將一起被刪除。這就是它的工作原理。

解決此問題的唯一方法是從介面中刪除所有地址並以正確的順序重新插入它們。然後,添加的第一個地址(在 /27 範圍內)將是該範圍內的主地址,而後面的地址都將是輔助地址。

定址從一開始就被破壞了,在這種情況下你無能為力。您最好的解決方案是重新啟動網路服務。

一種可能的解決方法是更改​​源路由地址。這將具有與更改主地址幾乎相同的效果。在你的情況下:

ip route change 172.16.45.0/27 dev eth0 src 172.16.45.3

在這種情況下,發往 172.16.45.0/27 的數據包將源地址設置為 172.16.45.3。如果您還想更改通過網關的數據包的來源,您將需要另一個命令。

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