Netfilter 是如何工作的(五):初識連接跟蹤(connection track)

logo

報文過濾連接跟蹤可以說是Netfilter提供的兩大基本功能。前者被大多數人熟知,因爲我們對防火牆的第一印象就是可以阻止有害的報文傷害計算機;而後者就沒這麼有名了,很多人甚至不知道Netfilter有這項功能。

Why 使用連接跟蹤

顧名思義,連接跟蹤是保存連接狀態的一種機制。爲什麼要保存連接狀態呢? 舉個例子,當你通過瀏覽器訪問一個網站(連接網站的80端口)時,預期會收到服務器發送的源端口爲80的報文迴應,防火牆自然應該放行這些迴應報文。那是不是所有源端口爲80端口的報文都應該放行呢?顯然不是,我們只應該放行源IP爲服務器地址,源端口爲80的報文,而應該阻止源地址不符的報文,即使它的源端口也是80。總結一下這種情況就是,我們只應該讓主動發起的連接產生的雙向報文通過

NAT

另一個例子是NAT。我們可以使用iptables配置nat表進行地址或者端口轉換的規則。如果每一個報文都去查詢規則,這樣效率太低了,因爲同一個連接的轉換方式是不變的!連接跟蹤提供了一種緩存解決方案:當一條連接的第一個數據包通過時查詢nat表時,連接跟蹤將轉換方法保存下來,後續的報文只需要根據連接跟蹤裏保存的轉換方法就可以了。

連接跟蹤發生在哪裏

Connection tracking hooks into high-priority NF_IP_LOCAL_OUT and NF_IP_PRE_ROUTING hooks, in order to see packets before they enter the system.

連接跟蹤需要拿到報文的第一手資料,因此它們的入口是以高優先級存在於LOCAL_OUT(本機發送)和PRE_ROUTING(報文接收)這兩個鏈。

既然有入口,自然就有出口。連接跟蹤採用的方案是在入口記錄,在出口確認(confirm)。以IPv4爲例:

arch

當連接的第一個skb通過入口時,連接跟蹤會將連接跟蹤信息保存在skb->nfctinfo,而在出口處,連接跟蹤會從skb上取下連接跟蹤信息,保存在自己的hash表中。當然,如果這個數據包在中途其他HOOK點被丟棄了,也就不存在最後的confirm過程了。

連接跟蹤信息是什麼

連接跟蹤信息會在入口處進行計算,保存在skb上,信息具體包括tuple信息(地址、端口、協議號等)、擴展信息以及各協議的私有信息。

struct

  • tuple信息包括髮送和接收兩個方向,對TCPUDP來說,是IPPort;對ICMP來說是IPTypeCode,等等;
  • 擴展信息比較複雜,本文暫時略過;
  • 各協議的私有信息,比如對TCP就是序號、重傳次數、縮放因子等。

報文的連接跟蹤狀態

途徑Netfilter框架的每一個報文總是會在入口處(PRE ROUTING或者LOCAL OUT)被賦予一個連接跟蹤狀態。這個狀態存儲在skb->nfctinfo,有以下常見的取值:

  • IP_CT_ESTABLISHED:這是一個屬於已經建立連接的報文,Netfilter目擊過兩個方向都互通過報文了
  • IP_CT_RELATED:這個狀態的報文所處的連接與另一個IP_CT_ESTABLISHED狀態的連接是有聯繫的。比如典型的ftpftp-data的連接就是ftp-control派生出來的,它就是RELATED狀態
  • IP_CT_NEW:這是連接的第一個包,常見的就是TCP中的SYN包,UDPICMP中第一個包,
  • IP_CT_ESTABLISHED + IP_CT_IS_REPLY:與IP_CT_ESTABLISHED類似,但是是在回覆方向
  • IP_CT_RELATED + IP_CT_IS_REPLY:與IP_CT_RELATED類似,但是是在回覆方向

總結

  • 連接跟蹤Netfilter提供的一項基本功能,它可以保存連接的狀態。用戶可以爲不同狀態的連接的報文制定不同的策略;
  • 連接跟蹤在報文進入Netfilter入口將信息記錄在報文上,在出口進行confirm.確認後的連接信息可以影響之後的報文;
  • 連接跟蹤的信息主要包括基本的描述連接的tuple以及各協議的私有信息。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章