tcpcopy運行需要intercept的支持,tcpcopy負責抓包和發包工作,而intercept負責截獲應答包
tcpcopy代碼下載地址:
git clone http://github.com/session-replay-tools/tcpcopy
configure:
./configure (默認raw socket方式抓包)
或者
./configure --pcap-capture? (pcap方式抓包,在某些場景下,丟包率會高于raw socket方式抓包,這時候需要類似pf_ring的支持)
對于intercept:
代碼下載地址:
git clone http://github.com/session-replay-tools/intercept
configure方式:
./configure
運行方法參考下面具體例子(tcpcopy采用了configure來編譯):
這是一個內網的應用例子,我們的目的是復制下圖中adserver應用服務器的請求到測試系統中去。
在線adserver有2臺,主要供nginx調用,所以客戶端IP地址來自于nginx所在機器的IP地址,均為同一網段的IP地址。
我們假設在線adserver機器為10.100.10.1,10.100.10.2,nginx所在的機器ip地址為:10.100.10.11,10.100.10.12,10.100.10.13,
測試服務器有10.100.10.31,10.100.10.32(輔助服務器)
其中,10.100.10.31運行著類似在線adserver的應用,端口為11511,而在線應用端口是11311
我們在10.100.10.31上面添加如下路由:
route add -host 10.100.10.11 gw 10.100.10.32
route add -host 10.100.10.12 gw 10.100.10.32
route add -host 10.100.10.13 gw 10.100.10.32
這里的意思就是說,在測試服務器10.100.10.31返回給客戶端10.100.10.11~13的響應走默認網關10.100.10.32,但10.100.10.32機器其實并沒有開啟路由模式,所以這些響應包到了10.100.10.32機器后,會在ip層被drop掉,留給我們的機會就是可以在10.100.10.32的數據鏈路層抓到這些響應包。
我們在10.100.10.32機器(輔助服務器)上面運行intercept,用來捕獲響應包,命令如下:
執行intercept命令(需要root權限):
./intercept -i eth0 -F 'tcp and src port 11511' -d
我們在在線機器上面運行tcpcopy(root權限):
./tcpcopy -x 11311-10.100.10.31:11511 -s 10.100.10.32 -d
這里tcpcopy的含義是復制在線11311端口的數據包到10.100.10.31上面的11511端口中去,-s指定運行intercept所在機器的ip地址。
這樣請求就過去了,測試結果如下:
[root@hz12-26 logs]# grep 'Thu 10:30' access_0516_10.log -c
99415
[root@hz12-25 logs]# grep 'Thu 10:30' access_0516_10.log -c
99414
[root@bgp176-148 logs]# grep 'Thu 10:30' access_0516_10.log -c
198693
最后,需要注意新架構的若干細節:
1)發起請求的客戶端所在機器,不能同時運行相應的intercept,因為響應數據包路由回來后,這臺機器的tcp層會發送reset數據包給測試服務器,這樣就會干擾測試的進行。
2)在線服務和測試服務不要在一臺機器
如果在線服務響應的目的ip地址和測試服務響應的目的ip地址是一樣的,路由設置的時候,是無法區分在線的響應和測試的響應
3)對于外網應用,由于客戶端ip地址來自于世界各地,路由策略如下:
a)用兩個網卡,一個外網網卡,一個內網網卡,讓外網請求都路由到第二臺測試服務器上面去
比如改變測試服務器上面的默認路由:
route del default gw 真正的網關ip地址
route add default gw 輔助服務器的ip地址
b)利用tcpcopy的-c參數,修改客戶端源ip地址,這樣就方便設置路由
比如:./tcpcopy -x 11311-10.100.10.31:11511 -s 10.100.10.32 -c 192.168.100.x
相應路由設置:
route add -net 192.168.100.0 netmask 255.255.255.0 gw10.100.10.32
4)如果是在同一網段利用外網地址訪問,在機器B上面設置去往機器A的響應,走機器C,那么設置默認外網網卡路由不會生效,需要顯式指定,比如:
route add -host 機器A的外網ip地址? gw 機器C的外網ip地址
5)如果是內網應用,由于客戶端ip地址少,建議采用如下:
route add -host 內網客戶端ip地址 gw 輔助服務器的ip地址
或者
//如果客戶端ip地址來自于其它網段的話
route add -net xxx.xxx.xxx.0 netmask 255.255.255.0 gw 輔助服務器的ip地址
不要采用默認網關的方式
6)如果tcpcopy遇到大量“unsend:too many packets”的報警,請采用raw socket方式來抓請求數據包
7)如果客戶端來自于同一網段,那么響應包可能會直接通過mac地址返回給客戶端,導致路由設置不起作用,響應包不會被intercept所截獲,導致復制失敗
解決策略有兩個:
1)檢測路由命令是否有沖突,導致響應包直接返回給客戶端
2)tcpcopy運行的時候通過-c參數來改變客戶端的ip地址為不同網段的ip地址,就可以解決此問題。
8)如果同時有內網訪問和外網訪問,應該分別針對外網應用和內網應用,設置相應路由
9)運行intercept的輔助服務器,為方便路由設置,最好要和測試服務器在同一個網段,而且不要設置ip_forward
10)本文檔更新時間為2014.8.25