有时项目上线前需要模拟线上流量进行压测或者验证功能,或者从线上导流到测试环境,排查问题,使用 tcpcopy 可以帮你完成这些目的。
https://github.com/session-replay-tools/tcpcopy
一. 下载及安装
1.1. 下载
需要两个工具,分别是:
1.2. 工具部署
使用tcpcopy
进行线上导流,通常需要 3 台服务器:
- online server (运行 tcpcopy)
- target server (流量从 online server 复制到此机器)
- assistant server (运行 intercept)
1.3. 安装及命令使用方法
1.3.1. tcpcopy
./configure(在线导流模式)
或
./configure --offline(离线回放模式)
make
make install
在线导流方法:
tcpcopy -x localServerPort-targetServerIP:targetServerPort -s interceptServerIP
[-c <ip range,>] -d
离线重放方法:
tcpcopy -x 80-192.168.44.137:80 -s 192.168.44.136 -i test.pcap -n 2
将 test.pcap 报文放大 2 倍发送给 192.168.44.137
1.3.2. intercept
cd intercept
./configure
make
make install
使用方法:
intercept -F <filter> -i <device,>
二. 测试
假设我们 3 台服务器情况分别如下:
- online server: 192.168.44.128
- target server: 192.168.44.137
- assistant server: 192.168.44.136
2.1. 运行命令
2.1.1. target server
如果是在同一网段,设置去往 online server 的响应,路由到 assistant server,可以这样指定:
route add -host onlineIP gw assistantIP
如果客户端 IP 来自于其它网段的话:
route add -net xxx.xxx.xxx.0 netmask 255.255.255.0 gw assistantIP
这里添加静态路由:
route add -net 192.168.50.0 netmask 255.255.255.0 gw 192.168.44.136
确保被测试应用程序的响应包路由到辅助测试服务器,而不是回包给 online server
2.1.2. assistant server
intercept -i eth0 -F 'tcp and src port 80' -d
intercept 过滤 eth0 网卡 80 端口的 tcp response 报文。
辅助服务器要确保没有开启路由模式,为0表示没有开启:
cat /proc/sys/net/ipv4/ip_forward
0
辅助服务器上的 intercept 通过 pcap 抓取测试机应用程序的响应包,将头部抽取后发送给 online server 上的 tcpcopy ,从而完成一次请求的复制。
2.1.3. online server
tcpcopy -x 80-192.168.44.137:80 -s 192.168.44.136 -c 192.168.50.x -d
将本机 80 端口数据转发给192.168.44.137:80
,更改 client IP 为 192.168.50.x 之一,并从 192.168.44.136 获取 response 报文。
2.2. 查看各 server 报文情况
可以在各个 server 上使用 tcpdump 抓包查看收发报文情况
如:online server 上
tcpdump -n -i eth0 port 80 and dst host 192.168.44.137
三. 遇到的问题
3.1. 无法复制流量问题
之前在三台机器都是同网段的机器上测试,是可以成功复制流量的,但是 online server 与 target server 不在同一网段时,发现无法复制流量。
抓包发现
online ------(SYN)------> target
online <---(SYN + ACK)--- target
online ------(RST)------> target
解决方案
采用两台机器方案:
- online server,假设 IP 1.2.3.4
- target server,假设 IP 192.168.44.137
online server 运行:
tcpcopy -x 80-192.168.44.137:80 -s 192.168.44.137 -c 1.2.3.4 -d
online server iptables 添加下面规则
iptables -A INPUT -s 192.168.44.137 -p tcp --sport 80 -j DROP
target server 运行:
intercept -i eth0 -F 'tcp and src port 80' -d
然后可以分别在两台服务器上查看日志,如 nginx:
tail -f /usr/local/nginx/logs/access.log
参考
https://github.com/session-replay-tools/tcpcopy/issues/233
https://github.com/session-replay-tools/tcpcopy/issues/278
https://github.com/session-replay-tools/tcpcopy/issues/246