我希望有一个类似 tcpdump 的程序,它可以显示哪个程序发送了特定的数据包,而不仅仅是获取端口号。这是我时不时遇到的一个常见问题,当你手头有旧的 tcpdump 文件时,你无法找到哪个程序发送了该数据。
解决方案我如何识别 Linux 上哪个进程正在进行 UDP 通信? 表明我可以使用 auditd、dTrace、OProfile 或 SystemTap 解决此问题,但没有显示如何解决。即它没有显示调用 bind() 的程序的源端口。
我遇到的问题是奇怪的 UDP 数据包,由于这些端口的寿命很短,我花了一段时间才解决这个问题。我通过运行类似于以下的丑陋黑客来解决这个问题:
while true; date +%s.%N;netstat -panut;done
因此,要么有一种比这个 hack 更好的方法,要么有一种 tcpdump 的替代品,要么有某种方法可以从内核获取此信息,以便我可以修补 tcpdump。
使用 auditd 解决这个问题
sudo auditctl -a exit,always -F arch=b64 -S bind -k BIND
这将在 /var/log/audit/audit.log 中填充如下行:
type=SYSCALL msg=audit(1292929028.845:3377): arch=c000003e syscall=49 success=yes exit=0 a0=3 a1=808710 a2=10 a3=7fffab28ea10 items=0 ppid=1564 pid=24442 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=4294967295 comm="nc" exe="/bin/nc.openbsd" key="BIND"
type=SOCKADDR msg=audit(1292929028.845:3377): saddr=0200FFFF000000000000000000000000
然后解析 saddr=0200xxxx00,其中 xxxx 是端口号,0001 最低,FFFF 最高。
编辑:这是向超级用户提出的“跟踪程序发送到网络的内容”,但是没有什么好的解决方案。
答案1
有关发送数据包的进程的信息(即使该数据包源自本地计算机)不适用于 tcpdump,因为内核的数据包捕获接口不提供该信息...搜索“DLT_LINUX_SLL”http://www.tcpdump.org/pcap3_man.html
改变这一点肯定是一项相当复杂的内核黑客任务......
最接近解决方案的似乎是 iptable 的“owner”匹配模块,它支持通过用户 ID 匹配数据包(在一些linux 版本,我记得那个功能后来被删除了),以及 LOG 目标的 --log-uid(遗憾的是没有 --log-pid)选项。
因此,当您添加一个 iptables 规则时,例如: iptables -I OUTPUT -p tcp --syn -j LOG --log-prefix "new tcp connection: " --log-uid
您会获得一份日志(在您的内核日志中,又名dmesg
),其中包含所有新建立的连接及其源端口和用户 ID,因此您可以获得到用户的连接图,而无需轮询 netstat...
答案2
看着这个答案相同的问题。它建议使用审计框架。