iptables的基礎知識-iptables中TCP三次握手
iptables的基礎知識-iptables中TCP三次握手:
一個TCP連接是通過三次握手的方式完成的。首先,客戶程序發出一個同步請求(發出一個SYN分組);接著,服務器端回應一個SYN|ACK分組;最后返回一個ACK分組,連接完成,一共需要三個步驟,整個iptables過程如下所示:
- Client Server
- 1 SYN --->
- 2 <--- SYN+ACK
- 3 ACK --->
- <--- ACK
- ACK --->
接下來我們看具體iptables的過程,假設client(192.168.10.7)要訪問server(192.168.10.100,同時啟用iptables)的WEB主頁。
1 client首先發出一個SYN的連線請求(注意ack,rst等的值),源端口是1286,目的端口是80。
2 Server收到著請求后應答一個SYN+ACK,因為是SERVER應答client,所以源端口是80,目的端口是1286。
3 client再答復一個ACK,至此三步握手的過程結束,一個正常的連接建立。
從以上的三步中可以看到,一個正常的tcp連接建立的過程。值得注意的是一個正常的tcp發起的請求,tcp中包頭中SYN位是1,這就意味著如果一個新的包但是SYN卻不置位,這個包肯定有問題。
為了跟蹤一個TCP連接的狀態,我們在SERVER使用了如下命令:
- iptables -A INPUT -p tcp -m state --state NEW,ESTABLISHED -j ACCEPT
- iptables -A OUTPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
接著看在連接建立過程中iptables狀態表的變化:
1> 由于CLIENT和SERVER之前沒有任何連接,CLIENT發送的SYN(此時的TCP狀態是SYN_SENT)請求進入iptables 的INPUT鏈,發現是一個新包,那么此時iptables將此狀態定義為NEW,因為我們的規則允許,這個請求包被接受。
2> server返回一個SYN+ACK的包(此時的TCP狀態是SYN_RECIV),這個包要經過OUTPUT鏈(因為這個包是從本機發出的,目的地址是client),由于之前曾經收到一個包,此時個狀態,已經變成了ESTABLISHED,按照規則,這個包成功發送出去。
3> 接下來client發送一個ACK,同樣由于INPUT中允許,server接受這個包,至此連接完成,在整個過程中狀態從NEW變為ESTABLISHED(此時的TCP也是established)
注意:在第二步的時候,server上TCP的狀態是SYN_RECVD,對于iptables來講,狀態已經是established,但此時的三次握手并沒有完成,實際是半連接(對與TCP來講,必須是三次握手完成以后,狀態才是established)。所以iptables面對SYNFLOOD攻擊,可以通過控制SYN流量結合tc等實現。但是對于SYN攻擊,即便能保護服務器,對于帶寬的消耗也是沒有辦法的,因為攻擊者消耗了你大部分帶寬。具體連接過程中TCP狀態是如何變化可參考看TCP/IP V1等著作(douglas E.comer或者Steven Richard等的經典之作)。
注意iptables狀態機制在用戶空間里的部分不會查看TCP包的標志位(也就是說TCP標志對它而言是透明的)。如果我們想讓NEW狀態的包通過防火墻,就要指定NEW狀態,我們理解的NEW狀態的意思就是指SYN包,可是iptables又不查看這些標志位。這就是問題所在。有些沒有設置SYN或ACK的包,也會被看作NEW狀態的。這樣的包可能會被冗余防火墻用到,但對只有一個防火墻的網絡是很不利的(可能會被攻擊哦)。那我們怎樣才能不受這樣的包的影響呢?可以使用tcp-flags進行檢查。
上一節:iptables中的狀態檢測 下一節:iptables中的ICMP。
【編輯推薦】