Linux

Linux網路埠耗盡

  • October 18, 2020

我已經在這方面做了盡可能多的研究,而沒有直接探勘核心原始碼。關於這個主題似乎有大量虛假資訊/不正確資訊,所以我希望這能一勞永逸地回答我和其他人的問題。

嚴格來說是 IPv4,埠耗盡真的可能嗎?讓我解釋:

  • 似乎有 65535 個埠可供使用。0 不可用。
  • 我讀過埠耗盡要求 (src ip, src port, dst ip, dst port) 元組是唯一的。
  • 為了清楚起見,假設我可以通過 sysctl net.ipv4.ip_local_port_range 設置使用 100% 的臨時埠

這就是問題:它是這樣工作的嗎?

  • 我可以從 127.0.0.1:(x) 到 127.0.0.1:80 有 65k 個連接
  • 我可以有 65k 連接,從 127.0.0.1:(x) 到 127.0.0.1:555
  • 基本上再一次,問題是 (srcip,srcport,dstip,dstport) 必須是唯一的,對嗎?
  • 我無法打開從ip“A”到 IP“B”、埠“N”的超過 65k 個連接
  • 同樣,單個 IP無法在 xxxx:80 打開與我的網路伺服器的超過 65k 的連接,但是只要它們來自不同的源 IP ,我就可以支持超過 65k 的總體連接?

最後,我對(傳出)臨時埠和正在偵聽的傳入埠有點困惑。我意識到一旦建立連接,連接的每一端都是對等且平等的,但在此之前:

例如,如果確實 (srcip,srcport,dstip,dstport) 元組必須是唯一的,為什麼如果我啟用它,例如

net.ipv4.ip_local_port_range = 1024 65535

這允許使用 1024-65535 的臨時埠,如果我有綁定在埠 3306 上的服務(例如 mySQL),它們有時會因為埠正在使用而無法啟動。

這是否與以下事實有關:(這是我要求驗證的聲明):

  • (srcip,srcport,dstip,dstport) 對於每個埠範圍為 1-65535 的連接需要是唯一的(不注意作業系統對臨時埠的使用)
  • 但是,對於要綁定的套接字,它可以被視為 (srcip,srcport, *, *)。或者換一種說法,IP是否一定不能出於任何原因使用該埠來綁定?

我可以驗證上述行為,即我使用上面的確切 sysctl 行,因此我將 mySQL 移動到低於 1024 的埠,因為它偶爾會非常隨機地無法重新啟動,因為假設作業系統正在使用該埠(3306)對於臨時埠。

您在這裡有兩個主要問題:

1.

嚴格來說是 IPv4,埠耗盡真的可能嗎?

是的。例如,負載平衡路由器將所有連接發送到 NAT IP 地址。當您有許多SRC IP連接到單個DST IP.

這意味著您的網路伺服器可能有一堆連接,例如:

root@buglab:~# netstat -pnt
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 173.200.1.18:80      10.100.1.100:49923        ESTABLISHED 13939/nginx: worker
tcp        0      0 173.200.1.18:80      10.200.1.200:10155        ESTABLISHED 13939/nginx: worker
tcp        0      0 173.200.1.18:80      10.10.1.10:14400        ESTABLISHED 13939/nginx: worker
tcp        0      0 173.200.1.18:80      10.10.1.10:50652        ESTABLISHED 13939/nginx: worker
tcp        0      0 173.200.1.18:80      10.20.1.20:57554        ESTABLISHED 13939/nginx: worker 

這很好。但是,如果所有“外國地址”都相同,這可能會導致問題(例如,“使用一個 IP 地址執行 NAT <—> 伺服器的大型路由器”)。

如果我不得不假設為什麼短暫埠耗盡不是一個常見問題,我建議這是因為每個埠都需要一個監聽服務和足夠的資源來響應——另一個資源(記憶體、cpu)通常首先是一個瓶頸。

但是,在負載平衡公司工作時,我個人遇到了一些埠耗盡問題。

2. 為什麼使用的埠會給監聽服務帶來問題?

“這允許使用 1024-65535 的臨時埠,如果我有綁定在埠 3306 上的服務(例如 mySQL),它們有時會因為埠正在使用而無法啟動。”

如果該埠正在使用中,則 mySQL 伺服器無法綁定到該埠 - 例如通過 localhost:3306 或在所有介面上。例如,看到以下netstat輸出中的 0.0.0.0:80 行?

root@buglab:~# netstat -lnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      PID/Program name
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      964/php-fpm.conf)
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      1660/mysqld     
tcp        0      0 0.0.0.0:842             0.0.0.0:*               LISTEN      1317/inetd      
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      13938/nginx     

這意味著埠 80 正在偵聽伺服器本地的所有介面。nginx如果另一個程序在我的伺服器啟動之前持有埠 80 ,nginx將無法控制該埠,並且可能會導致其啟動過程失敗。

通常,埠 3306 很好,因為偵聽服務具有從主機請求的預定義埠(或範圍)——例如用於網路伺服器的埠 80 和 443。

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