我通过 TCP 连接到哪些主机?
# ./tcpconnect
PID COMM IP SADDR DADDR DPORT
1479 telnet 4 127.0.0.1 127.0.0.1 23
1469 curl 4 10.201.219.236 54.245.105.25 80
1469 curl 4 10.201.219.236 54.67.101.145 80
11072 ssh 6 ...fe8203ac ...fe82abcd 22
我从哪里接受 TCP 连接?
# ./tcpaccept
PID COMM IP RADDR LADDR LPORT
907 sshd 4 192.168.56.1 192.168.56.102 22
907 sshd 4 127.0.0.1 127.0.0.1 22
5389 perl 6 ...fec0ae21 ...fec0ae21 7001
这些工具是 tcpdump 的包装器吗?地狱不!我不想跟踪每个数据包,然后过滤 SYN(如果没有必要),我不想这样做,而且我不想。我可以跟踪执行TCP套接字连接和接受的内核函数,这些函数(相对于所有数据包)频率较低,因此开销较低。
这是我在BCC工具集合中发布的两个工具。我之前写过关于 bcc 前端及其 eBPF 后端的文章:简而言之,eBPF 是一种可以提供高级跟踪能力的新型主线 Linux 内核技术,而 bcc 是让 eBPF 更易于使用的 python 前端。这些工具非常新,依赖于Linux 4.1功能。
当前版本将 IPv6 地址打印为最后 32 位十六进制。没有理由我们不能打印所有内容,只是还没有编码RFC-4291 / RFC-5952。
我首先在套接字层(soconnect.d 和 soaccept.d)使用 Solaris 系统上的 DTrace 创建了类似的工具,后来使用我开发的稳定 TCP DTrace 提供程序,它们实际上变成了单行代码。我们还没有bcc / eBPF,但最终用户可以同时使用这些工具,这些工具附带手册页,示例,并具有带有USAGE消息的传统界面:
# ./tcpconnect -h
usage: tcpconnect [-h] [-t] [-p PID]
Trace TCP connects
optional arguments:
-h, --help show this help message and exit
-t, --timestamp include timestamp on output
-p PID, --pid PID trace this PID only
examples:
./tcpconnect # trace all TCP connect()s
./tcpconnect -t # include timestamps
./tcpconnect -p 181 # only trace PID 181
我之前发布过一个TCP重传工具,它使用ftrace(较旧的内置Linux跟踪器)并且没有内核调试信息(一个繁重的要求),因此它可以轻松地在许多Linux系统上工作,包括我们目前在Netflix的生产系统。该工具在我的性能工具集合中。以这种方式使用更复杂的TCP工具是可能的,但它变得非常具有挑战性和脆弱性:与平台和寄存器使用相关的工具。我根据需要编写它们来解决问题,但由于它们的脆性,我不愿意分享它们。
这些 bcc 工具仍然有警告,在手册页中讨论过(主要是动态跟踪仍然是一个不稳定的接口,工具可能需要在内核版本之间进行维护),但编写相对更稳定的东西更容易。我期待将来编写和分享更多的TCP(和UDP)工具,并在可以运行这些工具的Linux 4.1+系统上。还有很多事情要做和理解!