iptables连接跟踪ip_conntrack
一、ip_conntrack模塊介紹:
ip_conntrack 是Linux NAT一個跟蹤連接條目的模塊記錄著允許的跟蹤連接條目ip_conntrack 模塊會記錄 tcp 通訊協議的 established connection 記錄, 而且預設 timeout 時間長達五天 (432,000 秒).所以局域網中當有人使用p2p類的軟件就很容易使ip_conntrack達到最大值…也由此造成:
ip_conntrack: table full, dropping packet. ?的錯誤提示..網關丟棄數據包..網絡中斷..
具體解決辦法如下幾種:
1.加大ip_conntrack_max設定值
#modprobe ip_conntrack 需提前加載ip_conntrack模塊
#echo “986400″ > /proc/sys/net/ipv4/ip_conntrack_max 數值具體多大應計算得出
開機使用新數值..有三種辦法:
除vi /etc/rc.local外亦有:
#vi /etc/sysctl.conf 加入: net.ipv4.ip_conntrack_max = 986400
#sysctl -w net.ipv4.ip_conntrack_max=986400
2.減小ip_conntrack timeout 的時限 默認5天即432000s
ip_conntrack_tcp_timeout_established 值默認432000s 即5天
#echo “3600″ > /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_established
開機使用同于上例
#vi /etc/sysctl.conf 加入: net.ipv4.ip_tcp_timeout_established = 3600
#sysctl -w net.ipv4.ip_tcp_timeout_established=3600
3、為防止重啟Iptables后變為默認,還需修改模塊參數:
? ? ? ? vim/etc/modprobe.conf #添加以下內容
? ? options ip_conntrack hashsize=12800 ? ? ? ?#值為102400/8
-允許的最大跟蹤連接條目,在這篇文檔中我們叫作CONNTRACK_MAX
-存儲跟蹤連接條目列表的哈西表的大小,在這篇文檔中我們叫做HASHSIZE(下面是這個結構的描述)
CONNTRACK_MAX是在內核內存中netfilter可以同時處理的“任務”(連接跟蹤條目)。
一個跟蹤連接的條目是存儲在一個鏈接起來的列表的一個節點上,每個列表都是一個哈西表的元素。因此每個哈西表的條目(也叫一個桶-bucket)包含了一個鏈接起來的跟蹤連接條目。
要訪問一個特定包的跟蹤連接條目,內核必須:
-針對一個包中的已經定義的一些字符計算哈西值。這是一個不間斷的計算。
? 這個哈西值就會被當作哈西表的索引來使用,而跟蹤連接條目的列表就存儲在這里。
-反復的查看鏈接列表中的跟蹤連接條目以找到匹配的那一個。
? 這是一個耗資源的操作,依賴于列表的大小(也依賴于列表中被操作的跟蹤連接條目的位置)。
哈西表包含了HASHSIZE大小的鏈接條目。當條目滿的時候(總的跟蹤連接條目數達到了CONNTRACK_MAX),理想狀態下,每個列表(在最優化的條件下)將包含大約CONNTRACK_MAX/HASHSIZE的條目數。
不管你是否有連接,哈西表都將占用一個固定大小的非交換內核內存。但是最大連接跟蹤條目會檢測最多可以存儲多少條目(globally into the linked lists),也就是說他們最多可以占用多少的內核內存。
在i386架構上,HASHSIZE = CONNTRACK_MAX / 8
4、iptables raw表解決ip_conntrack: table full, dropping
RAW 表只使用在PREROUTING鏈和OUTPUT鏈上,因為優先級最高,從而可以對收到的數據包在連接跟蹤前進行處理。一但用戶使用了RAW表,在某個鏈 上,RAW表處理完后,將跳過NAT表和 ip_conntrack處理,即不再做地址轉換和數據包的鏈接跟蹤處理了.
RAW表可以應用在那些不需要做nat的情況下,以提高性能。如大量訪問的web服務器,可以讓80端口不再讓iptables做數據包的鏈接跟蹤處理,以提高用戶的訪問速度。
? ? ? ? iptables -A INPUT -m state --state UNTRACKED,ESTABLISHED,RELATED -j ACCEPT
iptables -t raw -A PREROUTING -p tcp --dport80 -j NOTRACK
iptables -t raw -A OUTPUT -p tcp --sport80 -j NOTRACK
5、舉例說明:
? 通過ip_conntrack buffer 使用狀況查出局域網中進行p2p下載的主機
查看目前 ip_conntrack buffer 使用狀況
? #grep conn /proc/slabinfo
結果實例: ip_conntrack 5918 8140 384 10 1:tunables 54 27 0:slabdata 814 814 0 (各值說明如下)
? ip_conntrack the cache name
? 5918 the number of currently active objects
? 8140 the total number of available objects
? 384 the size of each object in bytes
? 814 the number of pages with at least one active object
? 814 the total number of allocated pages
? 1 the number of pages per slab are given
man slabinfo 可查詢詳細說明.
查出目前 ip_conntrack 記錄最多的前五名 IP
? #cat /proc/net/ip_conntrack | cut -d ' ' -f 10 | cut -d '=' -f 2 | sort | uniq -c | sort -nr | head -5
結果實例:
?2987 192.168.1.30
? 334 192.168.1.52
? 166 192.168.1.56
? ?99 192.168.1.43
? ?84 192.168.1.46
由此可知, 192.168.1.30占用了絕大多數的ip_connect buffer,推斷這個IP的User可能使用了P2P軟件
推薦一個清除某IP鏈接的方法:通過過濾ip_conntrack表得到ESTABLISHED狀態過多的ip,用hping工具將這些ip從表中清理掉…
?下載: http://www.hping.org/download.html
安裝: ./configure;make;make install
hping清理IP鏈接腳本:(此腳本修改鏈接狀態為closed)
? #!/bin/sh
? ? if [ -z $1 ] ; then
? ? ? ? ? ? echo “NO INPUT IP”
? ? ? ? ? ? exit
? ? fi
? ? grep -E “^tcp .{10,25}ESTABLISHED src=$1 ” /proc/net/ip_conntrack | while read line; do
? ? S_IP=`echo $line | awk ‘{print substr($5,5)}’`
? ? S_SOCK=`echo $line | awk ‘{print substr($7,7)}’`
? ? D_IP=`echo $line | awk ‘{print substr($6,5)}’`
? ? D_SOCK=`echo $line | awk ‘{print substr($8,7)}’`
? ? echo “$S_IP:$S_SOCK $D_IP:$D_SOCK”
? ? hping2 $D_IP -R -s $S_SOCK -p $D_SOCK -a $S_IP -k -c 1 > /home/huaying/1.log 2>&1 &
? ? done
附:linux NAT 性能優化常用設置…
#echo “1024 65000″ > /proc/sys/net/ipv4/ip_local_port_range
#echo “100 1200 128 512 15 5000 500 1884 2″>/proc/sys/vm/bdflush
#echo “1″ > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
#echo “1″ > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
#echo “1048576″ > /proc/sys/net/ipv4/netfilter/ip_conntrack_max
#echo “1″ > /proc/sys/net/ipv4/ip_forward
#echo “268435456″ >/proc/sys/kernel/shmall
#echo “536870912″ >/proc/sys/kernel/shmmax
#echo “600″ > /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_established
#echo “1024″ > /proc/sys/net/ipv4/neigh/default/gc_thresh1
#echo “2048″ > /proc/sys/net/ipv4/neigh/default/gc_thresh2
#echo “4096″ > /proc/sys/net/ipv4/neigh/default/gc_thresh3
#echo “52428800″ > /proc/sys/net/ipv4/route/max_size
#echo “1″ > /proc/sys/net/ipv4/conf/all/proxy_arp
#echo “1″ > /proc/sys/net/ipv4/tcp_window_scaling
二、iptables連接跟蹤(Connection tracking)
? ? ? ?每個網絡連接包括以下信息:源地址、目的地址、源端口和目的端口,叫作套接字對(socket pairs);協議類型、連接狀態(TCP協議)和超時時間等。防火墻把這些信息叫作狀態(stateful),能夠檢測每個連接狀態的防火墻叫作狀態包 過濾防火墻。它除了能夠完成簡單包過濾防火墻的包過濾工作外,還在自己的內存中維護一個跟蹤連接狀態的表,比簡單包過濾防火墻具有更大的安全性。
? ? ? iptables中的狀態檢測功能是由state選項來實現的。對這個選項,在iptables的手冊頁中有以下描述:
? ? ? state ? ? ? ? ?這個模塊能夠跟蹤分組的連接狀態 ? ?--state state
? ? ? 這里,state是一個用逗號分割的列表,表示要匹配的連接狀態。有效的狀態選項包括:
INVAILD,表示分組對應的連接是未知 的;
ESTABLISHED,表示分組對應的連接已經進行了雙向的分組傳輸,也就是說連接已經建立;
NEW,表示這個分組需要發起一個連接,或者說,分組對應的連接在兩個方向上都沒有進行過分組傳輸;
RELATED,表示分組要發起一個新的連接,但是這個連接和一個現有的連接有關,例如:FTP的數據傳輸 連接和控制連接之間就是RELATED關系。
? ? ? ?對于本地產生分組,在PREROUTING或者OUTPUT鏈中都可以對連接的狀態進行跟蹤。在進行狀態檢測之前,需要重組分組的分片。這就是為什么在iptables中不再使用ipchains的ip_always_defrag開關。
? ? 1、 ?UDP和TCP連接的狀態表由/proc/net/ip_conntrack進行維護。稍后我們再介紹它的內容。狀態表能夠保存的最大連接數保存在/proc/sys/net/ipv4/ip_conntrack_max中。它取決于硬件的物理內存。
? ? ? ?iptables的連接跟蹤(Connection tracking),是如何工作的?
? ? ? 首先了解一下netfilter框架。如果要在兩個網絡接口之間轉發一個分組,這個分組將以以下的順序接收規則鏈的檢查:
? ? ? 1) PREROUTING鏈
? ? ? ?如果必要對這個分組進行目的網絡地址轉換(DNAT)和mangle處理。同時,iptables的狀態檢測機制將重組分組,并且以以下某種方式跟蹤其狀態:
? ? ? 分組是否匹配狀態表中的一個已經實現(ESTABLISHED)的連接。它是否是和狀態表中某個UDP/TCP連接相關(RELATED)的一個ICMP分組。這個分組是否要發起一個新(NEW)的連接。如果分組和任何連接無關,就被認為是無效(INVALID)的。
? ? ? 2) FORWARD鏈
? ? ? ?把分組的狀態和過濾表中的規則進行匹配,如果分組與所有的規則都無法匹配,就使用默認的策略進行處理。
? ? ? 3) POSTROUTING鏈
? ? ? ?如果有必要,就對分組進行源網絡地址轉換(SNAT),
注意:所有的分組都必須和過濾表的規則進行比較。如果你修改了規則,要拒絕所有的網絡流量,那么即使分組的狀態匹配狀態表中的一個ESTABLISHED條目,也將被拒絕。
下面,我們對UDP、TCP和ICMP三個協議分別進行分析。
? ?2、UDP連接
? ? ? ?UDP(用戶數據包協議)是一種無狀態協議,以為這個協議沒有序列號。不過,這并不意味著我們不能跟蹤UDP連接。雖然沒有序列號,但是我們還可以使用其它的一些信息跟蹤UDP連接的狀態。下面是狀態表中關于UDP連接的條目:
? ? ? ? ? ? ? ?udp 17 19 src=192.168.1.2 dst=192.168.1.50 sport=1032 dport=53 [UNREPLIED] src=192.168.1.50 ? ? ? ? ? ? dst=192.168.1.2 sport=53 dport=1032 use=1
? ? ? ? 這個狀態表項只有在iptables過濾規則允許建立新的連接時,才能建立。以下的規則可以產生這類狀態表項,這兩條規則只允許向外的UDP連接:
iptables -A INPUT -p udp -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -P udp -m state --state NEW,ESTABLISHED -j ACCEPT
上面的狀態表項包含如下信息:連接的協議是UDP(IP協議號17)。這個狀態表項還有19秒中就超時。發起連接方向上的源、目的地址和源、目的端口。應答方向上的源、目的地址和源、目的端口。這個連接使用UNREPLIED標記,表示還沒有收到應答。
? ? ? ?UDP連接的超時時間在/usr/src/linux /net/ipv4/netfilter/ip_conntrack_proto_udp.c文件中設置,如果改變了這個值,需要重新編譯Linux內核源代碼才能生效。下面是UDP連接超時時間的相關的源代碼:
#define UDP_TIMEOUT (30*HZ)
#define UDP_STREAM_TIMEOUT (180*HZ)
? ? ? 一個UDP請求等待應答的時間是30*HZ(這個值一般是30秒)。在上面的例子中,等待的時間已經消耗了11秒,還剩余19秒,如果在這段時間之內沒有 收到應答分組,這個表項就會被刪除。一旦收到了應答,這個值就被重置為30,UNREPLIED標志也被刪除。這個表項編程如下形式:
? ? udp 17 28 src=192.168.1.2 dst=192.168.1.50 sport=1032 dport=53 src=192.168.1.50 dst=192.168.1.2 sport=53 dport=1032 use=1
如果在這一對源、目的地址和源、目的端口上,發生了多個請求和應答,這個表項就作為一個數據流表項,它的超時時間是180秒。這種情況下,這個表項就變成如下形式:
? ? ? udp 17 177 src=192.168.1.2 dst=192.168.1.50 sport=1032 dport=53 src=192.168.1.50 dst=192.168.1.2 sport=53 dport=1032 [ASSURED] use=1
? ? ? 這時我們看到這個表項使用ASSURED標志。一旦連接表項使用ASSURED標志,那么即使在網絡負沉重的情況下,也不會被丟棄。如果狀態表已經飽和,當新的連接到達時,使用UNREPLIED標志的表項會受被丟棄。
? ? 3、TCP連接(被*** 的大戶人家)
? ? ? ? 一個TCP連接是通過三次握手的方式完成的。首先,客戶程序發出一個同步請求(發出一個SYN分組);接著,服務器端回應一個SYN|ACK分組;最后返回一個ACK分組,連接完成。整個過程如下所示:
Client ? ? | ? ? Server
SYN --->;
? ? ? ? <--- SYN+ACK
ACK --->;
? ? ? ? <--- ACK
ACK --->;
? ? ? .........
? ? ? .........
? ? ? ?SYN和ACK是由TCP分組頭的標志決定的。在每個TCP分組頭還有32位的序列號和應答號用于跟蹤會話。
? ? ? ?為了跟蹤一個TCP連接的狀態,你需要使用下面這樣的規則 :
iptables -A INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT
? ? ? 一旦一個初始SYN分組進入OUTPUT鏈,并且輸出規則允許這個分組建立一個新的連接,是通過linux Client端進行連接,狀態表的相關表項將如下所示:
? ? ? ? tcp 6 119 SYN_SENT src=140.208.5.62 dst=207.46.230.218 sport=1311 dport=80 [UNREPLIED] src=207.46.230.218 dst=140.208.5.62 sport=80 dport=1311 use=1
? ? ? ? 其中,TCP連接狀態是SYN_SENT,連接被標記為UNREPLIED。
? ? ? ? Server端收到后返回SYN+ACK
? ? ? ? 現在,Clinet端等待SYN+ACK分組的響應。一旦得到響應,這個TCP連接表項就變為:
? ? ? ?tcp 6 57 SYN_RECV src=140.208.5.62 dst=207.46.230.218 sport=1311 dport=80 src=207.46.230.218 dst=140.208.5.62 sport=80 dport=1311 use=1
? ? ? ? ?連接的狀態變為SYN_RECV,UNREPLIED標志被清除。
? ? ? ? ?現在等待完成握手的ACK分組。ACK分組到達后,首先對其序列號進行一些檢查,如果正確,就把這個連接的狀態變為ESTABLISHED,并且使用ASSURED標記這個連接。這時,這個連接的狀態如下所示:
? ? ? ? ? tcp 6 431995 ESTABLISHED src=140.208.5.62 dst=207.46.230.218 sport=1311 dport=80 src=207.46.230.218 dst=140.208.5.62 sport=80 dport=1311 [ASSURED] use=1
了解了TCP連接的狀態。現在,分析一下TCP連接的鏈路跟蹤檢測。實際上,狀態表只知道NEW、ESTABLISHED、RELATED和INVALID。
? ? ? ? 要注意:鏈路跟蹤檢測的狀態不等于TCP狀態。當一個SYN分組的響應SYN+ACK分組到達,Netfilter的狀態檢測模塊就會認為連接已經建立。但是,這時還沒有完成三次握手,因此TCP連接還沒有建立。
? ? ? ?另外,包過濾規則不能刪除狀態表中的表項,只有連接超時,對應的狀態表項才會被刪除。ACK分組能夠建立一個NEW狀態表項 。向防火墻之后一臺并不存在主機發送ACK分組,并不會返回RST分組,可以證明這個結論。因此,你需要使用以下的規則明確新的TCP連接應該是SYN分組建立的:
? ? ? ? ? ? ? ? iptables -A INPUT -p tcp !--syn -m state --state NEW -j DROP
這樣可以阻止空會話的繼續進行。
超時
所謂狀態表項的超時值是指每個表項存在的最大時間,這些超時值的大小在/usr/src/linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c文件中設置。以下是相關的代碼:
static unsigned long tcp_timeouts[]
= { 30 MINS, /* TCP_CONNTRACK_NONE, */
? ?5 DAYS, /* TCP_CONNTRACK_ESTABLISHED, */
? ?2 MINS, /* TCP_CONNTRACK_SYN_SENT, */
? ?60 SECS, /* TCP_CONNTRACK_SYN_RECV, */
? ?2 MINS, /* TCP_CONNTRACK_FIN_WAIT, */
? ?2 MINS, /* TCP_CONNTRACK_TIME_WAIT, */
? ?10 SECS, /* TCP_CONNTRACK_CLOSE, */
? ?60 SECS, /* TCP_CONNTRACK_CLOSE_WAIT, */
? ?30 SECS, /* TCP_CONNTRACK_LAST_ACK, */
? ?2 MINS, /* TCP_CONNTRACK_LISTEN, */
};
? ? ?4、.ICMP
? ? ? ? ? 在iptables看來,只有四種ICMP分組,這些分組類型可以被歸為NEW、ESTABLISHED兩類:
ECHO請求(ping,8 和ECHO應答(ping,0)。
時間戳請求(13)和應答(14)。
信息請求(15)和應答(16)。
地址掩碼請求(17)和應答(18 。
? 這些ICMP分組類型中,請求分組屬于NEW,應答分組屬于ESTABLISHED。而其它類型的ICMP分組不基于請求/應答方式,一律被歸入RELATED。
一個簡單的例子:
iptables -A OUTPUT -p icmp -m state --state NEW,ESTABLISHED, RELATED -j ACCEPT
iptables -A INPUT -p icmp -m state --state ESTABLISHED,RELATED -j ACCEPT
這鏈條規則進行如下的過濾:
? ? 一個ICMP echo請求是一個NEW連接。因此,允許ICMP echo請求通過OUTPUT鏈。
? ? 當對應的應答返回,此時連接的狀態是ESTABLISED,因此允許通過INPUT鏈。而INPUT鏈沒有NEW狀態,因此不允許echo請求通過INPUT鏈。也就是說,這兩條規則允許內部主機ping外部主機,而不允許外部主機ping內部主機。
? ? 一個重定向ICMP(5)分組不是基于請求/應答方式的,因此屬于RELATED。INPUT和OUTPUT鏈都允許RELATED狀態的連接,因此重定向(5)分組可以通過INPUT和OUTPUT鏈。
轉載于:https://blog.51cto.com/wushank/1264758
總結
以上是生活随笔為你收集整理的iptables连接跟踪ip_conntrack的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【职场攻略】是什么决定了我们的工资
- 下一篇: 丢失或损坏NDF文件如何附加数据库