我有一台运行网络密集型应用程序的机器,该应用程序会生成许多进程。我最近注意到机器正在生成 ARP 请求,寻找不存在的 IP 地址。我想追踪盒子上的哪个进程导致生成 ARP 请求,以便进行故障排除(这样我就可以知道应用程序的哪个部分正在寻找这个不存在的 IP)。
IP已更改,但无论如何它们并不重要。
tcpdump
我通过在同一网络上的另一台计算机上运行发现了这些 ARP 请求:
# tcpdump -i eth0 arp -t -n
ARP, Request who-has 1.1.1.100 tell 1.1.1.1, length 46
并不意味着有一个带有地址的设备1.1.1.100
,所以我想找到哪个进程1.1.1.1
正在寻找它。
我尝试使用ss -np | grep 1.1.1.100
以及netstat -np | grep 1.1.1.100
(对于那些好奇的人netstat
来说,被认为已弃用,它具有大多数相同的选项,并且旨在执行相同的功能)。这些都不会返回任何结果,可能是因为并列出打开的套接字,并且 ARP 请求将早于正在创建的套接字。ss
ss
ss
netstat
那么如何辨别哪个进程导致了 ARP 请求呢?
答案1
ss
确实显示尚未被 arp 解析的连接。他们处于状态SYN-SENT
。问题是这种状态仅保持几秒钟,然后连接就会失败,因此您可能看不到它。您可以尝试使用快速轮询
while ! ss -p state syn-sent | grep 1.1.1.100; do sleep .1; done
延长此状态时间的一种方法是为 arp 表中的 IP 地址设置任意硬连线 MAC 地址。然后连接将需要 30 秒以上才会超时,并且使用 更容易查看ss
。
例如,我的 eth0 位于 192.168.1.1
$ socat tcp:192.168.1.100:80 -
$ arp -i eth0 -n | grep 192.168.1.100
192.168.1.100 (incomplete) eth0
设置mac地址使socat很容易可见
$ sudo arp -i eth0 -s 192.168.1.100 80:ef:00:ff:ff:ff
$ socat tcp:192.168.1.100:80 - &
$ ss -p state syn-sent
Netid Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp 0 1 192.168.1.1:46608 192.168.1.100:http users:(("socat",pid=20230,fd=3))
答案2
您可以使用网络猪显示每个进程的网络流量的程序。但 arp 不会直接由运行进程生成,而是由操作系统生成。某些程序可能想要与 1.1.1.100 通信,但该 IP 不存在于 ARP 表中,因此操作系统正在发送 ARP 数据包来填充 MAC 地址表。
DHCP 服务器是否在 1.1.1.1 上运行?我想说的是,DHCP 服务器会探测租约范围内的地址,以查看其中哪些地址是空闲的。
答案3
我刚才也遇到了同样的问题。尝试了一些事情后,我回到了 sysdig。这对我来说效果很好:
sysdig fd.rip=1.1.1.100
就我而言,有问题的 IP 实际上是 172.28.210.22,输出是:
# sysdig fd.rip=172.28.210.22
5987580 15:42:55.952661802 7 dhclient (1232) < sendto res=300 data=...............*............RT..................................................
6318682 15:43:01.237021372 7 dhclient (1232) > sendto fd=6(<4u>172.28.210.22:67->172.28.208.42:68) size=300 tuple=0.0.0.0:68->172.28.210.22:67
6318683 15:43:01.237080305 7 dhclient (1232) < sendto res=300 data=...............*............RT..................................................
6926596 15:43:10.092470330 7 dhclient (1232) > sendto fd=6(<4u>172.28.210.22:67->172.28.208.42:68) size=300 tuple=0.0.0.0:68->172.28.210.22:67
6926608 15:43:10.092541255 7 dhclient (1232) < sendto res=300 data=...............*............RT..................................................
8882391 15:43:31.595024934 7 dhclient (1232) > sendto fd=6(<4u>172.28.210.22:67->172.28.208.42:68) size=300 tuple=0.0.0.0:68->172.28.210.22:67
这清楚地表明这是来自 dhclient。