2015/06/20

Netfilter的連接追蹤系統

引言

在Internet上搜尋到一篇文章Netfilter's Connection Tracking System ,搭配Yahoo字典、和Google翻譯等工具,我嘗試著將文章的片段翻譯成繁體中文版,希望大家對於Netfilter所提供的功能擁有些許認識。

摘要

以封包標頭資訊之獨特性為基礎的過濾策略已經過時了。近日,具備狀態防火牆(stateful firewall)提供了進階的機制,讓系統管理員與安全專家來定義更加聰明的策略。本文描述了Netfilter專案提供的連接追蹤系統的實作細節,以及諸如Netfilter框架的相關背景知識。本文將作為用來理解當前Linux核心所支援之具備狀態防火牆的最佳的補充文件。


Netfilter框架

Paul “Rusty” Russell於2.3.x開發時期草創了Netfilter專案,當時Linux既有的防火牆工具有著嚴重的缺陷、且必須完全重寫。Rusty決定重頭開始建立Netfilter框架,該框架包含了一組Linux網路協定堆疊的掛鉤(hook)。藉由這些掛鉤便可以向核心模組於不同的階段註冊一些網路封包處理程式。
Linux最受歡迎的防火牆工具iptables很容易跟Netfilter框架混淆,這是因為iptables的鏈(chain)和掛鉤有著相同的名稱,但iptables只是疊加在Netfilter框架之上的一塊磚。
很幸運的,Rusty花費了大量時間所撰寫的文件可以讓任何人上手並了解該框架,雖然某些時間必須不惜弄髒雙手去了解程式碼以便更加深入。

掛鉤與回呼函式

Netfilter插入了5個掛鉤至Linux網路堆疊以達到不同階段的封包處理,分述如下:
■PREROUTING:所有的封包,在進行選徑與IP標頭健全度檢查之前,都將命中這個掛鉤,無一例外。埠位址轉換和重導向、也就是所謂的DNAT (Destination Network Translation)便是在這個掛鉤實作的。
■LOCAL INPUT:所有準備進入本機的封包將命中這個掛鉤,作為最後一個本機入境的掛鉤。
■FORWARD:非進入本機的封包(例如穿越防火牆的封包)將抵達這個掛鉤。
■LOCAL OUTPUT:這是第一個出境封包路徑中的第一個掛鉤,本機的出境封包總是最先命中這個掛鉤。
■POSTROUTING:選徑之後將會命中這個掛鉤。SNAT (Source Network Address Translation)便註冊在這個掛鉤上。所有本機的出境封包也會抵達這個掛鉤。

接著,可以依據目的地來將流量區分為3種類型:
■穿越防火牆的流量,換言之,即不是到本機的流量。這類流量的路徑為PREROUTING、FORWARD、及POSTROUTING。
■防火牆的入境封包,也就是到本機的流量。這類流量的路徑為PREROUTING、及INPUT。
■防火牆的出境封包,這類流量的路徑為OUTPUT、及POSTROUTING。

可以註冊一個回呼函式至指定的掛鉤上,該回呼函式的雛型定義在netfilter.h的nf_hook_ops裡,該結構包含了該掛鉤、回呼函式、和優先權的相關資訊。一旦註冊一個以上的回呼函式至指定的掛鉤時,優先權用來指出哪一個先行執行。註冊的操作藉由nf_register_hook函式完成之。

回呼函式可以依據下列方式返回數種不同的值來讓框架解析:
■ACCEPT:讓封包持續地在堆疊裡遊走。
■DROP:沉靜地忽略該封包。
■QUEUE:藉由nf_queue的輔助把封包傳遞至userspace,因此userspace的程式可以處理封包。
■STOLEN:沉靜地把持住該封包直到某件事情發生,因此該封包暫時不會在堆疊裡遊走。通常用來收集分段的IP封包。
■REPEAT:強制讓封包重新進入掛鉤。

簡短說來,框架提供一個方法,讓註冊的回呼函式在前述的各階段以某種方式處理封包,返回的值可以讓框架依據該次的判決來套用特定的策略。
至此,若提供的資訊不足以理解Linux網路堆疊的背景,請參照其它文件以便了解封包如何在Linux網路堆疊裡遊走。

連接追蹤系統與具備狀態的檢查

以IP的來源、目的、及埠之類的封包標頭獨特性為基礎的過濾策略已經一去不復返了。多年來,這種方法已被證明不足以防止探測和拒絕服務攻擊。
幸運的是,目前系統管理員不太需要藉口以免去防火牆執行狀態過濾,目前已經有開放源碼的實作被用在量產的環境裡,像是Linux的這項特性便是因應Netfilter專案而生。連接追蹤則是疊加在Netfilter框架之上的另一塊磚。
基本上,連接追蹤系統儲存關於連接的狀態資訊到一個記憶體結構,該資訊包含了來源位址、目的位址、埠編號配對、協定類型、狀態、和逾時值。藉由這些額外的資訊便可以定義更加聰明的過濾策略。
此外,像是FTP、TFTP、IRC、與PPTP之類的應用協定很難利用傳統靜態過濾方式的防火牆來追蹤。連接追蹤系統定義了一個機制用來追蹤隨後將會描述的環節(aspect)。
連接追蹤系統不去過濾封包本身,預設的行為總是讓這些封包在網路堆疊裡遊走,雖然有一些很特別的例外將致使封包被丟棄(例如記憶體耗盡)。所以要記得連接追蹤系統只是追蹤封包,但不過濾封包。

狀態

連接可能處於的狀態分述如下:
■NEW:該連接正在啟動。當封包有效時便處於這個狀態,若其隸屬有效的初始化次序(例如在一個TCP連接中收到了SYN封包),然後防火牆只會觀察流量的單一方向(也就是說防火牆不會觀察回覆封包)。
■ESTABLISHED:當連接已經建立完畢時便處於這個狀態,換言之,防火牆觀察到雙向通訊時便會抵達這個狀態。
■RELATED:當連接是一個期望的連接時便處於這個狀態,文章隨後說明之。
■INVALID:當封包沒有遵守一個期望連接該有的行為時便處於這個狀態,系統管理員可以依據需求在iptables裡定義規則來記錄與丟棄該封包;如先前所描述的,連接追蹤系統不會過濾這類封包、而是提供一種過濾該類封包的途徑。
藉由隨後的方法,即便是無狀態的UDP也可以具備狀態,當然,前述狀態不會影響TCP的狀態。

重點

本文著重在獨立於第3層實作的nf_conntrack連接追蹤系統,它以IPv4相依的ip_conn_track為基礎、而後者在Linux核心第2.6.15版開始有效。對應之IPv4和IPv6特定的環節則分別在nf_conntrack_ipv4與nf_conntrack_ipv6模組被實作與支援。
第4層協定也在個別的模組被實作與支援。目前內建支援了TCP、UDP、與ICMP,SCTP則為選配。這些協定處理程式追蹤第4層協定細部的環節以確保連接正確地發展、且沒有出錯。
參照圖1,nf_conntrack_ipv4模組在數個掛鉤註冊了4個回呼函式,這些回呼函式座落在nf_conntrack_core.c檔案裡,取用第3層協定家族的參數,IPv6基本上也一樣。這些回呼函式可以區分為3類:conntrack修正與查詢、分段封包、與助手群(helpers)。由於nf_conntrack_ipv6與IPv4雷同故不再贅述。

實作議題

基礎結構

連接追蹤系統是一個選配的模組化可載入子系統,即便它總是被NAT子系統所需要。參照圖2,它利用雜湊表來達到有效率的查詢。每個bucket皆有雜湊tuple的雙向鏈結串列,每一個連接具備2個雜湊tuple,分別是發起方向(亦即封包來自發起該連接的點)、和回覆方向(亦即回覆封包至發起該連接的點)。
一個tuple呈現了一個連接、來源IP、目的IP、以及第4層協定資訊的關聯,這類tuple被嵌在一個雜湊tuple裡;結構被定義在nf_conntrack_tuple.h裡。
這2個雜湊tuple被嵌在nf_conn結構裡,也就是前述的conntrack,它儲存了已知連接的狀態。因此,conntrack為這2個雜湊tuple的容器,每個雜湊tuple為tuple的容器,而這導致了嵌入結構的3個層級。
雜湊函式用來計算呈現連接的雜湊tuple的位置,計算任務乃以相關的第3層與第4層協定資訊作為輸入參數;Jenkin的雜湊被用在雜湊函式。
雜湊計算利用隨機種子來增強避免可能之惡意使用者在已知雜湊鏈塞入的雜湊炸彈所造成的效能低落,因為這會導致雜湊tuple出現非常長的鏈。然而,conntrack表具有一個受限的conntrack的最大值,若它被填滿的時候,雜湊表中最近最少使用的conntrack將會被迫退出。conntrack表的尺寸可以在模組載入時、或核心開機的時候調整。

conntrack建立與查詢程序

nf_conntrack_in回呼函式被註冊在PREROUTING掛鉤,一些健全度檢查在這個階段完成,以便確保封包的正確性。
之後的檢查將發生於conntrack查詢程序中。該子系統嘗試查詢接收到的封包所匹配的conntrack,若沒有找到conntrack時則建立之,這個機制被resolve_normal_ct函式實作。
若封包隸屬於一個新的連接,剛建立的conntrack的confirmed旗標將被清除;若雜湊表具備該conntrack時才會把該旗標予以設定,這意味著這個時間點沒有新的conntrack被插入。每個插入動作將於封包成功地離開框架時發生(也就是抵達最後一個掛鉤而沒被丟棄)。一個封包與一個conntrack的關聯乃藉由指標來建立,若指標為空,則封包隸屬於無效的連接。iptables也允許取消某些連接,這個時候,冗餘的conntrack將被使用。
nf_conntrack_confirm被註冊在LOCAL INPUT與POSTROUTING掛鉤,如先前提到的,這2個掛鉤分別是本機流量與轉發流量的最後一個掛鉤。確認程序將在這些點執行,接著conntrack將被插入雜湊表、confirmed旗標將被設置、而關聯的計時器將被啟動。

分段封包的處理

分段封包的處理乃藉由ipv4_conntrack_defrag函式達成重整,一旦成功地接收了封包,封包的片段將繼續在堆疊中遊走。
在第2.4版核心分支,重整封包是線性的,也就是說這些封包會被複製到連續的記憶體裡;然而,在第2.6版核心分支引入了降低額外處理的影響的最佳化,封包的片段不再被複製到連續的記憶體裡,改為擺進一個串列,因此所有的處理程式必須知道有無分段。例如,若是需要儲存在TCP封包標頭的部份訊息時,必須留意該標頭有無分段,若有分段則所需的資訊已經被堆疊複製了,這部份因為已經具備便於操作的函式所以不會有問題,例如skb_header_point便曉得有無分段、且可以把所需之重整過的分段封包予以線性化,標頭檢查也不會招致任何的處理上的懲罰。

助手群與期望

有一些環節難以追蹤的應用層協定,例如FTP被動(passive)模式使用21埠控制要求伺服器某些資料的操作,但其使用1024至65535之間的TCP埠來接收要求的資料、而不是使用TCP的20埠,這件事意味著兩個獨立的連接本質上具有關聯。因此,防火牆需要額外的資料以便成功地過濾這類協定。
連接追蹤系統定義了一個稱為助手群的機制來讓系統辨識一個連接有無跟另一個既有的連接相互關聯。為了達到這個目標定義了一個稱為期望(expectation)的概念,一個期望指的是在限定期間發生的一個連接,有一個nf_conntrack_expect的結構被定義在nf_conntrack_core.h檔案內。
助手群在封包內搜尋環節難以追蹤的一組樣式。在FTP的案例中,參照圖3,助手群查詢被送出之回覆裡的啟動被動模式連接的PORT樣式(亦即在PASV方法),若樣式被找到時則一個期望隨之建立並且插入全域的期望清單,因此,助手群定義了一個可能之期望的連接的profile。
一個期望具有一個有限的存活時間,若conntrack被建立時,則連接追蹤系統搜尋匹配的期望,若無匹配則會查詢該連接的助手群。
當系統找到一個匹配的期望時則新的關聯至主conntrack的conntrack將被建立起來。例如FTP被動模式的例子中,呈現流向21埠控制埠的conntrack為主conntrack,呈現流向較高埠資料埠的conntrack則關聯至該conntrack。
助手群藉由nf_conntrack_helper_register來註冊之,其將添加一個助手群清單的結構。

結論與未來工作

有幾個Netfilter的連接追蹤系統既有實作的改進工作,例如在第4屆Netfilter Workshop便提到利用雜湊表樹來替換目前的雜湊表作法,初步看來性能良好。
更進一步,本文描述的子系統不只可以在核心端存取,額外還有稱為libnetfilter_conntrack的userspace函式庫可以作為核心連接追蹤狀態表的API。
至於助手群的部份,正在支援諸如H.323與VoIP網路電話的協定,此外有一些工作正在設法提供一個機制,以允許使用者在userspace實作自訂助手群,這也是Rusty進行Netfilter專案的早期想望。

參考文獻

原文下載網址 https://www.usenix.org/publications/login/june-2006-volume-31-number-3/netfilters-connection-tracking-system
維基百科對其的說明 https://en.wikipedia.org/wiki/Netfilter 



2 則留言:

  1. expect:
    This is the table of expectations. Connection tracking expectations are the mechanism used to "expect" RELATED connections to existing ones. Expectations are generally used by "connection tracking helpers" (sometimes called application level gateways [ALGs]) for more complex protocols such as FTP, SIP, H.323.

    conntrack:
    This is the default table. It contains a list of all currently tracked connections through the system. If you don't use connection tracking exemptions (NOTRACK iptables target), this means all connections that go through the system.

    http://conntrack-tools.netfilter.org/conntrack.html

    回覆刪除
  2. http://ebtables.netfilter.org/br_fw_ia/bridge3b.png

    回覆刪除