報文過濾和 鏈接跟蹤能夠說是Netfilter
提供的兩大基本功能。前者被大多數人熟知,由於咱們對防火牆的第一印象就是能夠阻止有害的報文傷害計算機;然後者就沒這麼有名了,不少人甚至不知道Netfilter
有這項功能。
顧名思義,鏈接跟蹤是保存鏈接狀態的一種機制。爲何要保存鏈接狀態呢? 舉個例子,當你經過瀏覽器訪問一個網站(鏈接網站的80
端口)時,預期會收到服務器發送的源端口爲80
的報文迴應,防火牆天然應該放行這些迴應報文。那是否是全部源端口爲80
端口的報文都應該放行呢?顯然不是,咱們只應該放行源IP爲服務器地址,源端口爲80
的報文,而應該阻止源地址不符的報文,即便它的源端口也是80
。總結一下這種狀況就是,咱們只應該讓主動發起的鏈接產生的雙向報文經過。瀏覽器
另外一個例子是NAT
。咱們可使用iptables
配置nat
表進行地址或者端口轉換的規則。若是每個報文都去查詢規則,這樣效率過低了,由於同一個鏈接的轉換方式是不變的!鏈接跟蹤提供了一種緩存解決方案:當一條鏈接的第一個數據包經過時查詢nat
表時,鏈接跟蹤將轉換方法保存下來,後續的報文只須要根據鏈接跟蹤裏保存的轉換方法就能夠了。緩存
Connection tracking hooks into high-priorityNF_IP_LOCAL_OUT
andNF_IP_PRE_ROUTING
hooks, in order to see packets before they enter the system.
鏈接跟蹤須要拿到報文的第一手資料,所以它們的入口是以高優先級存在於LOCAL_OUT
(本機發送)和PRE_ROUTING
(報文接收)這兩個鏈。服務器
既然有入口,天然就有出口。鏈接跟蹤採用的方案是在入口記錄,在出口確認(confirm
)。以IPv4
爲例:框架
當鏈接的第一個skb
經過入口時,鏈接跟蹤會將鏈接跟蹤信息保存在skb->nfctinfo
,而在出口處,鏈接跟蹤會從skb
上取下鏈接跟蹤信息,保存在本身的hash
表中。固然,若是這個數據包在中途其餘HOOK
點被丟棄了,也就不存在最後的confirm
過程了。網站
鏈接跟蹤信息會在入口處進行計算,保存在skb
上,信息具體包括tuple
信息(地址、端口、協議號等)、擴展信息以及各協議的私有信息。spa
tuple
信息包括髮送和接收兩個方向,對TCP
和UDP
來講,是IP
加Port
;對ICMP
來講是IP
加Type
和Code
,等等;TCP
就是序號、重傳次數、縮放因子等。途徑Netfilter
框架的每個報文老是會在入口處(PRE ROUTING
或者LOCAL OUT
)被賦予一個鏈接跟蹤狀態。這個狀態存儲在skb->nfctinfo
,有如下常見的取值:3d
Netfilter
目睹過兩個方向都互經過報文了ftp
,ftp-data
的鏈接就是ftp-control
派生出來的,它就是RELATED
狀態TCP
中的SYN
包,UDP
、ICMP
中第一個包,Netfilter
提供的一項基本功能,它能夠保存鏈接的狀態。用戶能夠爲不一樣狀態的鏈接的報文制定不一樣的策略;Netfilter
的入口將信息記錄在報文上,在出口進行confirm
.確認後的鏈接信息能夠影響以後的報文;tuple
以及各協議的私有信息。