内容纲要

这篇文章介绍下网易开源的流量重放(replay)工具 TCPCopy,说是简单介绍,绝对不是谦虚,因为自己了解的确实也不多。为什么不甚了解呢,大家可以到 TCPCopy 的官方仓库看看,https://github.com/session-replay-tools/tcpcopy.git,这货的官方文档是全英文的,不知道为什么,读起来特别有难度。OK,吐槽到这里结束,接下来是实战时间。

由于 TCPCopy 改版,网上的很多资料都不适用于最新版的 TCPCopy,当前的最新版是 V1.0.0,本文档也是基于该版本。

一、TCPCopy 相关的尝试

TCPCopy 是用来做 TCP 重放的,常用的场景是把线上流量复制到测试环境,用来排查线下不容易重现的问题,或者对测试环境做压力测试。
TCPCopy 分为两部分,tcpcopy 和 intercept,很多文档都不会告诉你什么是 intercept。以把线上服务器流量复制到线下的场景为例,tcpcopy 运行在线上服务器,intercept 并不是运行在用来测试的服务器上,而是运行在一台辅助的服务器上。后面会告诉你这台服务器的作用。到这里,你发现似乎没有测试服务器的什么事,那是因为,测试服务器真的不需要做什么配置,只需要起一个测试程序,指一条路由就可以了。科普就到这里,后面是部署环节。

二、实战 TCPCopy

1、配置环境

TCPCopy --> TCPCopy V1.0.0
线上服务器 --> 192.168.124.105
测试服务器 --> 192.168.124.68
辅助服务器 --> 192.168.124.180

在我的这个配置环境有三台服务器,一台模拟线上服务器,一台作为测试服务器,还有一台作为辅助服务器。流程如下:

  • tcpcopy 运行在线上服务器上,tcpcopy 会把线上服务器收到的流量,重放给测试服务器,重放的时候 tcpcopy 修改了 IP 数据包的源 IP 地址(譬如修改源地址为 192.168.2.254)。所以,线上服务器和测试服务器应该部署相同的服务。
  • tcpcopy 把源 IP 伪造成 192.168.2.254 的包发给了测试服务器,如此,测试服务器在处理完 tcpcopy 发过来的数据以后,会把这些数据包返回给客户端,即伪造的 192.168.2.254。
  • 由于没有 192.168.2.254 这个地址,我们在测试服务器添加一条专门的路由,把发往 192.168.2.0/24 的数据包,都全部转交给辅助服务器。
  • 为了保证辅助服务器会接受这些本不属于自己的,部署在辅助服务器上的 intercept 就发挥作用了。辅助服务器还可以用来把客户端的请求返回给 tcpcopy,但是默认只返回响应头部给 tcpcopy。辅助服务器应该类似于黑洞。

2、线上机器安装 tcpcopy

在线上服务器上下载,然后编译安装 tcpcopy 的包,如下:

1
2
3
4
5
6
wget https://github.com/session-replay-tools/tcpcopy/archive/1.0.0.tar.gz
tar xvf 1.0.0.tar.gz
cd tcpcopy-1.0.0
./configure --prefix=/opt/tcpcopy/
make
make install

3、辅助机器安装 intercept

安装 intercept 有一些额外的依赖需要安装上,然后和 tcpcopy 一样的套路源码编译安装。

1
2
3
4
5
6
7
# yum -y install libpcap-devel
# https://github.com/session-replay-tools/intercept/archive/1.0.0.tar.gz
# tar xvf 1.0.0.tar.gz
# cd intercept-1.0.0
# ./configure --prefix=/opt/tcpcopy/
# make
# make install

安装过程到此结束,很 Easy 吧!

4、部署

为了简单期间,我们在线上和测试服务器上各启一个简单的 http 服务器,最简单的办法,不用 apache 和 nginx,直接用 python 自带的模块。HTTP 服务启动命令如下:

1
# python -m SimpleHTTPServer

在线上服务器和测试服务器同时运行这个命令,开启一个监听在 8000 端口的简易 HTTP 服务器。

先在辅助服务器上开启 intercept,步骤不能错,没有 intercept 的话,tcpcopy 启动不起来:

1
# /opt/tcpcopy/sbin/intercept -i eth0 -F 'tcp and src port 8000' -d
  • -i, intercept 会监听端口,和 tcpcopy 进行通信,-i 就是指定监听在哪个端口。tcpcopy 启动的时候会来连这个端口,如果连不上,就会启动失败。
  • -F, 过滤规则,语法和 pcap 一样。
  • -d, 已守护进程方式运行

还有其它参数可以使用,-h 便可以查看,不详细解释了。

然后,在线上服务器开启 tcpcopy:

1
# /opt/tcpcopy/sbin/tcpcopy -x 8000-192.168.124.68:8000 -s 192.168.124.180 -c 192.168.2.254 -n 2 -d
  • -x, 是指本机 8000 端口的流量 copy 到 192.168.124.68 的 8000 端口
  • -s, 指定 intercept 机器的地址,tcpcopy 要和 intercept 建立连接
  • -c 伪装地址,在把流量复制到测试服务器的时候,修改数据包的源地址为 192.168.2.254,这样方便指定路由。也可以写成 192.168.2.x,这样源地址就是指定网段中的地址了。
  • -n 流量放大倍数,如果不是压测目的就不用指定这个参数。
    -d 以守护模式运行。

最后,在测试服务器上开启路由 (切记辅助服务器要和测试服务器在一个子网里):

1
# route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.124.180

路由的意思是把发往 192.168.2.0/24 地址的数据包全部转给辅助服务器。

测试效果
在另外一台机器上,向线上服务器发起请求,然后查看两个 HTTP 服务器的实时日志,
线上服务器的结果:

tcpcopy-onlineserver.png

发起了两次请求,由于 url 不存在,返回了 404 的 HTTP Code。再看测试服务器:

tcpcopy-testserver.png

在测试服务器上,请求变成了四次,明显看到流量被放大了 1 倍。效果正如预期。除此之外,还可以看到日志中的客户端 IP 也不一样。在原始的请求中,解析出来了主机名为 Matrix3,而在测试机器上,客户端 IP 是 192.168.2.254,就是我们捏造的 IP,注意伪造 IP 的时候,一定要避免环境中存在的 IP 和常用的 IP。
注意

  • 辅助服务器要扮演成一个黑洞,所以不能开启 ip_forward
  • 在请求会修改数据的地方,譬如修改数据库,如果配置不当,可能导致数据被重复修改多次。

OK,TCPCopy 就这些了!大家使用愉快。

发表评论

电子邮件地址不会被公开。 必填项已用*标注