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信息(地址、端口、協議號等)、擴展信息以及各協議的私有信息。spa

struct

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

報文的鏈接跟蹤狀態

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

  • 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以及各協議的私有信息。
相關文章
相關標籤/搜索