![iptable 的 conntrack 模組何時追蹤封包的狀態?](https://rvso.com/image/756248/iptable%20%E7%9A%84%20conntrack%20%E6%A8%A1%E7%B5%84%E4%BD%95%E6%99%82%E8%BF%BD%E8%B9%A4%E5%B0%81%E5%8C%85%E7%9A%84%E7%8B%80%E6%85%8B%EF%BC%9F.png)
它首先需要存儲狀態。對於我使用的一些舊的 BSD 防火牆,我猜被命名為 IPFW,我曾經放置一條滿足「追蹤離開封包的狀態」的規則,並將其放置在介面的出站方向上。然後,入站方向上的另一個規則會根據出站方向上的規則所建立的狀態檢查它們。因此,曾經有 2 條規則:(1) 填入 states 表,這是在出站方向上,(2) 尋找 states 表,這是在入站方向上。
但是對於connntrack,我看到它應用在INPUT鏈上,例如這個規則:
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
這讓我想知道,這個聲明實際上是在做什麼?
- 是不是說它將透過將資訊放入狀態表中來開始追蹤與該規則相符的資料包?
- 或者它是否表示它已經擁有狀態訊息,並且將根據該訊息對入站訊息採取行動? (例如,如果它們屬於先前接受的連接,則接受?)。但是,在這種情況下,states 表是在哪裡填入的呢?是哪一條規則規定的?還是它是無規則且隱含的?
答案1
Netfilter 和 conntrack 的介紹
首先是 Netfilter 和通用網路中資料包流的強制性示意圖:
Netfilter 是一個封包過濾框架,將自身插入網路堆疊的其餘部分(由「路由決策」和其他白色圓邊框部分錶示)。 Netfilter 為其他子系統和「客戶端」提供鉤子和 API。這些部分中有連線(連接追蹤器)和iptables(或者nftables)。 Netfilter 與 Netfilter 之間的分離連線是相當模糊的。你可以考慮一下連線作為 Netfilter 的一個整合部分。
在描述資料包遍歷的各個步驟的示意圖中,您可以看到在某個點(在 raw/PREROUTING 和 mangle/PREROUTING 之間,或在 raw/OUTPUT 和 mangle/OUTPUT 之間)資料包遍歷連線。
在此刻,連線將在自己的查找表中搜尋(保存在內核記憶體中的小型查找資料庫):
- 如果未找到此資料包的特徵(且如果未在原始表中聲明 UNTRACKED),則新的 conntrack 雙向元組條目(協議,然後是特定的系列和協議資訊:初始來源和端口,初始目標和端口,回复源和端口,回复目標和端口(最後兩個通常是相反的,除非涉及NAT 或一些奇怪的協議,例如echo描述流的回應符合 ICMP 的回顯請求)) 是用狀態 NEW 建立的。
- 如果它與(在任何方向上)先前的條目匹配並且與該流的狀態相容,則流狀態可能會被更改(例如:如果之前不是這種情況,則從 NEW 更改為 ESTABLISHED )。
- 如果由於某種特定原因,資料包無法與現有流匹配,儘管它具有其特徵(例如:在已成功啟動重傳後收到的晚 TCP 資料包,因此在序列和 SACK 值方面超出了視窗)資料包將被標記為無效。
- 還有一些其他情況,例如 RELATED:這是關於資料包,不是流本身的一部分,而是與可以與其他現有(即:在資料庫中)流關聯的新流相關。兩個例子是接收資料包時創建的 ICMP 錯誤(例如:UDP 連接埠無法存取)或當特殊協定幫助程式(如核心模組)(
nf_conntrack_ftp
它是連線子系統,偵測封包是與在命令流(連接埠 21 上)上執行的 FTP 命令 PASV/EPSV 或 PORT/EPRT 關聯的單獨資料流的一部分。
解決問題
話雖如此,以下是您的兩個要點的答案:
在主網路命名空間中連線一旦加載其模組(包括可能的相關協定特定子模組),就開始追蹤連接。對於非初始網路命名空間(容器...),這也要求其他一些子系統引用它(例如 OP 的iptables的 conntrack 模組或使用稍後描述的命令
conntrack
)。這是預設設置,資料包必須明確標記為 UNTRACKED前這連線子系統認為該資料包未被追蹤。在 Linux 上,只有少數情況不需要跟踪,但當然,狀態防火牆和狀態/動態 NAT 將不再可用(steless NAT 甚至可能需要首先使用 UNTRACKED,但仍然可以使用)已完成,但未完成iptables。TC或者nftables能)。避免連線處理一些資料包,這種iptables可以使用規則(例如:連接埠 80/tcp):iptables -t raw -A PREROUTING -p tcp --dport 80 -j CT --notrack iptables -t raw -A OUTPUT -p tcp --sport 80 -j CT --notrack
當封包穿過filter/INPUT並到達此規則時:
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
這iptables的特定內核模組
xt_conntrack
查詢連線子系統(由各種相關的核心模組處理nf_conntrack*
)並詢問其查找資料庫中該資料包的狀態。如果答案是RELATED
或ESTABLISHED
資料包匹配,則繼續做出「接受」判決。其實結果已經緩存在數據包第一次查找完成時(通常是連線)所以這是一個廉價的“查找”。因此,這是處理之前已經接受的流的通用規則。這些流量最初可以在明確提及的規則中被接受-m conntrack --ctstate NEW
,或者簡單地在未提及但放置的規則中被接受後這個通用規則(但請記住無效狀態,通常應在執行此操作之前將其刪除)。新增一個項目符號:傳入資料包和傳出資料包的處理在 PREROUTING 和 OUTPUT 之間非常對稱(即使它們看起來不對稱):連線PREROUTING 和 OUTPUT 中的介面(以及其他一些地方,考慮到網路位址轉換正在與連線,除了其第一個資料包處於 NEW 狀態遍歷iptables的 nat 表)。這可能與您撰寫的有關 IPFW 的描述略有不同。如果運行應用程式的伺服器也限制傳出流量,那麼它很可能需要相同的通用iptables規則在過濾器/輸出和過濾器/輸入中,以允許已接受的傳入流量的傳出應答資料包通過。
附加資訊
有專門的工具可以與連線子系統的查找表來自conntrack 工具。
conntrack
:查詢、刪除或更新由處理的查找表的內容連線。一些例子。
您可以使用以下命令列出所有追蹤的條目(如果沒有額外的過濾器,這些條目可能會很大):
conntrack -L
如果您的系統正在執行 NAT(例如,專用 LAN 前面的路由器,或運行虛擬機器和容器),您可以使用
--any-nat
,--src-nat
或--dst-nat
來僅顯示相應內容。所有 NAT、所有來源 NAT(偽裝)或所有目標 NAT(通常用於轉送連接埠):即時監控連線事件:
conntrack -E
conntrackd
:一個守護進程,其兩個主要目的是(conntrack)流量記帳和統計,或者高可用狀態防火牆集群狀態同步。