Iptables

使用 iptables 限制每個 IP 地址的最大連接數和每秒的新連接數

  • February 17, 2021

我們有一個 Ubuntu 12.04 伺服器,埠 80 上有 httpd,我們想限制:

  • 每個 IP 地址到 httpd 的最大連接數為 10
  • 每秒到 httpd 的最大新連接數為 150

我們如何使用 iptables 做到這一點?

iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 32 -j REJECT --reject-with tcp-reset  

這將拒絕來自一個源 IP 的超過 15 個的連接。

iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 150/second --limit-burst 160 -j ACCEPT  

在應用每秒 150 個新連接(數據包)的限制之前,允許 160 個新連接(實際上是數據包)。

您希望 iptables 中的以下規則能夠回答您問題中的兩個要求:

iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT

iptables -t filter -I INPUT -p tcp --dport 80 -m state \
 --state RELATED,ESTABLISHED -j ACCEPT

# Adjust "--connlimit-above NN" to limit the maximum connections per IP
#   that you need.
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
 --connlimit-above 10 --connlimit-mask 32 -j DROP

# Adjust "--connlimit-above NNN" to the maximum total connections you
#   want your web server to support
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
 --connlimit-above 150 -j DROP

因為我們使用 -I (根據 OP 請求),所以我們必須以相反的順序執行它們,所以從下往上“讀取”它們。

我還建議考慮將 –connlimit-mask NN 從 32 更改為 24。這會將完整的 C 類網路(同一範圍內最多 256 個 IP 地址)限制為 10 個連接。您還可以使用任何其他無類別數字,例如 22 或 30,具體取決於您認為您的服務可能會被如何使用。

此外,根據您希望客戶端的行為方式,您可能希望在上述兩個規則中使用“-j REJECT –reject-with tcp-reset”而不是“-j DROP”,甚至僅在最大 150 個連接中使用規則。

如果您拒絕連接,使用埠 80 的瀏覽器或軟體將立即顯示“不可用”狀態,但 DROP 選項將導致客戶端等待並重試幾次,然後再報告該站點不可用。我自己傾向於使用 DROP,因為它的行為更像是連接不良而不是離線伺服器。

此外,如果連接限制在仍在重試時回落到 150(或 10)以下,那麼它最終會連接到您的伺服器。

但是,REJECT 選項會導致站點的流量減少一小部分,因為 DROP 會導致它在重試時發送額外的數據包。可能不是那麼相關。

另一方面,如果您的埠 80 流量是集群的一部分,那麼 REJECT 將告訴集群控制器它已關閉,並在重試超時期間停止向其發送流量。

RELATED,ESTABLISHED 規則假設您的預設規則是阻止所有流量(iptables -t filter -P INPUT DROP)。這只是接受屬於已接受連接的其他數據包。

此外 –syn 告訴它注意(或計算)建立 TCP 連接的數據包。

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