tcpdump統計http請求並導出URL文本

tcpdump統計http請求並導出URL文本

tcpdump

  1. tcpdump是一個用於截取網路分組,並輸出分組內容的工具。憑藉強大的功能和靈活的截取策略,使其成為類UNIX系統下用於網路分析和問題排查的首選工具

  2. tcpdump 支援針對網路層、協議、主機、網路或埠的過濾,並提供and、or、not等邏輯語句來幫助你去掉無用的資訊

  3. 語法

    tcpdump [ -DenNqvX ] [ -c count ] [ -F file ] [ -i interface ] [ -r file ]
            [ -s snaplen ] [ -w file ] [ expression ]
    

    img

strings

  1. strings命令 在對象文件或二進位文件中查找可列印的字元串。字元串是4個或更多可列印字元的任意序列,以換行符或空字元結束。 strings命令對識別隨機對象文件很有用。

  2. 語法

    strings [ -a ] [ - ] [ -o ] [ -t Format ] [ -n Number ] [ -Number ]  [file ... ]
    
  3. 選項

    -a --all:掃描整個文件而不是只掃描目標文件初始化和裝載段
    -f –print-file-name:在顯示字元串前先顯示文件名
    -n –bytes=[number]:找到並且輸出所有NUL終止符序列
    - :設置顯示的最少的字元數,默認是4個字元
    -t --radix={o,d,x} :輸出字元的位置,基於八進位,十進位或者十六進位
    -o :類似--radix=o
    -T --target= :指定二進位文件格式
    -e --encoding={s,S,b,l,B,L} :選擇字元大小和排列順序:s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit
    @ :讀取中選項
    

awk

  1. awk是linux中處理文本的強大工具,或者說是一種專門處理字元串的語言,它有自己的編碼格式。awk的強大之處還在於能生成強大的格式化報告。

  2. 語法

    img

  3. 常用命令

    1. -F參數:指定分隔符,可指定一個或多個

    2. print; : 列印命令, 後面可字元串的拼接

    3. 數據欄位變數

      • $0表示整行文本
      • $1表示文本行中第一個數據欄位
      • $2表示文本行中第二個數據欄位
      • $n表示文本行中第n個數據欄位
    4. getline; : 常用方法是讀取下一行數據 , 也有其他用法

導出方法

  1. tcpdump抓取數據包

    tcpdump -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x504f -w /tmp/tcp.cap -s 512 2>&1
    
    • 按Ctrl+C即可結束抓取 , 也可直接設置定時結束 , 如下定時30s後結束抓取:

      tcpdump -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x504f -w /tmp/tcp.cap -s 512 2>&1 &sleep 30
      
    • 命令解釋

      1. -i 即interface:指定tcpdump需要監聽的網卡。默認會抓取第一個網卡 . eth0即指定的網卡名稱 , 可通過ifconfig命令獲取網卡資訊
      2. tcp[20:2]=0x4745 or tcp[20:2]=0x504f : 過濾表達式 , 意思是過濾數據包中tcp數據段的21-22位元組字元為GET或者POST的數據包 , 即過濾HTTP GET/POST請求的數據包
      3. -w /tmp/tcp.cap : 指定tcpdump將抓包數據輸出到文件 /tmp/tcp.cap 中而不是標準輸出
      4. -s 512 即-s len:設置tcpdump的數據包抓取長度為512,如果不設置默認將會是65535位元組。對於要抓取的數據包較大時,長度設置不夠可能會產生包截斷
      5. 2>&1 : 將標準錯誤輸出重定向到標準輸出 , Linux中1為標準輸出(stdout) , 2為標準錯誤輸出(stderr)
      6. &sleep 30 : 命令保持30s
  2. 通過strings命令來找出GET/POST的url以及Host

    strings /tmp/tcp.cap | grep -E "GET /|POST /|Host:" | grep --no-group-separator -B 1 -E "Host:" | grep --no-group-separator -A 1 -E "GET /|POST /" | awk '{url=$2;getline;host=$2;printf ("%s\n",host""url)}' > /tmp/url.txt
    
    • 命令解釋

      1. strings /tmp/tcp.cap : 將tcpdump生成的文件指定為查詢字元串的源文件

      2. grep -E "GET /|POST /|Host:" | grep --no-group-separator -B 1 -E "Host:" | grep --no-group-separator -A 1 -E "GET /|POST /" :

        1. grep -E "GET /|POST /|Host:" : 查找以"GET /POST /Host:開頭的字元串

        2. grep --no-group-separator -B 1 -E "Host:" | grep --no-group-separator -A 1 -E "GET /|POST /": 保證查詢的字元串標準輸出均為一行Host:緊接著一行GET /POST /

          • 此處將多出的幾行/biling登錄的url都給去除了 , 做到一一對應
          • --no-group-separator : 當使用’-A’, ‘-B’ or ‘-C’時,不輸出任何組分隔符,而是將不同組相鄰輸出
        3. 輸出樣式示例如下

          image-20211231165459096

      3. awk '{url=$2;getline;host=$2;printf ("%s\n",host""url)}' > /tmp/url.txt :

        1. url=$2;先將上述得到的標準輸出文本的第一行Host: 字元串的第二段字元串賦值給url(以空格分段) , 如: tgateway.changyou.com
        2. getline;讀取下一行GET /POST /的內容 , ;host=$2;再將該行的第二段字元串賦值給host , 如:/gateway/cyou/order/query.json?page_no=1&page_size=10&status=&user_id=512001187843600
        3. printf ("%s\n",host""url)}' > /tmp/url.txt : 將得到的兩個變數以host""url的格式列印至tmp/url.txt中(""為空字元串 , 主要用於表達式中分割兩個變數)

其他可實現的需求

  1. 計算伺服器QPS

    wc -l /tmp/url.txt | cut -d' ' -f 1得到一個數字 , 該數字除以統計的秒數即是QPS

  2. 排除靜態文件統計前10訪問url:

    grep -v -i -E "\.(gif|png|jpg|jpeg|ico|js|swf|css)" /tmp/url.txt | sort | uniq -c | sort -nr | head -n 10

參考資料

  1. tcpdump: //www.jianshu.com/p/d9162722f189
  2. strings: //ipcmen.com/strings
  3. awk: //blog.csdn.net/u010502101/article/details/81839519
  4. grep: //www.cnblogs.com/pangbing/p/6535562.html
  5. 導出文章: //linux.it.net.cn/e/shell/2014/0706/2390.html