Linux

如何使用 nftables 設置最大連接限制?

  • February 1, 2022

我希望限制與 Linux 伺服器上執行的給定服務的並發連接數。我的理解是,這可以通過iptables使用connlimit模組來完成。例如,如果我想限制與我的 SSH 伺服器的並發連接(並假設預設策略是拒絕),那麼這應該允許 10 個並發連接,第 11 個被拒絕(從記憶體中寫入):

iptables -A INPUT -p tcp --dport 22 -m connlimit --connlimit-upto 10 -j ACCEPT

事情是在我正在建構的新伺服器上,我想使用nftables. 雖然我可以connlimit在手冊頁中找到提到的內容,但它只是說明了consider native interface. Refer to Meters. 在搜尋了有關 Meters 的資訊後,雖然它在速率限制方面看起來很棒,但我找不到任何表明我可以做connlimit.

那麼,鑑於我想使用nftables,如何創建一個僅匹配 X 個並發連接的規則?

自 Linux 核心 4.18 以來添加了一個新的擴展nft_connlimit,它提供了一個表達式。ct count

對於這種情況,等效規則(從頭開始)將是:

nft flush ruleset
nft add table ip filter
nft add chain ip filter input '{ type filter hook input priority 0; }'
nft add rule ip filter input tcp dport 22 ct count 10 counter accept
# nft add rule ip filter input tcp dport 22 counter reject with tcp reset

一些備註:

  • 像往常一樣counter是可選的,用於獲取計數器nft list ruleset以了解規則觸發的次數。
  • 替換上面所有出現的ipwithip6將獲得 IPv6 的等價物。現在更有趣的是使用inet一起獲得 IPv4 和 IPv6 SSH 連接的組合計數,因為它們是由 conntrack 一起計算的。
  • 必須避免使用 4.19.0 和 4.19.9 之間的核心,因為使用此功能可能會使主機崩潰。(即將發布)核心 4.20 和核心 4.19.10 包括幾個與 conncount、修復崩潰和錯誤計數相關的更新檔。核心 4.18.x 的狀態未知。

更新:限制每個網路,而不僅僅是每個 IP,相當於 iptables’--connlimit-mask

從 netfilter-devel 郵件列表中的初始更新檔重新閱讀稀缺文件,不僅ct count限於單獨使用(或僅限於上面的範例)。它可以在meter表達式/列表中用於任何更複雜的用途。

如果一個人想要拒絕對埠 2222(某個程序正在偵聽)的連接,每個隨機 /24 網路源 IP 的連接計數超過 3 個,則應使用此規則(從 nft 0.9.0 / 核心 4.19.10 開始):

nft add rule ip filter input tcp dport 2222 meter test-2222-count-meter '{ ip saddr & 255.255.255.0 ct count over 3 }' counter reject with tcp reset

這將創建一個名為的儀表列表test-2222-count-meter,該列表將動態添加相關的“地圖”數據(對於每個不同的 /24 網路已匹配一個連接)。我不確定是否曾經通過垃圾收集刪除過時的數據(即 /24 網路不再有任何連接)。

可以列出儀表的內容(它不會顯示達到的計數,只是在看到新網路時動態添加的“地圖”)。例如,在來自10.0.3.1、和的一些連接10.0.3.66之後:10.0.4.5``172.31.4.5

# nft list meter ip filter test-2222-count-meter
table ip filter {
   meter test-2222-count-meter {
       type ipv4_addr
       size 65535
       elements = { 10.0.3.0 : ct count over 3 , 10.0.4.0 : ct count over 3 , 172.31.4.0 : ct count over 3  }
   }
}

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