ip_conntrack: table full, dropping packet
伺服器上出現了這樣的錯誤(/var/log/messages):
ip_conntrack: table full, dropping packet.
查了一些資料,原因是使用了iptables,伺服器的串連數太大,核心的 Connection Tracking System(conntrack)沒有足夠的空間來存放串連的資訊,解決 方法就是增大這個空間。
查看當前大小:
$ sysctl net.ipv4.netfilter.ip_conntrack_max net.ipv4.netfilter.ip_conntrack_max = 65535
增大空間,/etc/sysctl.conf修改或新增下面內容:
net.ipv4.netfilter.ip_conntrack_max = 655350
生效:
$ sysctl -p
那麼,什麼是Connection Tracking System(conntrack),它是如何工作的,和 iptables的關係是什麼,為了弄清這些問題,我又查了一些資料,整理如下。
Netfilter
Netfilter is a set of hooks inside the Linux kernel that allows kernel modules to register callback functions with the network stack. A registered callback function is then called back for every packet that traverses the respective hook within the network stack.1
簡單地說,Netfilter Framework通過在 Linux network protocol stack 上的一系列 hooks,提供了一種機制,使得核心模組可以在 network stack 中註冊一些回呼函數,每 個網路包的傳輸都會經過這些回呼函數。
而iptables是基於Netfilter Framework上的一套工具,運行於使用者態,用於配製網路包的 過濾規則。由於iptables的chains和hooks和Netfilter Framework有同樣的名字,但 iptables只是在Netfilter Framework上的一個工具而已。
The Hooks and Callback Function
Netfilter在Linux network stack中插入了5個hooks,實現了在不同的階段對包進行處理 。
-
- PREROUTING: 所有的包都會進過這個hook,在路由之前進行。DNAT等 就是在這一層實現。LOCAL INPUT: 所有要進入原生包都經過這個hook.FORWARD: 不進入原生包經過這個hook.LOCAL OUTPUT: 離開原生包經過這個hook.POSTROUTING: 經過路由之後的包會經過這個hook,SNAT就在這一層實現。所有由 本機發出的包都要經過這個hook.
NF_IP_PRE_ROUTING NF_IP_FORWARD NF_IP_POST_ROUTING [1] ====> ROUTER ====> [3] =============> [4] || /\ || || || ROUTER \/ || [2] ===> LOCAL PROCESS ===>[5] NF_IP_LOCAL_IN NF_IP_LOCAL_OUT
可以在一個hook上註冊callback函數,callback的返回下面的某個值:
- ACCEPTDROPQUEUE: 通過nf_queue把包傳到使用者空間;STOLEN: Silently holds the packet until something happens, so that it temporarily does not continue to travel through the stack. This is usually used to collect defragmented IP packets.也就是說暫停包的傳輸直到某個條 件發生;REPEAT: 強制這個包重新走一遍這個hook;
總之就是,Netfilter Framework提供了一個架構,可以在包傳輸的不同階段,通過回調 函數的方式對包進行過濾。
上面提到了”defragmented IP packets”, Wikipedia解釋如下;
The Internet Protocol (IP) implements datagram fragmentation, breaking it into smaller pieces, so that packets may be formed that can pass through a link with a smaller maximum transmission unit (MTU) than the original datagram size.
簡單地說就是資料包的長度大於了MTU的大小,就會把資料包分區,裝在多個較小的包裡面 傳輸出去。
The Connection Tracking System and the Stateful inspectionConnection Tracking System, which is the module that provides stateful packet inspection for iptables.
Basically, the connection tracking system stores information about the state of a connection in a memory structure that contains the source and destination IP addresses, port number pairs, protocol types, state, and timeout. With this extra information, we can define more intelligent filtering policies. Connection tracking system just tracks packets; it does not filter. (Netfilter’s connection tracking system)
串連的狀態在conntrack系統中,一個串連可能有如下的狀態:
- NEW: 串連正在建立,比如對於TCP串連,收到了一個SYN包;ESTABLISHED: 串連已經建立,可以看到“來往”的包;RELATED: 關聯的串連;INVALID: 不合法的;
所以,即使像是UDP這樣無狀態的協議,對於Connection Tracking System也是有狀態的。
實現conntrack系統主要使用一個hash表來檢索查詢。表中的每一項,都是一個雙鏈表。( Each bucket has a double-linked list of hash tuples.)一個串連有兩個hash tuples ,一個是“來”(包來自於建立串連的那一方)方向,一個是“回”方向。每個tuple都存了這 個串連的相關資訊,兩個tuple的又組織在nf_conn結構中,該結構就代表了一個串連的 狀態。
Hash表中hash值的計算是基於3層和4層的一些協議資訊,同時引入了一個隨機量防止攻擊 。conntrack表有一個最大容量,表充滿時,就會選擇一個最近使用時間最早的conntrack 丟棄。
回呼函數nf_conntrack_in註冊在PREROUTING hook上,它會檢查包的合法性,並且在表 中查詢這個包是否屬於哪個conntrack,如果沒找到的話,一個新的conntrack就會被建立 ,並且其中confirmed標誌沒有被設定。在LOCAL INPUT和POSTROUTING上註冊的 nf_conntrack_cofirm函數,會把一個conntrack的confirmed標誌設定上。對於進入本 機或者forward出去的包,這兩個hook是包最後的經過的hook,如果這時包還沒有被丟棄的 話,就設定confirmed位並且把建立的conntrack加入到hash表中。
Helpers and Expectation一些應用程式層的協議不容易被追蹤,比如FTP的passive mode,使用21連接埠做控制,另外又用 一個隨機連接埠擷取資料。對於使用者來說 這兩個串連是聯絡在一起的(related)。
Conntrack系統提供了一種叫做helper的機制,使得系統能夠判斷一個串連是否和已經存在 的某個串連有關係。改機制定義了expectation的概念,一個expectation指在一個 預期的時間段內出現的串連。那FTP來說,helper在返回的包中尋找資料轉送連接埠的相關信 息,找到的話,找到的話,一個expectation就被建立並被插入到expectation的鏈表中。
當一個conntrack建立時,conntrack系統首先會尋找是否有匹配的expectation,沒有的話 就會對這個串連使用helper。如果找到匹配的expectation,新的conntrack就會和建立那 個expectation的conntrack關聯起來。
JH, 2014-01-14
參考資料:
- http://www.netfilter.org/Netfilter’s connection tracking system