iptables模擬網絡連接問題並分析

以下說明了日常開發中常見的網絡問題的模擬方法、異常表現,及定位問題的方法,並提供了Linux網絡請求命令nc、curl,防火牆命令iptables的使用說明。

1.  前言

相關內容如下:

Windows抓包與網絡分析工具總結:https://blog.csdn.net/a82514921/article/details/104609924

Linux抓包與網絡分析工具總結:https://blog.csdn.net/a82514921/article/details/104616502

Java程序網絡連接分析方法總結:https://blog.csdn.net/a82514921/article/details/104616519

iptables模擬網絡連接問題並分析:https://blog.csdn.net/a82514921/article/details/104616548

2.  問題分類

在開發過程中,經常發生的網絡連接失敗包括:連接拒絕、連接超時、讀返回超時等,以下主要分析這些比較常見的異常。

3.  Linux網絡請求與防火牆命令

以下使用Linux版本爲2.6.32-642.6.2.el6.x86_64。

3.1  nc命令

man nc的說明爲“nc(或netcat)應用程序可對TCP或UDP進行處理,可以打開TCP連接,發送UDP數據包,監聽任意TCP和UDP端口,進行端口掃描,以及處理IPv4和IPv6”。

nc命令可能沒有預裝,需要進行安裝。

以下對下文需要使用的nc命令進行說明(使用代理等其他複雜功能未涉及)。

3.1.1  nc選項

l  -k

-k選項只能與-l選項結合使用,使nc的當前連接完成後,保持監聽,等待後續的連接。

當使用-l選項但不使用-k選項時,nc命令在接收到一次連接後會自動退出;當使用-l選項且使用-k選項時,nc命令在接收到連接後不會自動退出,會繼續處理連接。

l  -l

使nc監聽並處理接入的連接,而不是向遠程主機發起連接。

該選項無法與“-p”“-s”“-z”選項同時使用,-w選項指定的超時時間會被忽略。

l  -n

不對任何地址、主機名或端口進行DNS或服務查找。

當指定-n選項後,會導致無法使用域名或主機名,localhost也無法使用。

l  -u

使用UDP替代默認的TCP協議。

l  -v

使nc打印更詳細的輸出。

當nc連接遠程主機失敗時,默認無提示;當指定-v選項後,會打印錯誤信息。

當nc監聽端口時,連接成功後默認不會顯示客戶端連接信息;指定-v選項後,會顯示客戶端連接信息。

l  -w timeout

指定超時時間,如果連接和標準輸入的空閒時間超過超時時間,連接會被靜默關閉。

-w選項對-l選項沒有效果,即無論是否使用-w選項,nc都會永遠監聽等待連接。

超時時間默認不存在。

l  -z

指定nc只是掃描監聽,不向其發送數據。

使用nc連接遠程主機成功時,當指定-z選項時,nc會自動退出,並顯示連接成功的信息。

nc連接成功時,若不指定-z選項,nc不會自動退出,可在標準輸入輸入數據,回車後會發送給服務器;若服務器使用nc -l監聽,會顯示客戶端發送的數據,在服務器的nc標準輸入輸入數據並回車後,在客戶端的nc也會顯示數據。

l  port[s]

使用nc連接遠程主機時,可以只指定一個端口,也可指定某個範圍的端口,當指定端口範圍時,格式爲“nn-mm”,如“80-90”,nc會對每個端口進行掃描,並輸出結果。

3.1.2  nc使用示例

執行“nc -l 8080”,使nc監聽8080端口,當有連接建立成功後,nc會自動退出。若指定了-v選項,會顯示客戶端連接信息,如“Connection from [客戶端IP] port 8080 [tcp/webcache] accepted”。

執行“nc -l 8080 -k”,使nc監聽8080端口,當有連接建立成功後,nc不會自動退出,會繼續監聽等待連接,且會顯示客戶端發送的數據。

執行“nc localhost 8080”,會連接本機的8080端口。若連接成功,可以在標準輸入輸入數據,回車後發送給服務器;若連接失敗(端口未監聽),默認自動退出且無輸出,若指定了-v選項,會自動退出並提示“nc: connect to localhost port 8080 (tcp) failed: Connection refused”。

執行“nc localhost 8080 -z”,會連接本機的8080端口。若連接成功,會自動退出並顯示“Connection to localhost 8080 port [tcp/webcache] succeeded!”;若連接失敗(端口未監聽),默認自動退出且無輸出,若指定了-v選項,會自動退出並提示“nc: connect to localhost port 8080 (tcp) failed: Connection refused”。

3.2  curl命令

man curl的說明爲“curl是用於從服務器獲取或向服務器傳輸數據的工具,支持的協議包括HTTP、HTTPS、FTP、FTPS、SCP、SFTP、TFTP、DICT、TELNET、LDAP或文件。該命令被設計爲不需要用戶交互。curl提供了大量有用的技巧,如代理支持,用戶身份驗證,FTP上傳,HTTP POST,SSL連接,Cookies,文件傳輸及恢復等”。

以下對下文需要使用的curl命令進行說明(指定請求方法、請求數據、HTTP頭,發送HTTPS請求,使用代理,keey-alive配置,使用其他協議等其他複雜功能未涉及)。

3.2.1  curl選項

curl命令的使用方式爲“curl [options] [URL...]”。

l  --connect-timeout <seconds>

設置連接服務器時的超時時間秒數,只限制連接階段的超時時間,當curl已完成連接後,該選項不再生效。

l  -m/--max-time <seconds>

設置整個操作的超時時間秒數。

3.2.2  curl示例

執行“curl http://127.0.0.1:12345 --connect-timeout 2”,訪問http://127.0.0.1:12345,連接超時時間設置爲2秒。當連接超時時,提示爲“curl: (28) connect() timed out!”。

執行“curl http://127.0.0.1:12345 -m 2”,訪問http://127.0.0.1:12345,操作總超時時間設置爲2秒。當連接成功但訪問請求超時時,提示爲“curl: (28) Operation timed out after 2000 milliseconds with 0 bytes received”。

3.3  iptables命令

man iptables的說明爲“用於IPv4包過濾及NAT的管理工具。用於在Linux內核中設置、維護及檢查IPv4數據包過濾規則表。可以定義幾個不同的表,每個表包含許多內置鏈,也可以包含用戶定義的鏈。每個鏈都是可以匹配一系列數據包的規則列表。每個規則都指定如何處理匹配的數據包”。

執行iptables需要root權限。

iptables可以作爲軟件防火牆使用,以下對下文需要使用的iptables命令進行說明(其他複雜功能未介紹),使用的iptables版本爲1.4.7。

3.3.1  iptables targets

防火牆規則指定了數據包和目標的處理條件。如果數據包不匹配,則使用規則鏈中的下一個進行檢查;如果數據包匹配,則使用對應的目標進行處理。目標可以爲用戶定義的鏈名稱,也可以特殊值ACCEPT、DROP、QUEUE或RETURN之一。

l  ACCEPT

ACCEPT代表允許數據包通過。

l  DROP

DROP代表丟棄數據包。

3.3.2  iptables targets擴展

iptables還可以使用擴展的target模塊,在標準發佈中包含了很多targets擴展,以下僅對REJECT進行說明。

l  REJECT

REJECT用於在匹配的數據包返回中發送錯誤數據包,REJECT是一個終止target,會終止規則遍歷。REJECT僅能用於INPUT、FORWARD及OUTPUT鏈中,以及僅從這些鏈調用的用戶定義鏈。

“--reject-with type”選項可以控制返回的錯誤數據包的性質,type可爲icmp-net-unreachable、icmp-host-unreach-able、icmp-port-unreachable、icmp-proto-unreachable、icmp-net-prohibited、icmp-host-prohibited或icmp-admin-prohib-ited。默認值爲port-unreachable。

tcp-reset選項僅可用於TCP協議,會發送TCP RST包。

3.3.3  iptables表

“-t, --table table”選項用於指定命令作用的數據包匹配的表。如果內核配置了自動模塊加載,則會嘗試加載該表的相應模塊(如果該表尚不存在)。

iptables中具有以下表:

l  filter

filter是iptables使用的默認的表(如果沒有指定-t選項)。

filter表包含以下的內置的鏈:

內置鏈名

作用

INPUT

對應發往本地套接字的數據包

FORWARD

對應通過本機路由的數據包

OUTPUT

對應本地生成的數據包

l  nat

略。

l  mangle

略。

l  raw

略。

3.3.4  iptables命令

l  -A, --append chain rule-specification

在指定的鏈的末尾附加一條或多條規則。

l  -D, --delete chain rule-specification/-D, --delete chain rulenum

從指定的鏈中刪除一條或多條規則。

l  -I, --insert chain [rulenum] rule-specification

在指定的鏈使用指定的規則編號插入一條或多條規則。若指定的規則編號(rulenum)爲1,則在鏈的頭部插入。當未指定規則編號時,默認使用1。

l  -L, --list [chain]

列出指定的鏈中的全部規則。若未指定鏈,則列出所有鏈中的規則。和iptables的其他命令類似,該命令使用於指定的表(默認爲filter)。

l  -F, --flush [chain]

清空指定的鏈,若未指定鏈,則清空指定表的全部鏈。該命令與逐個刪除全部的規則效果相同。

3.3.5  iptables參數

l  [!] -p, --protocol protocol

指定規則或需要檢查的包對應的協議。可爲tcp、udp、udplite、icmp、esp、ah、sctp或all中的一個,也可以是數值。允許使用/etc/protocols文件中的協議名稱。數字0等同於all,協議all將與所有協議匹配,並作爲該參數的默認值。

“!”可以使參數含義反轉,如“! -p tcp”,代表不是tcp協議則匹配。

“! -p tcp ”會導致--dport等參數無法使用。

l  [!] -s, --source address[/mask][,...]

指定源地址。地址可以是網絡名稱、主機名、網絡IP地址(帶掩碼)或IP地址。規則在被提交給內核前,主機名僅被解析一次。不建議使用遠程查詢(如DNS)對任何名稱進行解析。掩碼可以是網絡掩碼,或通過數字指定網絡掩碼左側的1的數量。--src是當前參數的別名。

“!”可以使參數含義反轉,如“! -s 127.0.0.1”,代表不是“127.0.0.1”的源地址則匹配。

l  [!] -d, --destination address[/mask][,...]

指定目標地址。與-s參數用法類似。--dst是當前參數的別名。

“!”可以使參數含義反轉,如“! -d 127.0.0.1”,代表不是“127.0.0.1”的目標地址則匹配。

l  -j, --jump target

指定規則的target,即當包匹配規則時需要執行什麼操作。target可以是用戶定義的鏈(不是此規則所在的鏈),一個特殊的可以立即決定數據包操作的內置target,或擴展的target。如果規則中省略了此選項(並且未使用-g,跳轉到指定的鏈),則規則對匹配到的包將不會有效果,但規則上的計數器將遞增。

當-j參數不指定target時,不會對匹配的數據包產生影響,可用於觀察滿足規則的包數量與大小。

l  [!] -i, --in-interface name

指定包被接收時通過的接口名稱(只對通過INPUT、FORWARD和PREROUTING鏈的包有效)。當接口名稱以“+”結尾時,則以指定名稱開頭接口會被匹配。當未指定該參數時,所有的接口都會被匹配。

-i參數只能與“-I INPUT”同時使用(都是指定接收數據包的規則),不能與“-I OUTPUT”同時使用。

“!”可以使參數含義反轉,如“! -i eth0”,代表包被接收時通過的接口不是“eth0”則匹配。

l  [!] -o, --out-interface name

指定包被髮送時通過的接口名稱(只對通過INPUT、FORWARD和POSTROUTING鏈的包有效)。當接口名稱以“+”結尾時,則以指定名稱開頭接口會被匹配。當未指定該參數時,所有的接口都會被匹配。

-i參數只能與“-I OUTPUT”同時使用(都是指定發送數據包的規則),不能與“-I INPUT”同時使用。

“!”可以使參數含義反轉,如“! -o eth0”,代表包被髮送時通過的接口不是“eth0”則匹配。

3.3.6  iptables其他選項

l  -v, --verbose

輸出詳細信息。該選項使“-L, --list”命令顯示接口名稱、規則選項(如果存在)和TOS掩碼。數據包和字節計數器也被列出,後綴分別爲“K”“M”或“G”,分別爲1000、1,000,000和1,000,000,000的倍數(-x選項可以改變該輸出格式)。對於附加、插入、刪除和替換操作,該選項會使對應規則的詳細信息被打印。

l  -n, --numeric

使用數字格式的輸出。IP地址與端口號會以數字形式打印,可以避免DNS解析。在默認情況下(未指定當前選項時),iptables會嘗試以主機或、網絡名稱或服務名的形式進行展示。

例如執行“iptables -I INPUT -s localhost”命令添加規則。

執行“iptables -L -v”命令查看規則,可以看到IP地址顯示爲主機名形式。

Chain INPUT (policy ACCEPT 285 packets, 57158 bytes)

 pkts bytes target     prot opt in     out     source               destination        

    0     0            all  --  any    any     localhost            anywhere           

...

執行“iptables -L -v -n”命令查看規則,可以看到IP地址爲數字形式。

Chain INPUT (policy ACCEPT 8195 packets, 11M bytes)

 pkts bytes target     prot opt in     out     source               destination        

    0     0            all  --  *      *       127.0.0.1            0.0.0.0/0           

...

l  -x, --exact

展開數字。顯示數據包與字節計數器的精確的值,而不是顯示四捨五入的K(1000)、M(1000K)或G(1000M)。該選項只能在使用-L命令時使用。

以下爲示例:

執行“iptables -L -v -x”命令,可以看到數字展示爲精確的值。

Chain INPUT (policy ACCEPT 79027 packets, 56436626 bytes)

    pkts      bytes target     prot opt in     out     source               destination        

       0        0            all  --  any    any     localhost            anywhere           

 

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)

    pkts      bytes target     prot opt in     out     source               destination        

 

Chain OUTPUT (policy ACCEPT 55000 packets, 13694656 bytes)

    pkts      bytes target     prot opt in     out     source               destination

執行“iptables -L -v”命令,可以看到數字展示爲以K、M、G爲單位的形式。

Chain INPUT (policy ACCEPT 79027 packets, 56M bytes)

 pkts bytes target     prot opt in     out     source               destination        

    0     0            all  --  any    any     localhost            anywhere           

 

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)

 pkts bytes target     prot opt in     out     source               destination        

 

Chain OUTPUT (policy ACCEPT 55001 packets, 14M bytes)

 pkts bytes target     prot opt in     out     source               destination

l  --line-numbers

當使用-L命令時,可以指定當前選項,可以根據規則在鏈中的位置,在每個規則的開頭顯示行號。

3.3.7  iptables擴展匹配

iptables可以使用擴展的包匹配模塊。

包匹配模塊有兩種加載方式:

一是隱式加載,指定了-p或--protocol選項;

二是指定了-m或--match選項,後續指定匹配模塊名稱。

當使用了包匹配模塊後,可以使用很多額外的命令選項,由指定的模塊決定。

iptables的基礎包中包含了addrtype、ah、cluster、comment、connbytes、connlimit、connmark、conntrack、dccp、dscp、ecn、esp、hashlimit、helper、icmp、iprange、length、limit、mac、mark、multiport、owner、physdev、pkttype、policy、quota、rateest、realm、recent、sctp、set、socket、state、statistic、string、tcp、tcpmss、time、tos、ttl、u32、udp、unclean等模塊。

以上模式的命令大多可以通過“!”使命令含義反轉。

3.3.7.1     tcp擴展

當指定了“-p tcp”或“--protocol tcp”時,可以使用tcp擴展,支持以下選項:

l  [!] --source-port,--sport port[:port]

指定源端口或源端口範圍。可爲服務名稱或端口號,也可以指定端口範圍,格式爲“first:last”。當未指定first端口時,默認使用0;噹噹未指定last端口時,默認使用65535。

示例:“sudo iptables -I INPUT -p tcp --dport 12344:12346”。

l  [!] --destination-port,--dport port[:port]

指定目標端口或源端口範圍。

l  [!] --tcp-flags mask comp

可以匹配TCP數據包的標誌位,略。

[!] --syn

l  可以匹配TCP數據包的標誌位,略。

3.3.8  iptables默認規則

某些版本的Linux系統在安裝後存在默認的iptables規則。

如CentOS 6.9/RedHat 6.5等版本安裝後存在默認iptables規則,僅允許訪問本機的22端口。

3.3.9  iptables使用示例

執行“iptables -L -v”,查看iptables規則,如下所示。pkts與bytes,分別展示匹配規則的包數量,及字節數

Chain INPUT (policy ACCEPT 9451 packets, 3109K bytes)

 pkts bytes target     prot opt in     out     source               destination        

 9438 3109K            tcp  --  any    any     anywhere             anywhere           

 

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)

 pkts bytes target     prot opt in     out     source               destination         

 

Chain OUTPUT (policy ACCEPT 9614 packets, 4601K bytes)

 pkts bytes target     prot opt in     out     source               destination  

 

執行“iptables -I INPUT -p tcp --dport 12345 -i eth0 -j REJECT”,設置對於接收的TCP協議數據包,若目標端口爲12345,且網絡接口爲eth0時則拒絕。

會導致本機可以訪問本機的12345端口,經過eth0網絡接口的其他機器不可訪問本機的12345端口。

 

執行“iptables -I INPUT -p tcp --dport 12345 -i lo -j REJECT”,設置對於接收的TCP協議數據包,若目標端口爲12345,且網絡接口爲迴環接口lo時則拒絕。

會導致本機不可訪問本機的12345端口,經過eth0網絡接口的其他機器可以訪問本機的12345端口。

 

執行“iptables -I OUTPUT -p tcp --sport 12345 -o eth0 -j REJECT”,設置對於發送的TCP協議數據包,若源端口爲12345,且網絡接口爲eth0時則拒絕。

會導致本機可以訪問本機的12345端口,經過eth0網絡接口的其他機器不可訪問本機的12345端口。

 

執行“iptables -I OUTPUT -p tcp --sport 12345 -o lo -j REJECT”,設置對於發送的TCP協議數據包,若源端口爲12345,且網絡接口爲迴環接口lo時則拒絕。

會導致本機不可以訪問本機的12345端口,經過eth0網絡接口的其他機器可訪問本機的12345端口。

 

執行“iptables -I INPUT -p tcp -s 192.168.0.0/16 --dport 12345 -j DROP”,使用掩碼的IP地址,設置對於接收的TCP協議數據包,若源地址爲192.168網段的IP,且目標端口爲12345時則拒絕。

 

執行“iptables -I INPUT -p tcp -s 192.168.0.1 --dport 12345  ! -i eth0 -j ACCEPT”,設置對於接收的TCP協議數據包,若源地址爲192.168.0.1,且目標端口爲12345,且網絡接口不是eth0時則允許。

 

執行“iptables -I OUTPUT ! -p tcp -d 192.168.0.1 -i eth0 -j ACCEPT”,設置對於發送的數據包,如果協議不是TCP,且目標地址爲192.168.0.1,且網絡接口爲eth0時則允許。

 

執行“iptables -I OUTPUT -p tcp ! -s 192.168.0.1 --dport 12345 -i eth0 -j ACCEPT”,設置對於發送的TCP協議數據包,若源地址不是192.168.0.1,且目標端口爲12345,且網絡接口爲eth0時則允許。

3.3.10     ip6tables

對於IPv6的數據包,當需要使用iptables相關功能時,需要使用ip6tables命令。ip6tables是IPv6的包過濾管理工具。

4.  模擬異常

4.1  模擬連接拒絕

4.1.1  模擬方法

4.1.1.1     訪問未監聽的端口

訪問存在的IP的未監聽的端口 ,可以出現連接拒絕異常。

4.1.1.2     使用iptables模擬連接拒絕

4.1.1.2.1  客戶端連接請求被拒絕

假設服務器IP爲192.168.0.1,監聽端口爲12345。在客戶端執行iptables命令設置以下規則,使客戶端連接請求被拒絕,可以出現連接拒絕異常。

iptables -I OUTPUT -p tcp -d 192.168.0.1 --dport 12345 -j REJECT

4.1.1.2.2  服務器處理連接請求被拒絕

假設客戶端IP爲192.168.0.1,服務器監聽端口爲12345。在服務器執行iptables命令設置以下規則,使客戶端連接請求被拒絕,可以出現連接拒絕異常。

iptables -I INPUT -p tcp -s 192.168.0.1 --dport 12345 -j REJECT

4.1.2  模擬結果

模擬連接被拒絕,使用以下命令進行連接,結果如下:

l  telnet

執行“telnet 192.168.0.1 12345”,結果如下:

Trying 192.168.0.1...

telnet: connect to address 192.168.0.1: Connection refused

l  nc

執行“nc -z -v 192.168.0.1 12345”,結果如下:

nc: connect to 192.168.0.1 port 12345 (tcp) failed: Connection refused

l  curl

執行“curl 192.168.0.1:12345”,結果如下:

curl: (7) couldn't connect to host

4.2  模擬連接超時

4.2.1  模擬方法

4.2.1.1     訪問不存在IP的端口

訪問不存在IP的端口 ,可以出現連接超時異常。

4.2.1.2     使用iptables模擬連接超時

4.2.1.2.1  客戶端連接請求被丟棄

假設服務器IP爲192.168.0.1,監聽端口爲12345。在客戶端執行iptables命令設置以下規則,使客戶端連接請求被丟棄,可以出現連接超時異常。

iptables -I OUTPUT -p tcp -d 192.168.0.1 --dport 12345 -j DROP

4.2.1.2.2  服務器處理連接請求被丟棄

假設客戶端IP爲192.168.0.1,服務器監聽端口爲12345。在服務器執行iptables命令設置以下規則,使客戶端連接請求被丟棄,可以出現連接超時異常。

iptables -I INPUT -p tcp -s 192.168.0.1 --dport 12345 -j DROP

4.2.2  模擬結果

模擬連接被拒絕,使用以下命令進行連接,結果如下:

l  telnet

執行“telnet 192.168.0.1 12345”,一直顯示“Trying 192.168.0.1...”。

l  nc

執行“nc -z -w 2 -v 192.168.0.1 12345”,設置連接超時時間爲2秒,結果如下:

nc: connect to 192.168.0.1 port 12345 (tcp) timed out: Operation now in progress

l  curl

執行“curl --connect-timeout 2 192.168.0.1:12345”,設置連接超時時間爲2秒,結果如下:

curl: (28) connect() timed out!

4.3  模擬讀返回超時

4.3.1  模擬方法

4.3.1.1     自定義服務器

自定義Socket服務器,可通過以下方式之一可使客戶端連接後出現讀返回超時異常:

l  只調用bind方法進行監聽,不調用accept方法創建Socket對象;

l  accept方法創建Socket對象,不向客戶端返回數據,且不調用創建的Socket對象的close方法;

l  accept方法創建Socket對象,等待超過客戶端的超時時間後再向其返回數據。

假設自定義服務器的IP爲192.168.0.1,端口爲12345。

4.3.2  模擬結果

l  curl

執行“curl -m 2 192.168.0.1:12345”,設置連接超時時間爲2秒,結果如下:

curl: (28) Operation timed out after 2000 milliseconds with 0 bytes received

5.  應用程序網絡異常現象

5.1  Java程序網絡異常

5.1.1  連接拒絕

使用Java的Socket類連接服務器,若連接被拒絕,異常信息爲“java.net.ConnectException: Connection refused: connect”。

5.1.2  連接超時

使用Java的Socket類連接服務器,若當連接超時,異常信息爲“java.net.SocketTimeoutException: connect timed out”。

5.1.3  讀返回超時

使用Java的Socket類連接服務器,若讀返回超時,異常信息爲“java.net.SocketTimeoutException: Read timed out”。

5.2  HttpClient網絡異常

以下使用HttpClient爲4.3.6。

5.2.1  連接拒絕

使用HttpClient連接服務器,若連接被拒絕,異常信息爲“org.apache.http.conn.HttpHostConnectException: Connect to 192.168.0.1:12345 [/192.168.0.1] failed: Connection refused: connect”。

5.2.2  連接超時

使用HttpClient連接服務器,若連接超時,異常信息爲“org.apache.http.conn.ConnectTimeoutException: Connect to 192.168.0.1:12345 [/192.168.0.1] failed: connect timed out”。

5.2.3  讀返回超時

使用HttpClient連接服務器,若讀返回超時,異常信息爲“java.net.SocketTimeoutException: Read timed out”。

5.3  Jedis訪問Redis服務器失敗

5.3.1  異常模擬方法

通過iptables設置規則,模擬異常場景,可以使應用訪問Redis服務器失敗。

Jedis連接Redis服務器失敗時,可能導致應用初始化失敗,因此可能需要在應用正常啓動後,

5.3.2  異常模擬結果

當Jedis訪問Redis服務器失敗時,異常信息爲“redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool”,Caused by異常信息爲“redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: connect timed out”。

6.  TCP協議說明

6.1  三次握手說明

TCP協議說明見https://tools.ietf.org/html/rfc793

建立連接的三次握手過程的示意圖爲“Basic 3-Way Handshake for Connection Synchronization Figure 7.”,如下所示:

  TCP A                                                TCP B

 

1.  CLOSED                                               LISTEN

 

2.  SYN-SENT    --> <SEQ=100><CTL=SYN>               --> SYN-RECEIVED

 

3.  ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK>  <-- SYN-RECEIVED

 

4.  ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK>       --> ESTABLISHED

 

5.  ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK><DATA> --> ESTABLISHED

6.2  RST的說明

關於RST的說明爲“A control bit (reset), occupying no sequence space, indicating that the receiver should delete the connection without further interaction.”。

RST爲控制位(復位),不佔用序列空間,表示接收方應刪除連接且無需進一步交互。

7.  TCP數據包分析

以下數據包均在客戶端捕獲,客戶端操作系統爲Linux 2.6.32-642.6.2.el6.x86_64,捕獲數據包工具爲tcpdump。

7.1  正常情況下的TCP連接

正常情況下的TCP連接數據包如下所示,與TCP協議說明建立連接的三次握手過程一致。

7.2  TCP連接拒絕

7.2.1  訪問未監聽的端口

當客戶端訪問存在的IP未監聽的端口時,連接被拒絕。

數據包如下所示,可以看到客戶端向服務器發送SYN後,服務器返回了RST,ACK,使客戶端中斷連接,與TCP協議說明的RST標誌作用相符。

7.2.2  客戶端連接請求被拒絕

在客戶端使用iptables設置規則,使客戶端連接請求被拒絕,在客戶端使用tcpdump捕獲數據包,未捕獲到對應數據包。

7.2.3  服務器處理連接請求被拒絕

在服務器設置iptables規則,使其處理連接請求被拒絕,客戶端連接會被拒絕。

數據包如下所示,可以看到客戶端向服務器發送SYN後,客戶端未接收到服務器的返回。

7.3  TCP連接超時

7.3.1  訪問不存在IP的端口

當客戶端訪問不存在的IP的端口時,連接超時(訪問不存在的IP:123.123.123.123)。

數據包如下所示,可以看到客戶端向服務器發送SYN後,未接收到服務器的返回,經過一段時間後進行重發。

7.3.2  客戶端連接請求被丟棄

在客戶端使用iptables設置規則,使客戶端連接請求被丟棄,在客戶端使用tcpdump捕獲數據包,未捕獲到對應數據包。

7.3.3  服務器處理連接請求被丟棄

在服務器設置iptables規則,使其處理連接請求被丟棄,客戶端連接會超時。

數據包如下所示,可以看到客戶端向服務器發送SYN後,未接收到服務器的返回,經過一段時間後進行重發。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章