Tcpcopy初体验.

Tcpcopy 初体验

 

Tcpcopy是一个模拟真实流量的测试工具。它的工作基本思想是,从已经上线的服务器复制一份真实流量到测试服务器。Tcpcopy的代码开源,代码仓库放在https://github.com/wangbin579/tcpcopy

 

经过初步学习,已成功在公司的测试机器上部署tcpcopy,并用简单的DEMO程序测试达到预期目的。

 

1.安装

因为作者写的安装介绍只提到最基本的信息,而测试环境各不一样,在我用的测试机的实际安装过程中碰到一些问题。这时问题在这里列出,以供后来者参考,以节省时间。测试机:10.12.194.199 ; 10.12.194.212 ; 10.12.194.214 。

 

1.1 需要额外安装的库:

需要在网站 www.netfilter.org 下载 libmnl, libnfnetlink, libnetfilter_queue 三个工程并安装。 安装顺序为 libmnl, libnfnetlink, libnetfilter_queue,因为第三个依赖第二个,第二个依赖第一个。安装方法是GNU工具的传统三板斧方式: ./configure ; make; make install。这三个工程生成三个.so库放置到/usr/local/lib,而我们用的操作系统环境并没有把该目录列在默认查找库文件的目录列表中,因此要编辑 /etc/ld.so.conf 文件,把目录/usr/local/lib 加入,再运行 ldconfig 更新ld链接程序使用的cache。

 

1.2 IP_Queue和NFQueue内核模块:

这两个内核模块给在用户空间编写处理内核空间中传递网络数据包提供接口。它们的区别是IP_Queue是旧的实现,仅支持IPv4,NFQueue是新的实现。Tcpcopy工程依赖这两个模块之一。

 

Tcpcopy官方文档中多次提到tcpcopy在内核版本小于3.5时默认使用IP_Queue,并在使用例子中有一步操作:

# modprobe ip_queue

这个操作是确保加载ip_queue模块到内核。

我们的测试环境的内核版本号是2.6.32,按照官方文档介绍,内核版本小于3.5,于是使用#modprobe ip_queue命令,结果报错显示我们使用的内核没有启用动态模块加载。

于是再用 # zcat /proc/config.gz 检查当前内核的配置,发现CONFIG_IP_NF_QUEUE is not set, 说明IP_Queue模块没有被buit-in,再查找NFQueue的配置项发现 CONFIG_NETFILTER_NETLINK_QUEUE=y。

所以,在我们的环境中,应该忽略官方文档中# modprobe ip_queue,我们的内核已经内建了比IPQueue更新的NFQueue

 

1.3 编译安装tcpcopy

官方文档中把已经正常运行业务的服务器称为在线服务器(online server),把运行待测试用的服务器称为目标服务器(target server)。

在在线服务器端运行配置命令时务必指定 –enable-nfqueue,这是因为我们用的内核中只有NFQueue,如果不指定这个选项,编译出的tcpcopy不会运行成功,会在日志文件中报错:please make sure ip queue is running.

# ./configure –enable-nfqueue –enable-pcap

 

官方文档中介绍设置防火墙规则时写道,如果内核使用NFQueue,则在目标服务器如此设置

# iptables -I OUTPUT -p tcp –sport port -j NFQUEUE

实际执行中,iptables返回出错iptables: Unknown error 18446744073709551615。咨询万能的谷歌后,给的答案是iptables的版本太旧,不认识NFQueue。于是下载了新的iptables版本并安装,但编译时报错缺少一个库文件,这个新的库文件在我们的相对比较旧的环境下没有。解决方案是仍然用旧的iptables:

# iptables -I OUTPUT -p tcp –sport port -j QUEUE

没有使用NFQUEUE,而是使用QUEUE,iptables设定通过。后面的测试证明暂时也没有问题。

 

2.测试

我把tcpd稍微改了一下,改成了一个echo服务器同时也打印收到的报文,监听9999端口。

把10.12.194.199作为在线服务器:

 

# cd /home/kamus/bin

# ./tcpd                  # 运行echo服务器

# ./tcpcopy -x 9999-10.12.194.212:9999  # 把发往echo服务器的tcp包复制一份发往10.12.194.212的9999端口

# ./tcpdump -vv -i any dst port 9999 # 监视所有发往9999端口的包

 

把 10.12.194.212 作为目标服务器:

# cd /home/kamus/bin

# ./tcpd

# ./intercept

 

把 10.12.194.214 作为客户机:

# cat /etc/passwd | netcat 10.12.194.199 9999

客户机把本机的密码文件发往10.12.194.199机器的echo服务器。这时客户机,在线服务器和目标服务器都打印出了 /etc/passwd 的文件。运行在在线服务器上的tcpdump监控到了tcpcopy复制的包。测试结果符合预期。

 

3.小结

目前只是简单的实验了一下tcpcopy,没有进行大流量的测试。

 

Tcpcopy的官方首页上的文档比用git clone下载下来后的源代码树中的最新文档旧。新的tcpcopy实现有了更高级的发式,可以不依赖内核空间的IP_Queue或NFQueue模块,但需要额外一台机器。还未测试这种方式。

 

另外,我有个想法,如果在线服务器和目标服务器用集线器连接,那么理论上可以在目标服务器上嗅探到在线服务器上收发的数据包,这样就可以不用在在线服务器上运行tcpcopy复制流量,而只需要在目标服务器上嗅探以太网上发往在线服务器上的数据包,这样就会对在线服务器毫无影响。

 

大致看了下tcpcopy的代码,发现代码写得很干净,希望把tcpcopy的代码详细看一遍,以后就能在上面进行二次开发,以及提高调试使用tcpcopy时出错的能力。

copyright ykyi.net