【正文】
iptables中的狀態(tài)檢測(cè)功能是由m state state選項(xiàng)來(lái)實(shí)現(xiàn)的,state這個(gè)模塊能夠跟蹤分組的連接狀態(tài)(即狀態(tài)檢測(cè))。state state這里,state是一個(gè)用逗號(hào)分割的列表,表示要匹配的連接狀態(tài)。有效的狀態(tài)選項(xiàng)包括:INVAILD,表示分組對(duì)應(yīng)的連接是未知的;ESTABLISHED,表示分組對(duì)應(yīng)的連接已經(jīng)進(jìn)行了雙向的分組傳輸,也就是說(shuō)連接已經(jīng)建立;NEW,表示這個(gè)分組需要發(fā)起一個(gè)新的連接,或者說(shuō),分組對(duì)應(yīng)的連接在兩個(gè)方向上都沒(méi)有進(jìn)行過(guò)分組傳輸;RELATED,表示分組要發(fā)起一個(gè)新的連接,但是這個(gè)連接和一個(gè)現(xiàn)有的連接有關(guān),例如:FTP的數(shù)據(jù)傳輸連接和控制連接之間就是RELATED關(guān)系。對(duì)于本地產(chǎn)生分組,在PREROUTING或者OUTPUT鏈中都可以對(duì)連接的狀態(tài)進(jìn)行跟蹤。在進(jìn)行狀態(tài)檢測(cè)之前,需要重組分組的分片。UDP和TCP連接的狀態(tài)表由/proc/net/ip_conntrack進(jìn)行維護(hù)。狀態(tài)表能夠保存的最大連接數(shù)保存在/proc/sys/net/ipv4/ip_conntrack_max中。它取決于硬件的物理內(nèi)存。 iptables的狀態(tài)檢測(cè)是如何工作 iptables概述首先大體看一下整個(gè)netfilter框架。如果要在兩個(gè)網(wǎng)絡(luò)接口之間轉(zhuǎn)發(fā)一個(gè)分組,這個(gè)分組將以以下的順序接收規(guī)則鏈的檢查:首先,是PREROUTING鏈。如果必要對(duì)這個(gè)分組進(jìn)行目的網(wǎng)絡(luò)地址轉(zhuǎn)換(DNAT)和mangle處理。同時(shí),iptables的狀態(tài)檢測(cè)機(jī)制將重組分組,并且以以下某種方式跟蹤其狀態(tài):216。 分組是否匹配狀態(tài)表中的一個(gè)已經(jīng)實(shí)現(xiàn)(ESTABLISHED)的連接。216。 它是否是和狀態(tài)表中某個(gè)UDP/TCP連接相關(guān)(RELATED)的一個(gè)ICMP分組。216。 這個(gè)分組是否要發(fā)起一個(gè)新(NEW)的連接。216。 如果分組和任何連接無(wú)關(guān),就被認(rèn)為是無(wú)效(INVALID)的。其次,是FORWARD鏈。把分組的狀態(tài)和過(guò)濾表中的規(guī)則進(jìn)行匹配,如果分組與所有的規(guī)則都無(wú)法匹配,就使用默認(rèn)的規(guī)則進(jìn)行處理。最后,是POSTROUTING鏈。如果有必要,就對(duì)分組進(jìn)行源網(wǎng)絡(luò)地址轉(zhuǎn)換(SNAT),注意:所有的分組都必須和過(guò)濾表的規(guī)則進(jìn)行比較。如果你修改了規(guī)則,要拒絕所有的網(wǎng)絡(luò)流量,那么即使分組的狀態(tài)匹配狀態(tài)表中的一個(gè)ESTABLISHED條目,也將被拒絕。 UDP連接UDP(用戶數(shù)據(jù)包協(xié)議)是一種無(wú)狀態(tài)協(xié)議,以為這個(gè)協(xié)議沒(méi)有序列號(hào)。不過(guò),這并不意味著我們不能跟蹤UDP連接。雖然沒(méi)有序列號(hào),但是我們還可以使用其它的一些信息跟蹤UDP連接的狀態(tài)。下面是狀態(tài)表中關(guān)于UDP連接的條目:udp 17 19 src= dst= sport=1032 dport=53 [UNREPLIED] src= dst= sport=53 dport=1032 use=1這個(gè)狀態(tài)表項(xiàng)只有在iptables過(guò)濾規(guī)則允許建立新的連接時(shí),才能建立。以下的規(guī)則可以產(chǎn)生這類狀態(tài)表項(xiàng),這兩條規(guī)則只允許向外的UDP連接:iptables A INPUT p udp m state state ESTABLISHED j ACCEPTiptables A OUTPUT p udp m state state NEW,ESTABLISHED j ACCEPT一個(gè)TCP連接是通過(guò)三次握手的方式完成的。首先,客戶程序發(fā)出一個(gè)同步請(qǐng)求(發(fā)出一個(gè)SYN分組);接著,服務(wù)器端回應(yīng)一個(gè)SYN|ACK分組;最后返回一個(gè)ACK分組,連接完成。整個(gè)過(guò)程如下所示:Client ServerSYN SYN+ACKACK ACKACK ..................SYN和ACK是由TCP分組頭的標(biāo)志決定的。在每個(gè)TCP分組頭還有32位的序列號(hào)和應(yīng)答號(hào)用于跟蹤會(huì)話。為了跟蹤一個(gè)TCP連接的狀態(tài),需要使用下面這樣的規(guī)則:iptables A INPUT p tcp m state state ESTABLISHED j ACCEPTiptables A OUTPUT p tcp m state state NEW,ESTABLISHED j ACCEPT用以下的規(guī)則明確新的TCP連接應(yīng)該是SYN分組建立的:iptables A INPUT p tcp ! –syn m state state NEW j DROP這樣可以阻止空會(huì)話的繼續(xù)進(jìn)行。在iptables看來(lái),只有四種ICMP分組,這些分組類型可以被歸為NEW、ESTABLISHED兩類:(1) ECHO請(qǐng)求(ping,8)和ECHO應(yīng)答(ping,0)。(2) 時(shí)間戳請(qǐng)求(13)和應(yīng)答(14)。(3) 信息請(qǐng)求(15)和應(yīng)答(16)。(4) 地址掩碼請(qǐng)求(17)和應(yīng)答(18)。這些ICMP分組類型中,請(qǐng)求分組屬于NEW,應(yīng)答分組屬于ESTABLISHED。而其它類型的ICMP分組不基于請(qǐng)求/應(yīng)答方式,一律被歸入RELATED。舉例如下:iptables A OUTPUT p icmp m state state NEW,ESTABLISHED,RELATED j ACCEPTiptables A INPUT p icmp m state state ESTABLISHED,RELATED j ACCEPT規(guī)則進(jìn)行如下的過(guò)濾:一個(gè)ICMP echo請(qǐng)求是一個(gè)NEW連接。因此,允許ICMP echo請(qǐng)求通過(guò)OUTPUT鏈。當(dāng)對(duì)應(yīng)的應(yīng)答返回,此時(shí)連接的狀態(tài)是ESTABLISED,因此允許通過(guò)INPUT鏈。而INPUT鏈沒(méi)有NEW狀態(tài),因此不允許echo請(qǐng)求通過(guò)INPUT鏈。也就是說(shuō),這兩條規(guī)則允許內(nèi)部主機(jī)ping外部主機(jī),而不允許外部主機(jī)ping內(nèi)部主機(jī)。一個(gè)重定向ICMP(5)分組不是基于請(qǐng)求/應(yīng)答方式的,因此屬于RELATED。INPUT和OUTPUT鏈都允許RELATED狀態(tài)的連接,因此重定向(5)分組可以通過(guò)INPUT和OUTPUT鏈。 FTP協(xié)議的狀態(tài)檢測(cè)上面,我們比較詳細(xì)地介紹了iptables的態(tài)檢測(cè)機(jī)制?,F(xiàn)在,我們以FTP狀態(tài)檢測(cè)為例介紹如何使用iptables進(jìn)行連接狀態(tài)檢測(cè)。首先,我們需要加載ip_conntrack_ftp模塊。使用如下規(guī)則就可以允許建立FTP控制連接(這里沒(méi)有考慮IMCP問(wèn)題):iptables A INPUT p tcp –sport 21 m state state ESTABLISHED j ACCEPTiptables A OUTPUT p tcp –dport 21 m state state NEW,ESTABLISHED j ACCEPT除了控制連接之外,F(xiàn)TP協(xié)議還需要一個(gè)數(shù)據(jù)通道,不過(guò),數(shù)據(jù)連接可以通過(guò)主動(dòng)和被動(dòng)兩種模式建立。(1) 主動(dòng)模式在主動(dòng)模式下,客戶程序在控制通道上,使用PORT命令告訴FTP服務(wù)器自己這邊的數(shù)據(jù)傳輸端口,然后FTP從20端口向這個(gè)端口發(fā)起一個(gè)連接。連接建立后,服務(wù)器端和客戶端就可以使用這個(gè)連接傳輸數(shù)據(jù)了,例如:傳送的文件、ls等命令的結(jié)果等。因此,在主動(dòng)模式下FTP數(shù)據(jù)傳輸通道是反向建立的,它從FTP服務(wù)器端向客戶端發(fā)起。在主動(dòng)模式下,客戶端使用的數(shù)據(jù)傳輸端口是不固定的,因此我們需要在規(guī)則中使用端口范圍。由于客戶端使用的端口都是大于1024的,這并不會(huì)降低系統(tǒng)的安全性。在iptables中,有一個(gè)專門跟蹤FTP狀態(tài)的模塊ip_conntrack_ftp。這個(gè)模塊能夠識(shí)別出PORT命令,并從中提取端口號(hào)。這樣,F(xiàn)TP數(shù)據(jù)傳輸連接就被歸入RELATED狀態(tài),它和向外的FTP控制連接相關(guān),因此我們不需要在INPUT鏈中使用NEW狀態(tài)。下面的規(guī)則可以實(shí)現(xiàn)我們的意圖:iptables A INPUTp tcp –sport 20 m state state ESTABLISHED,RELATED j ACCEPTiptables A OUTPUT p tcp –dport 20 m state state ESTABLISHED j ACCEPT(2) 被動(dòng)模式和主動(dòng)模式相反,在被動(dòng)模式下,指定連接端口的PORT命令是服務(wù)器端發(fā)出的。FTP服務(wù)器通過(guò)PORT命令告訴客戶端自己使用的FTP數(shù)據(jù)傳輸端口,然后等待客戶端建立數(shù)據(jù)傳輸連接。在被動(dòng)模式下,建立數(shù)據(jù)傳輸連接的方向和建立控制連接的方向是相同的。因此,被動(dòng)模式具有比主動(dòng)模式更好的安全性。由于ip_conntrack_ftp模塊能夠從PORT命令提取端口,因此我們?cè)贠UTPUT鏈中也不必使用NEW狀態(tài),下面的規(guī)則可以實(shí)現(xiàn)對(duì)被動(dòng)模式下的FTP狀態(tài)檢測(cè):iptables A INPUT p tcp –sport 1024: dport 1024: m state state ESTABLISHED j ACCEPTiptables A OUTPUT p tcp –sport 1024: dport 1024 m state state ESTABLISHED,RELATED j ACCEPT綜合以上的分析,我們可以得到FTP連接的狀態(tài)檢測(cè)規(guī)則,對(duì)于主動(dòng)模式的FTP,需要下面的iptables規(guī)則:iptables A INPUT p tcp sport 21 m state state ESTABLESED j ACCEPTiptables A OUTPUT p tcp dport 21 m state state NEW,ESTABLISED j ACCEPTiptables A INPUT p tcp sport 20 m state state ESTABLISED,RELATED j ACCEPTiptables A OUTPUT p tcp dport 20 m state state ESTABLISED j ACCEPT對(duì)于被動(dòng)模式的FTP連接,需要使用如下iptables規(guī)則iptables A INPUT p tcp sport 21 m state state ESTABLESED j ACCEPTiptables A OUTPUT p tcp dport 21 m state state NEW,ESTABLISED j ACCEPTiptables A INPUT p tcp sport 1024: dport 1024: m state state ESTABLISHED j ACCEPTiptables A OUTPUT p tcp sport 1024: dport 1024: m state state ESTABLISHED,RELATED j ACCEPT21 /