linux下使用tcpdump抓包分析tcp的三次握手


linux下使用tcpdump抓包分析tcp的三次握手

首先貼上tcp 三次握手的原理圖
linux下使用tcpdump抓包分析tcp的三次握手
服務器開啟ftp服務並執行tcpdump抓包
服務器:192.168.3.14 ftp服務
客戶端:192.168.3.100
服務器執行以下命令,客戶端訪問服務器ftp://192.168.3.14
tcpdump -S tcp port 21 -nn -i eth0 -c 20 > ftp.txt
-S打印TCP 數據包的順序號時, 使用絕對的順序號, 而不是相對的順序號
監控ftp的命令端口21
-c 只抓20個數據包
linux下使用tcpdump抓包分析tcp的三次握手
linux下使用tcpdump抓包分析tcp的三次握手
192.168.3.100客戶端使用隨機端口訪問服務器21端口,seq=242796690(syn=j)
服務器192.168.3.14回應客戶端192.168.3.100
seq 1102963514, ack 242796691(ack=j+1,seq=k)
客戶端192.168.3.100確認接受到服務器192.168.3.14的信息
ack 1102963515(ack=k+1)
此時服務器與客戶端進入ESTABLISHED狀態,開始進行數據傳送。。

利用tcpdump命令統計http的GET和POST請求

1、搭建的知識庫服務器, 需要統計來訪者都是哪些人,因為系統不是自己開發的,看不到訪問日志。所以考慮從系統層面抓取訪問流量來實現。

2、通過tcpdump抓取的數據包,在wireshark中打開發現,http的請求GET動作,或者POST動作,加HOST拼接成一個url可以打開,抓取到的頁面類似於這種:http://192.168.102.238:8090/pages/viewpage.action?pageId=491717

3、由於我們內部工作人員的IP地址基本固定,所以通過IP和訪問的域名來判斷是否是正常的打開頁面請求,來記錄一次來訪者。

4、tcpdump命令使用如下:

[root@conence ~]# tcpdump -i em1 tcp[20:2]=0x4745 or tcp[20:2]=0x504f -c 10
| awk {'print $3'} | uniq | sort -n //偏移抓包tcp[20:2]=0x4745 為HTTP-GET 請求,0x504f為HTTP-POST請求,利用該條命令抓取HTTP的GET和POST請求。

5、簡單寫一個抓包的腳本,放到crontab中每秒執行

[root@coence test]# cat sic.sh
#!/bin/bash
i=1
while (($i<=5))
do
DATE0=`date +%Y%m%d%H%M`
/usr/sbin/tcpdump -i em1 tcp[20:2]=0x4745 or tcp[20:2]=0x504f -c 20 | awk {'print $3'}| uniq | sort -n |awk -F '.' '{print $1.$2.$3.$4}' | uniq >> /tmp/log/src.log_${DATE0}

*//該命令用於抓取HTTP GET/POST 請求,提取源IP,然后利用awk排序並輸出,其中uniq 去除重復項,awk -F XX ,提取一個IP地址的其中一個字段 print $1.$2 目的是拆分同一個字符串(比如192.168.1.1.55611這個在awk來看是一個字符,如果需要輸出其中的55611 則需要通過-F 加 "." 來拆分,然后使用 print $5 單獨輸出其中的一個字段),其中/usr/sbin/tcpdump 為絕對路徑,如果需要把這個腳本加到crontab中來執行,就需要填寫絕對路徑*

sleep 10s
*//等待10s,抓包數到20個,才能確認是一次正常的頁面請求,這個通過抓包測試過,打開一個頁面在15-20個數據包左右*
kill `ps aux | grep tcpdump | grep -v grep | awk '{print $2}'`
//結束當前的抓包
let "i++"
done
exit

6、保存的日志還需要導出之后,通過execl來轉換

7、簡單的統計效果

 
分類:  linux常用命令
 
 

 

1.監聽eth0網卡HTTP 80端口的request和response
tcpdump -i eth0 -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
2.監聽eth0網卡HTTP 80端口的request(不包括response),指定來源域名"example.com",也可以指定IP"192.168.1.107"
tcpdump -i eth0 -A -s 0 'src example.com and tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
3.監聽本機發送至本機的HTTP 80端口的request和response
tcpdump -i lo -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
4.監聽eth0網卡HTTP 80端口的request和response,結果另存為cap文件
tcpdump -i eth0 -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' -w ./dump.cap
注1:如果報錯"tcpdump: Bluetooth link-layer type filtering not implemented",是因為默認網卡不是ech0,需要用-i參數指定
注2:通過ifconfig命令查看網卡

$ tcpdump -i eth0 -nnA tcp and src host 192.168.1.231 and dst 211.138.24.191|grep 關鍵字過濾

tcpdump

tcpdump是linux系統自帶的抓包工具,主要通過命令行的方式,比較適合在線上服務器進行抓包操作,如果是windows或者ubuntu完全可 以選擇一些圖形化的工具,ubuntu比較推薦用wireshark,安裝方式很簡單sudo apt一下即可。

命令行格式:
tcpdump [ -adeflnNOpqStvx ] [ -c 數量 ] [ -F 文件名 ][ -i 網絡接口 ] [ -r 文件名] [ -s snaplen ][ -T 類型 ] [ -w 文件名 ] [表達式 ]

常用的參數:
-l    使標准輸出變為緩沖行形式;
-n    不把網絡地址轉換成名字;

-c    在收到指定的包的數目后,tcpdump就會停止;
-i    指定監聽的網絡接口;(如果沒有指定可能在默認網卡上監聽,需要指定綁定了特定IP的網卡)
-w    直接將包寫入文件中,並不分析和打印出來;
-s 指定記錄package的大小,常見 -s 0 ,代表最大值65535,一半linux傳輸最小單元MTU為1500,足夠了
-X 直接輸出package data數據,默認不設置,只能通過-w指定文件進行輸出

常用表達式:

關於類型的關鍵字,主要包括host,net,port
傳輸方向的關鍵字,主要包括src , dst ,dst or src, dst and src
協議的關鍵字,主要包括fddi,ip ,arp,rarp,tcp,udp等類型
邏輯運算,取非運算是 'not ' '! ', 與運算是'and','&&';或運算 是'or' ,'||'
其他重要的關鍵字如下:gateway, broadcast,less,greater

實際例子:

1. http數據包抓取 (直接在終端輸出package data)

tcpdump tcp port 80 -n -X -s 0 指定80端口進行輸出

2. 抓取http包數據指定文件進行輸出package

tcpdump tcp port 80 -n -s 0 -w /tmp/tcp.cap

對應的/tmp/tcp.cap基本靠肉眼已經能看一下信息,比如http Header , content信息等

3. 結合管道流

tcpdump tcp port 80 -n -s 0 -X -l | grep xxxx

這樣可以實時對數據包進行字符串匹配過濾

4. mod_proxy反向代理抓包

線上服務器apache+jetty,通過apache mod_proxy進行一個反向代理,80 apache端口, 7001 jetty端口

apache端口數據抓包: tcpdump tcp port 80 -n -s 0 -X -i eth0   注意:指定eth0網絡接口
jetty端口數據抓包: tcpdump tcp port 7001 -n -s 0 -X -i lo 注意:指定Loopback網絡接口

5. 只監控特定的ip主機
tcpdump tcp host 10.16.2.85 and port 2100 -s 0 -X 
需要使用tcp表達式的組合,這里是host指示只監聽該ip

小技巧:

1. 可結合tcpdump(命令) + wireshark(圖形化)

操作: 

在服務器上進行tcpdump -w /tmp/tcp.cap 指定輸出外部文件
scp /tmp/tcp.cap 拷貝文件到你本地
wireshark &  啟動wireshark
通過 File -> Open  打開拷貝下來的文件,這樣就可以利用進行數據包分析了
剩下來的事就非常方便了

tcpdump -XvvennSs 0 -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854

0x4745 為"GET"前兩個字母"GE"

0x4854 為"HTTP"前兩個字母"HT"

說明: 通常情況下:一個正常的TCP連接,都會有三個階段:1、TCP三次握手;2、數據傳送;3、TCP四次揮手

里面的幾個概念:

  • SYN: (同步序列編號,Synchronize Sequence Numbers)
  • ACK: (確認編號,Acknowledgement Number)
  • FIN: (結束標志,FINish)

TCP三次握手(創建 OPEN)

  • 客戶端發起一個和服務創建TCP鏈接的請求,這里是SYN(J)
  • 服務端接受到客戶端的創建請求后,返回兩個信息: SYN(K) + ACK(J+1)
  • 客戶端在接受到服務端的ACK信息校驗成功后(J與J+1),返回一個信息:ACK(K+1)
  • 服務端這時接受到客戶端的ACK信息校驗成功后(K與K+1),不再返回信息,后面進入數據通訊階段

數據通訊

  • 客戶端/服務端 read/write數據包

TCP四次握手(關閉 finish)

  • 客戶端發起關閉請求,發送一個信息:FIN(M)
  • 服務端接受到信息后,首先返回ACK(M+1),表明自己已經收到消息。
  • 服務端在准備好關閉之前,最后發送給客戶端一個 FIN(N)消息,詢問客戶端是否准備好關閉了
  • 客戶端接受到服務端發送的消息后,返回一個確認信息: ACK(N+1)
  • 最后,服務端和客戶端在雙方都得到確認時,各自關閉或者回收對應的TCP鏈接。

詳細的狀態說明(以及linux相關參數調整)

  1. SYN_SEND
    • 客戶端嘗試鏈接服務端,通過open方法。也就是TCP三次握手中的第1步之后,注意是客戶端狀態
    • sysctl -w net.ipv4.tcp_syn_retries = 2 ,做為客戶端可以設置SYN包的重試次數,默認5次(大約180s)引用校長的話:僅僅重試2次,現代網絡夠了
  2. SYN_RECEIVED
    • 服務接受創建請求的SYN后,也就是TCP三次握手中的第2步,發送ACK數據包之前
    • 注意是服務端狀態,一般15個左右正常,如果很大,懷疑遭受SYN_FLOOD攻擊
    • sysctl -w net.ipv4.tcp_max_syn_backlog=4096 , 設置該狀態的等待隊列數,默認1024,調大后可適當防止syn-flood,可參見man 7 tcp
    • sysctl -w net.ipv4.tcp_syncookies=1 , 打開syncookie,在syn backlog隊列不足的時候,提供一種機制臨時將syn鏈接換出
    • sysctl -w net.ipv4.tcp_synack_retries = 2 ,做為服務端返回ACK包的重試次數,默認5次(大約180s)引用校長的話:僅僅重試2次,現代網絡夠了
  3. ESTABLISHED
    • 客戶端接受到服務端的ACK包后的狀態,服務端在發出ACK在一定時間后即為ESTABLISHED
    • sysctl -w net.ipv4.tcp_keepalive_time = 1200 ,默認為7200秒(2小時),系統針對空閑鏈接會進行心跳檢查,如果超過net.ipv4.tcp_keepalive_probes * net.ipv4.tcp_keepalive_intvl = 默認11分,終止對應的tcp鏈接,可適當調整心跳檢查頻率
    • 目前線上的監控 waring:600 , critial : 800
  4. FIN_WAIT1
    • 主動關閉的一方,在發出FIN請求之后,也就是在TCP四次握手的第1步
  5. CLOSE_WAIT
    • 被動關閉的一方,在接受到客戶端的FIN后,也就是在TCP四次握手的第2步
  6. FIN_WAIT2
    • 主動關閉的一方,在接受到被動關閉一方的ACK后,也就是TCP四次握手的第2步
    • sysctl -w net.ipv4.tcp_fin_timeout=30, 可以設定被動關閉方返回FIN后的超時時間,有效回收鏈接,避免syn-flood.
  7. LASK_ACK
    • 被動關閉的一方,在發送ACK后一段時間后(確保客戶端已收到),再發起一個FIN請求。也就是TCP四次握手的第3步
  8. TIME_WAIT
    • 主動關閉的一方,在收到被動關閉的FIN包后,發送ACK。也就是TCP四次握手的第4步
    • sysctl -w net.ipv4.tcp_tw_recycle = 1 , 打開快速回收TIME_WAIT,Enabling this option is not recommended since this causes problems when working with NAT (Network Address Translation)
    • sysctl -w net.ipv4.tcp_tw_reuse =1, 快速回收並重用TIME_WAIT的鏈接, 貌似和tw_recycle有沖突,不能重用就回收?
    • net.ipv4.tcp_max_tw_buckets: 處於time_wait狀態的最多鏈接數,默認為180000.

相關說明

  • 主動關閉方在接收到被動關閉方的FIN請求后,發送成功給對方一個ACK后,將自己的狀態由FIN_WAIT2修改為TIME_WAIT,而必須 再等2倍的MSL(Maximum Segment Lifetime,MSL是一個數據報在internetwork中能存在的時間)時間之后雙方才能把狀態 都改為CLOSED以關閉連接。目前RHEL里保持TIME_WAIT狀態的時間為60秒
  • keepAlive策略可以有效的避免進行三次握手和四次關閉的動作

其他網絡重要參數

net.ipv4.tcp_rmem 參數

默認值: min=4096 default=87380 max=4194304

net.ipv4.tcp_wmem 參數

默認值: min=4096 default=16384 max=4194304

單獨總結tcpdump抓包的常用命令

主要語法
過濾主機/IP:
tcpdump -i eth1 host 172.16.7.206
抓取所有經過網卡1,目的IP為172.16.7.206的網絡數據

過濾端口:
tcpdump -i eth1 dst port 1234
抓取所有經過網卡1,目的端口為1234的網絡數據

過濾特定協議:
tcpdump -i eth1 udp
抓取所有經過網卡1,協議類型為UDP的網絡數據

抓取本地環路數據包
tcpdump -i lo udp 抓取UDP數據
tcpdump -i lo udp port 1234 抓取端口1234的UDP數據
tcpdump -i lo port 1234 抓取端口1234的數據

特定協議特定端口:
tcpdump udp port 1234
抓取所有經過1234端口的UDP網絡數據

抓取特定類型的數據包:
tcpdump -i eth1 ‘tcp[tcpflags] = tcp-syn’
抓取所有經過網卡1的SYN類型數據包
tcpdump -i eth1 udp dst port 53
抓取經過網卡1的所有DNS數據包(默認端口)

邏輯語句過濾:
tcpdump -i eth1 ‘((tcp) and ((dst net 172.16) and (not dst host 192.168.1.200)))’
抓取所有經過網卡1,目的網絡是172.16,但目的主機不是192.168.1.200的TCP數據

抓包存取:
tcpdump -i eth1 host 172.16.7.206 and port 80 -w /tmp/xxx.cap
抓取所有經過網卡1,目的主機為172.16.7.206的端口80的網絡數據並存儲


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM