/proc/net/nf_contrack 是鏈接跟蹤文件,它裏面的內容由 nf_conntrack.ko 模塊寫入。在 iptables 中使用 -m state 選項時,iptables 不但加載 xt_state.ko 模塊,且 nf_conntrack.ko 模塊也會被加載進來。通常而言,xt_state.ko 和 nf_conntrack.ko 這兩個模塊在許多 Linux 發行版裏是默認編譯進內核的。
下面經過幾個試驗來淺析一下 nf_conntrack 中的內容。
先打開一個已經鏈接不上了的網站,而後查看一下該文件內容: 服務器
[root@beyes beyes]# cat /proc/net/nf_conntrack ipv4 2 udp 17 168 src=192.168.1.104 dst=192.168.1.1 sport=53221 dport=53 src=192.168.1.1 dst=192.168.1.104 sport=53 dport=53221 [ASSURED] mark=0 zone=0 use=2 ipv4 2 tcp 6 115 SYN_SENT src=192.168.1.104 dst=66.85.191.46 sport=49535 dport=80 [UNREPLIED] src=66.85.191.46 dst=192.168.1.104 sport=80 dport=49535 mark=0 zone=0 use=2 ipv4 2 tcp 6 116 SYN_SENT src=192.168.1.104 dst=66.85.191.46 sport=49536 dport=80 [UNREPLIED] src=66.85.191.46 dst=192.168.1.104 sport=80 dport=49536 mark=0 zone=0 use=2 ipv4 2 udp 17 19 src=192.168.1.104 dst=192.168.1.1 sport=43652 dport=53 src=192.168.1.1 dst=192.168.1.104 sport=53 dport=43652 mark=0 zone=0 use=2
將上面的每一行,根據每一個空白所分隔做爲一個字段,好比第 1 個字段是 ipv4,第 2 個字段是 2,第 3 個字段是 udp 等。
首先看第 1 條記錄
該條記錄主要是描述 DNS 解析的。首先客戶端對服務器發出一個請求包,當這個數據報到達防火牆時,該鏈接在 state 模塊裏就認爲是 NEW 狀態,所以, nf_conntrack 模塊隨即將該鏈接信息添加到 /proc/net/nf_contrack 文件中來。下面是主要字段的說明:
第 3 個字段表示使用 udp 協議。
第 4 個字段中的 17 表示 udp 的協議編號,能夠在 /etc/protocols 文件中查詢到。
第 6 和 第 7 個字段 src=192.168.1.104 dst=192.168.1.1 分別指出了發出 udp 包的源地址 192.168.1.104 和發往的目的地址 192.168.1.1 。這裏須要說明的是,我這裏的上網環境是路由器撥號,我的計算機接在路由器上。所以,對於客戶機來講,路由器192.168.1.1 是一個 DNS,而真正的 DNS 是在路由器裏設置的,好比能夠自動獲取 ISP 所提供的 IP 或者自定義一個。
第 8 到第 13 個字段指出了客戶機和路由器的 IP 地址,以及通信時所用的端口,DNS 服務器使用 53 端口,客戶機則隨機使用。
第 14 個字段 [ASSURED] 表示客戶端和路由器之間的鏈接已經確認。
第 5 個字段的值關係到兩個文件,一個是 /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream ,另外一個是 /proc/sys/net/netfilter/nf_conntrack_udp_timeout 。第 1 個文件中的值是 180,第 2 個文件中的值是 30 。像上面第 1 條 DNS 查詢記錄,當創建鏈接後,鏈接記錄就會寫到 /proc/net/nf_contrack 文件中,而後就開始從 180 秒(nf_conntrack_udp_timeout_stream)倒計時,若是時間到那麼就將該條記錄從文件中刪除。若是 DNS 查詢在發出後的 30 秒(nf_conntrack_udp_timeout)內還不能獲得服務器的迴應,那麼也會刪除掉該條記錄,注意如果這種狀況,那第 14 個字段的值爲 [UNREPLIED],表示服務器不響應客戶端。
再看第 2, 第 3 條記錄
在瞭解了上面的第 1 條記錄後,第 2, 第 3 條記錄的解釋也就大同小異了。注意看到,它的第 14 個字段的值是 [UNREPLIED] ,表示服務器沒法響應客戶端的請求。另外,第 6 個字段 SYN_SENT 表示鏈接狀態。在 TCP 協議中,在客戶端發送帶有 SYN 標記的數據包後,這條 TCP 的鏈接狀態就會設置爲 SYN_SENT (顧名思義,已經發送了 SYN),當這個帶有 SYN 標記的數據包送達防火牆時,防火牆上的 TCP 鏈接狀態也會設置爲 SYN_SENT,而對於 state 模塊來講,則是 NEW 狀態。接着,服務器的應答數據包裏會帶有 SYN 和 ACK 標記,若是能收到該應答包,那麼 TCP 的鏈接就進入 SYN_RECV 狀態。若是沒有等到服務器的應答,那麼防火牆就必須根據第 5 個字段的信息來處理這條鏈接。
第 5 個字段和上面的 UDP 的同樣,也是一個時間值。它表示,若是客戶端在超過 120 秒後還沒法獲得服務器端的應答,那麼該鏈接狀態在防火牆上就要被清除。這個 120 秒是由 /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_syn_sent 文件所給出。
當服務器對 SYN 請求發出應答數據包時,TCP 鏈接進入 SYN_RECV 狀態,當應答數據包經過防火牆時,防火牆在 nf_conntrack 文件中也會將狀態更新爲 SYN_RECV。此時,對於 state 模塊來講,它就是一個 ESTABLISHED 狀態了。若是客戶端不能接着響應服務器,那麼防火牆在 60 秒後會清除該鏈接記錄,這個 60 秒是由 /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_syn_recv 文件所給出的。
最後,當客戶端和服務器端完成三次握手 後,nf_conntrack 模塊也會將 /proc/net/nf_contrack 文件中的鏈接信息更新爲 ESTABLISHED。注意,這裏的 ESTABLISHED 狀態是 TCP 鏈接狀態,而不是 state 模塊所描述的 ESTABLISHED 狀態,state 的 「鏈接」 狀態已經在TCP 的 SYN_RECV 時已經設立。當 TCP 的 ESTABLISHED 狀態創建後,客戶端和服務器就經過該條鏈接傳輸數據與通信。若是在鏈接創建後,但一直沒有傳輸任何數據包,那麼防火牆會在 432000 秒以後清除該條記錄,此時客戶端和服務器端的鏈接將被迫中斷。432000 這個時間值由 /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established 這個文件給出。若是在此時間內,若是又有數據傳輸,那麼這個值又自動恢復爲 432000 自動延續生命週期。tcp