記一個TCP通訊問題的排查

 

摘要 前段時間開發銀企互聯接口,與***端通訊的服務通過一段時間就會卡死,形成接口不可用。本文記錄這個問題的解決過程。html

nmap wireshark tcpdump netstat mysql


目錄[-]linux

原由

本文記錄一次與某***端通訊問題的解決過程,介紹幾個比較經常使用(重要)的工具使用方法。企業處理與銀行相關的業務時,銀行通常會在企業部署一個客戶端軟件。企業經過這個客戶端軟件與銀行的網銀系統通訊,然後是銀行的核心繫統,後面的具體過程就不得而知了。
shell

182131_6klv_188847.png

銀行提供的客戶端通常都會提供HTTP和SOCKET兩種協議接口。爲了控制成本,選擇HTTP接口完成了開發,放到測試環境跑了一段,發現一個頻繁使用的查詢接口會報銀行返回空報文的異常,緊接着其餘接口也會報錯,該銀行的全部服務都處於不可用狀態。更要命的是銀行的客戶端處於假死狀態,只有強制殺進程才能重啓。apache

這是比較惱人的,銀行的服務具備不可替代性這個問題不管如何都得解決。僅保留查詢接口用於重現問題,調用間隔從30min縮短到5min, 大約只能持續一天多就掛掉了。諮詢銀行的聯繫人,他們提供的方案很簡單: 換SOCKET方式試試。因而用按照SOCKET方式又實現了一遍,但是依然不行。編程

通訊包分析
api

爲了方便調式問題,直接在Linux上用PHP調用***端的SOCKET服務。利用tcpdump和wireshark分別在linux/winServer上抓包。能夠看到正常通訊與異常通訊的差異。安全

正常時tcpdump和wireshark抓包:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$sudo  tcpdump -i eth0 -nn -s 0 host 10.x.x.17 and port 30010
tcpdump: verbose output suppressed, use -v  or -vv for  full protocol decode
listening on eth0, link-type  EN10MB (Ethernet), capture size 65535 bytes
20:12:02.956784 IP 10.x.x.123.52160 > 10.x.x.17.30010: S 4017966576:4017966576(0) win 5840 <mss 1460,sackOK,timestamp 998567408 0,nop,wscale 7>
20:12:02.957104 IP 10.x.x.17.30010 > 10.x.x.123.52160: S 2297525216:2297525216(0) ack 4017966577 win 65535 <mss 1460,nop,wscale 3,nop,nop,sackOK>
20:12:02.957145 IP 10.x.x.123.52160 > 10.x.x.17.30010: . ack 1 win 46
20:12:02.957469 IP 10.x.x.123.52160 > 10.x.x.17.30010: P 1:309(308) ack 1 win 46
20:12:03.110329 IP 10.x.x.17.30010 > 10.x.x.123.52160: . ack 309 win 46499
20:12:03.876788 IP 10.x.x.17.30010 > 10.x.x.123.52160: P 1:8(7) ack 309 win 46499
20:12:03.876932 IP 10.x.x.123.52160 > 10.x.x.17.30010: . ack 8 win 46
20:12:03.877202 IP 10.x.x.17.30010 > 10.x.x.123.52160: P 8:703(695) ack 309 win 46499
20:12:03.877321 IP 10.x.x.123.52160 > 10.x.x.17.30010: . ack 703 win 57
20:12:03.878559 IP 10.x.x.17.30010 > 10.x.x.123.52160: F 703:703(0) ack 309 win 46499
20:12:03.879075 IP 10.x.x.123.52160 > 10.x.x.17.30010: F 309:309(0) ack 704 win 57
20:12:03.879231 IP 10.x.x.17.30010 > 10.x.x.123.52160: . ack 310 win 46499

220831_yMt4_188847.jpg

***端阻塞時tcpdump和wireshark抓包:

?

1
2
3
4
5
6
7
8
9
10
$sudo  tcpdump -i eth0 -nn -s 0 host 10.x.x.17 and port 30010
tcpdump: verbose output suppressed, use -v  or -vv for  full protocol decode
listening on eth0, link-type  EN10MB (Ethernet), capture size 65535 bytes
20:01:24.054838 IP 10.x.x.123.50587 > 10.x.x.17.30010: S 3343083156:3343083156(0) win 5840 <mss 1460,sackOK,timestamp 998407685 0,nop,wscale 7>
20:01:24.055055 IP 10.x.x.17.30010 > 10.x.x.123.50587: S 2176848168:2176848168(0) ack 3343083157 win 65535 <mss 1460,nop,wscale 3,nop,nop,sackOK>
20:01:24.055122 IP 10.x.x.123.50587 > 10.x.x.17.30010: . ack 1 win 46
20:01:24.055331 IP 10.x.x.123.50587 > 10.x.x.17.30010: P 1:309(308) ack 1 win 46
20:01:24.159265 IP 10.x.x.17.30010 > 10.x.x.123.50587: . ack 309 win 46499
20:05:41.762361 IP 10.x.x.17.30010 > 10.x.x.123.50579: R 1648624200:1648624200(0) ack 3303560693 win 0
20:06:20.521227 IP 10.x.x.17.30010 > 10.x.x.123.50587: R 1:1(0) ack 309 win 0

220900_aDaD_188847.jpg

能夠看到***端出問題時,沒有發送響應包,而超時(時間應該是銀行端控制的,之後再研究socket編程)後會發送RST包。

至此,能夠分析獲得問題出在客戶端上: 沒有響應報文,企業端看到的是超時返回空。客戶端爲何不響應報文,又是什麼致使客戶端從正常到異常呢?由於***端對企業來講就是個黑盒,只能從外圍入手。好在銀行方面後來提供了一個比較有價值的信息: 端口掃描有可能會致使客戶端出現假死現象(...此處省略若干...),看來這是個已知問題。

端口掃描與監控

發現問題後,諮詢對方聯繫人,一直沒有獲得明確的答覆。好在銀行方面提供了一個比較有價值的信息:端口掃描有可能致使客戶端假死(爲何?)。順着這個線索,先摸索一下是否有別的機器對這臺winServer作掃描吧。wireshark上過濾TCP端口30010的通訊包,檢測了2天,問題終於被發現了。的確是有人對這臺機器作掃描,不過理由正當而充分: 例行檢測端口存活性。

下一步就是要重現問題了,這裏用到了一個很是強大的端口掃描工具nmap(Network Mapper), 引用官方的介紹:

Nmap (「Network Mapper」) is an open source tool for network exploration and security auditing. It was designed to rapidly scan large networks, although it works fine against single hosts. Nmap uses raw IP packets in novel ways to determine what hosts are available on the network, what services (application name and version) those hosts are offering, what operating systems (and OS versions) they are running, what type of packet filters/firewalls are in use, and dozens of other characteristics.

主用用在:主機發現,服務和版本探測,操做系統探測等方面,是一款強大的安全審查工具。更多的端口掃描技術請移步nmap相關介紹。一個經常使用的TCP SYN掃描的例子以下:

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$./nmap  -n -T4 10.x.x.123
  
Starting Nmap 6.40 ( http://nmap.org ) at 2014-02-28 18:28 CST
Nmap scan report for  10.x.x.123
Host is up (0.00099s latency).
Not shown: 984 closed ports
PORT     STATE SERVICE
22/tcp    open   ssh
53/tcp    open   domain
80/tcp    open   http
111/tcp   open   rpcbind
139/tcp   open   netbios-ssn
443/tcp   open   https
445/tcp   open   microsoft-ds
3306/tcp  open   mysql
5001/tcp  open   commplex-link
8009/tcp  open   ajp13
8080/tcp  open   http-proxy
8081/tcp  open   blackice-icecap
8088/tcp  open   radan-http
8089/tcp  open   unknown
8888/tcp  open   sun-answerbook
9000/tcp  open   cslistener
  
Nmap done: 1 IP address (1 host up) scanned in  0.14 seconds

nmap的選項能夠參考這裏。回到***端上,利用nmap對指定端口(30010)掃描。爲了對比,先用nmap掃下apache,並用netstat看下端口使用狀況。

?

1
2
3
4
5
6
7
8
9
10
$./nmap  -n -T4 -P0 -sV 10.x.x.123 -p 80
  
Starting Nmap 6.40 ( http://nmap.org ) at 2014-02-28 18:41 CST
Nmap scan report for  10.x.x.123
Host is up (0.00045s latency).
PORT   STATE SERVICE VERSION
80/tcp  open   http    Apache httpd
  
Service detection performed. Please report any incorrect results at http://nmap.org/submit/  .
Nmap done: 1 IP address (1 host up) scanned in  6.33 seconds

?

1
2
3
4
$netstat  -anp | grep  "10.x.x.123"
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 10.x.x.103:44547          10.x.x.123:80             ESTABLISHED 19375/nmap

對客戶端的掃描結果:

?

1
2
3
4
5
6
7
8
9
10
$./nmap  -n -T4 -P0 -sV 10.x.x.17 -p 30010
  
Starting Nmap 6.40 ( http://nmap.org ) at 2014-02-28 18:43 CST
Nmap scan report for  10.x.x.17
Host is up (0.00049s latency).
PORT      STATE SERVICE VERSION
30010/tcp  open   unknown
  
Service detection performed. Please report any incorrect results at http://nmap.org/submit/  .
Nmap done: 1 IP address (1 host up) scanned in  161.48 seconds

?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$netstat  -anp | grep  "30010"
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 10.x.x.103:46322          10.x.x.17:30010           FIN_WAIT2   -  
$netstat  -anp | grep  "30010"
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 10.x.x.103:54353          10.x.x.17:30010           ESTABLISHED 20090/nmap          
tcp        0      0 10.x.x.103:46322          10.x.x.17:30010           TIME_WAIT   -
.......(此處省略若干).........
$netstat  -anp | grep  "30010"
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 10.x.x.103:54414          10.x.x.17:30010           FIN_WAIT2   -                   
tcp        0      0 10.x.x.103:54415          10.x.x.17:30010           FIN_WAIT2   -                   
tcp        0      0 10.x.x.103:54408          10.x.x.17:30010           FIN_WAIT2   -                   
tcp        0      0 10.x.x.103:54400          10.x.x.17:30010           FIN_WAIT2   -                   
tcp        0      0 10.x.x.103:54402          10.x.x.17:30010           FIN_WAIT2   -                   
tcp        0      0 10.x.x.103:54426          10.x.x.17:30010           ESTABLISHED 20090/nmap          
tcp        0      0 10.x.x.103:54427          10.x.x.17:30010           ESTABLISHED 20090/nmap          
tcp        0      0 10.x.x.103:54422          10.x.x.17:30010           FIN_WAIT2   -                   
tcp        0      0 10.x.x.103:54416          10.x.x.17:30010           FIN_WAIT2   -                   
tcp        0      0 10.x.x.103:54417          10.x.x.17:30010           FIN_WAIT2   -                   
tcp        0      0 10.x.x.103:54398          10.x.x.17:30010           FIN_WAIT2   -                   
tcp        0      0 10.x.x.103:54392          10.x.x.17:30010           FIN_WAIT2   -

221049_QMse_188847.jpg

比較可見,***端沒有返回相應的信息,nmap就嘗試新的鏈接去獲取,最後建了一堆鏈接。而與此同時,客戶端開始拒絕正常的接口服務了,並不停地RST,至此問題已經重現,nmap最後也沒有獲得版本信息,超時返回。

本文不打算猜想客戶端實現上的缺陷,那是另一個問題。肯定問題後,下一步就是怎麼防禦了。好在經過Tomcat服務能夠經過本地通訊調用***端接口,只要在winServer上設置本地安全策略,禁止外部IP鏈接到這臺服務器上指定端口(30010)便可。具體設置操做能夠參考這裏的一片文章,在次再也不贅述。

小結

這個問題的解決,先後歷時好幾天,好在銀行接口須要充分測試,不然....。工具不熟練,嚴重影響排查效率是一方面,技術上不夠敏感沒能快速定位問題纔是首因。歸根結底一句話:基礎亟待增強,共勉吧。

相關文章
相關標籤/搜索