簡單談談網絡抓包,特別是thrift 接口


按照慣例先談談最近情況,最近不是剛好跨年嗎?看到很多人都在寫年度總結,所以我也在寫年度總結文章(其實之前我基本沒有寫過的,今年有點感觸,也想記錄一下),結果發現寫起來有點多,之前還想着元旦前發出來,結果元旦過后,今天我也還在寫,而且還寫不完,不過也差不多了,預計明天會發出來。然后最近需求比較多,工作比較忙,同時遇到了一個比較麻煩的需求,就想着記錄一下,先充當一下這周的文章任務😂。

背景

最近,我在公司做這樣的一個事情,整理老舊的api服務,需要統計接口的每個請求的ip和請求參數,找出對應的調用的ip,以便通知業務方修改為新的api服務。其中我們的這個api服務調用有分為thrift調用和http調用,由於之前的舊的服務設計比較簡陋,沒有通過dubbo 等注冊中心調用,也沒有完整的監控(不要問我為什么沒有,我也很無奈😭),導致我想找出調用ip也找不到,日志里面沒有記錄。

具體操作方法

方法一,直接修改業務代碼

剛開始我們是想修改原業務代碼,加上調用ip和請求參數的日志打印的。原本以為不會有什么問題,但是我們准備開始動手改造的時候,發現http協議提供的接口,比較好改造,直接 httpRequest 可以獲取到客戶端ip ,請求參數也很好打印。接着我們打算動手也修改一下thrift 接口的那部分,原本以為都是接口,估計thrift框架也會提供對應的方式獲取(我們使用的原生的apche thrift 框架來提供服務),於是網上找了一下,發現thrift 接口好像並 http 接口那么好改造,網上說需要加個監聽類,監聽請求,類似以下情況:

     /**
	 * 調用RPC服務的時候觸發
	 * 每調用一次方法,就會觸發一次
	 */
	public void processContext(ServerContext serverContext, TTransport inputTransport, TTransport outputTransport)
	{
		/**
		 * 把TTransport對象轉換成TSocket,然后在TSocket里面獲取Socket,就可以拿到客戶端IP  (這里有可能轉化不成功的,inputTransport 不一定為 TSocket 類來的,還有可能為 TFrmef ,這里依賴於thrift 提供服務的方式 )
		 */
		TSocket socket = (TSocket)inputTransport;
		System.out.println(socket.getSocket().getRemoteSocketAddress());
	}

參考:兩種方式獲取Thrift調用的客戶端IP地址
https://blog.csdn.net/mn960mn/article/details/50585278

但是,我們實際操作的時候,建了這個監聽類,起了自己的本地服務,並用單元測試去測試的時候,發現報了以下這樣的一個錯誤。

org.apache.thrift.transport.TFramedTransport cannot be cast to org.apache.thrift.transport.TSocket

說TFramedTransport 不能轉成 TSocket 這個類 ,估計是實例類跟要強轉的類不一致。

一開始,還以為自己的寫錯了,對着網上的博客檢查了以下沒有問題。只是發現這個實際實例化出來的類不是 TSocket 類型。試了幾次后,發現還是不行,於是有根據這個錯誤在網上找了一下,TFramedTransport 獲取 IP(參考這個錯誤描述: https://www.oschina.net/question/858822_2182069) 。這才發現,我們的thrift接口提供方式跟網上說的不一樣,而我們這種情況,如果需要獲取Client Ip ,有這幾種方式:1. 修改thrift 框架源碼, 2. 重新繼承TFramedTransport類重寫里面的一個方法。

看到這兩種方法,我們一下子就放棄了,原本想着只是簡單加個監控,沒想着修改太多東西,如果為了見這樣一個監控,改動那么大的,害怕影響業務(我們這個api服務還是挺多業務方在使用的)。

方法二,網絡抓包

於是,我們考慮起第二種方案,使用抓包去打印出客戶端ip和請求參數。tcpdump 是一開始就會想到的工具,當用 tcpdump 去抓包的時候,發現 thrift 接口有些是亂碼的。接着就網上找一下是否thrift接口的監控工具,一圈下來,說 thrift-tool ,wireshark(tshark)可以使用,然后又去試了,安裝了挺久的,發現由於我們機器的ubuntu的版本太久了,安裝不了最新的 thrift-tool (這個是安裝之后,還要依賴tcpdump的版本,tcpdump版本太老也不行,tcpdump命令重裝也重裝了很久😰,最后發現也安裝不了指定版本)和 wireshark ,發現都沒有辦法使用這兩種工具。考慮到我們這個api服務都部署在很多老的物理機上面,考慮兼容性問題和可以方便在其他機器上也部署(我們這個api服務分別部署在10多台的物理機上)。

於是又重新考慮回tcpdump 命令了兜兜轉轉一圈又回到原點, tcpdump 🐮逼。簡單實驗了一下,抓包的出的thrift請求參數和響應結構,如果是英文的,大部分還是能正常顯示的,可以根據 判斷是否包含 接口請求參數英文關鍵字 和判斷目標ip和端口,獲取到對應的請求參數和的請求ip。如果發送的參數為英文tcpdump直接抓包是能顯示大部分參數的,需要完整的參數信息也可以通過直接在業務代碼中加監控,thrift 接口在代碼中監控發送請求參數還是挺簡單的,主要是獲取請求ip有點麻煩。

大概命令是這樣的(這里假設read為請求參數關鍵字)
tcpdump -i any -A -s 0 'tcp port 9521' | grep -E "read|> [0-9\.]+9521"

這樣就可以獲取到 thrift 接口請求到的 9521 端口 的訪問ip和請求參數,不過打印出來的日志,還需要自己的去處理一下的。基本上的請求參數的上一行就是該請求的ip。

總結

這篇文章主要介紹了解決獲取 thrift接口 的請求參數和客戶端請求 ip 的問題。算作記錄一下自己的解決問題的流程。其中順便了解一下抓包工具 wireshark 的使用,之前一直有聽說過這個軟件,但是一直沒有實際使用過,感覺的確好用。 另外算作也提醒自己在搭建api服務的時候,記得做好每次接口調用ip和請求ip的監控,不然后面接手的人查起來真的想崩潰,例如:我😪。

這篇也算一篇比較水的文章吧,不過我自己從這次解決問題中還是學到了很多東西的,稍微記錄一下:

  1. wireshark 過濾可以通過 tcp and ip.addr == 127.0.0.1 and thrift 命令設置在 dispaly filter 來獲取目標的請求, thrift 表示協議,不過如果wireshark 版本太低的話,可以識別不了這個協議。
  2. wireshark 的命令行版本為: tshark
  3. wireshark 的幫助文檔地址 https://gitlab.com/wireshark/wireshark/-/wikis/home ,wireshark 的CaptureFilters(捕捉前過濾) 和DisplayFilters(捕捉后篩選) 區別
  4. sudo tshark -s 512 -i eth0 -n -f 'tcp dst port 9521' -l tshark 的命令,捕捉tcp 的請求的,參考: https://www.cnblogs.com/liun1994/p/6142505.html

微信公眾號圖片


免責聲明!

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



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