Security

iptables - 如何殺死除 ip 之外的已建立連接?

  • April 25, 2021

我有 2 個 iptables 配置。第二個 iptables 在 15:00 替換第一個。第一個 iptables 是:

#!/bin/bash

/usr/sbin/iptables -F
/usr/sbin/iptables -P INPUT DROP
/usr/sbin/iptables -P FORWARD DROP
/usr/sbin/iptables -P OUTPUT ACCEPT

/usr/sbin/iptables -A INPUT -i lo -j ACCEPT
/usr/sbin/iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT

csa=MY_IP_TO_ALLOW

/usr/sbin/iptables -A INPUT -p tcp -m tcp -s $csa --dport 22 -m connlimit --connlimit-upto 1 -j ACCEPT
/usr/sbin/iptables -A INPUT -p tcp -m tcp -s $csa --dport 80 -m connlimit --connlimit-upto 1 -j ACCEPT
/usr/sbin/iptables -A INPUT -p tcp -m tcp -s $csa --dport 443 -m connlimit --connlimit-upto 1 -j ACCEPT
/usr/sbin/iptables -A INPUT -p tcp -s MY_SECOND_IP --dport 3306 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

第二個iptables是:#!/bin/bash

/usr/sbin/iptables -F
/usr/sbin/iptables -P INPUT DROP
/usr/sbin/iptables -P FORWARD DROP
/usr/sbin/iptables -P OUTPUT ACCEPT

/usr/sbin/iptables -A INPUT -i lo -j ACCEPT
/usr/sbin/iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT

/usr/sbin/iptables -A INPUT -p tcp -s MY_SECOND_IP  --dport 3306 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

當我從第一個 iptables 切換到第二個 iptables 時,我如何確定所有活動連接都會從保存在“csa”中的 ip 中被殺死?

我不是 iptables 的專家。這是一種保護外部 IP 的安全方法嗎?當第二個被啟動時,這是阻止第一個 iptables 中允許的 ip 連接的正確方法嗎?

非常感謝

  1. 利用iptables-restore

一條一條地添加規則會一次更改防火牆一條規則,防火牆規則集可能會出現不需要的中間狀態。相比之下,iptables-save原子地保存規則集,反向iptables-restore原子地恢復規則集(至少對於給定的表)。一個數據包要麼看到第一個規則集,要麼看到第二個規則集,但永遠不會看到中間狀態。

一旦有了工作規則集,就不應使用 shell 命令將其載入回來,而應使用iptables-save將規則轉儲到文件中並iptables-restore從該文件載入回來。這個文件可以很容易地直接編輯,因為它至少是規則本身的常用語法。如果存在動態組件(動態 IP、臨時 IP 禁令等),則應使用某些邏輯調整規則,例如使用使用者定義的鍊或配套ipset工具以及相關的匹配目標。 2. 已建立的連接將使用目前方法保持建立

iptables-restore由於有狀態的短路規則,以這種方式(或使用 )切換規則不會終止活動連接。此規則查詢仍然具有有效條目並將繼續允許流量的*conntrack 。*因此,儘管新規則集現在禁止它,但允許在埠 22 80 或 443 上已建立的連接無限期地持續(只要保持足夠的流量)。

要終止所有已建立的連接,還應該(安裝conntrack-tools並)在以下之後執行:

conntrack -F

這將刷新conntrack查找表,要求連接通過 NEW 狀態返回。埠 3306 的規則將保持已經建立的連接不受阻礙。 3. 即使conntrack -F預設情況下使用 TCP 也是不夠的。

已經建立的 TCP 連接有一個特殊的處理,可以從 TCP 屬性驗證它們的流,並允許在狀態 NEW 中再次創建一個conntrack條目,儘管沒有看到 TCP SYN 數據包。這由預設為鬆散的sysctl屬性控制。net.netfilter.nf_conntrack_tcp_loose

這仍然需要在iptables規則集中的某處允許 NEW 狀態。唉,情況就是這樣,因為OUTPUT鏈允許一切,所以這包括處於 NEW 狀態的流的數據包。因此,雖然來自客戶端的數據包現在最初被丟棄,但如果伺服器從先前的流向客戶端發出單個數據包,連接將不受阻礙地恢復。

  • 為了避免這種情況,通常可以netfilter.nf_conntrack_tcp_loose像這樣禁用:
sysctl -w net.netfilter.nf_conntrack_tcp_loose=0

這也會中斷之後與埠 3306 建立的連接`conntrack -F`。*conntrack-tools*不容易刪除除一個之外的每個流,因此使用多個`conntrack -D ...` 不是一種簡單的方法,但對於 OP 的特定情況(僅刪除三種流)來說很好:


換`conntrack -F`為:
nntrack -D -s $csa -p tcp --dport 22
nntrack -D -s $csa -p tcp --dport 80
nntrack -D -s $csa -p tcp --dport 443
另一種方法是保持鬆散的 TCP 處理,但也使用有狀態規則限制傳出數據包。


如(使用現代版本的[`state`](https://manpages.debian.org/iptables-extensions.8.en.html#state): [`conntrack`](https://manpages.debian.org/iptables-extensions.8.en.html#conntrack)):
tables -A OUTPUT -o lo -j ACCEPT
tables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
tables -P OUTPUT DROP

這種情況下,還應該使用類似的規則為伺服器所需的公共服務(DNS、NTP、Web 訪問等)啟用顯式傳出流量`-A OUTPUT -p ... --dport ... -m conntrack --ctstate NEW -j ACCEPT`。




---


注意:我離開了RELATED的處理。在 ESTABLISHED 中使用 RELATED 通常是個好主意。


例如 OP 的規則不允許 ICMP,因此如果沒有 RELATED 規則來啟用相關的 ICMP 錯誤,[路徑 MTU 發現將無法正常工作](https://en.wikipedia.org/wiki/Path_MTU_Discovery#Problems)(例如:通過路徑中的隧道時 TCP 連接可能會掛起)。仍然應該先看看這個部落格:[安全使用 iptables 和連接跟踪助手](https://home.regit.org/netfilter-en/secure-use-of-helpers/)。

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