如何找出发送数据包(生成网络流量)的进程的PID?

Jak*_*sic 7 networking linux auditd

几周前,我遇到了一个问题,我在大约 300 个节点的大型网络中更改了 DNS 地址。之后,一些节点仍然继续询问旧的DNS服务器,尽管resolv.conf没问题,并且host/nslookup正在查询新的DNS服务器。

查看 tcpdump 并尝试使用 iptables 日志记录请求,我确认确实有些主机仍在向旧名称服务器发送查询。

我让其中一台主机退出生产并开始关闭服务/跟踪进程,试图找出罪魁祸首。

最后 - 它是 lldpd 守护进程,它显然在启动时缓存了名称服务器,甚至没有注意到 resolv.conf 中的变化。

所以,我的问题是 - 有没有更智能的方法来找出哪个 PId 正在生成特定类型的流量?我尝试使用 auditctl 但没有取得多大成功。CentOS 6 有问题,但如果有任何 Linux 发行版的解决方案,我将不胜感激。

Mar*_*ale 6

几天前我也遇到了同样的问题,并想出了一个非常简单的方法。它基于这样一个事实,即发送进程将在发送请求的同一端口上等待 DNS 响应的到来

  1. 找出传出 DNS 请求的源端口,使用 iptables -j LOG
  2. 使用lsof -i UDP:<source_port>找出哪些进程正在等待该端口上的响应。

当然,当响应在几毫秒内到达时,您不能手动执行此操作;此外,即使是自动化的,也不能保证您能够在 DNS 响应到达之前查询系统,并且发送过程终止。这就是为什么在执行上述步骤之前,我还配置内核流量控制器以延迟定向到特定 ip/端口的传出数据包(使用tc模块netem)。这使我可以控制我必须在步骤 1 中获得的源 UDP 端口上查询系统关于哪个 PID 正在等待 DNS 响应的时间窗口。

我已经tc在一个名为ptrap的小脚本中自动化了上述步骤,包括延迟(这是一个更通用的解决方案,不限于 DNS 请求,因此有资格检测使用任何基于 TCP/UDP 的协议的进程)。在它的帮助下,我发现,就我而言,联系旧 DNS 服务器的服务是 sendmail。


Dmi*_*ats 5

auditctl 有什么问题?

你会这样做

1) 定义你的审计规则来审计 sendmsg 和 sendto 系统调用。这些系统调用在名称解析期间使用。

auditctl -a exit,always -F arch=b64 -S sendmsg -S sendto -k send
Run Code Online (Sandbox Code Playgroud)

2) 现在搜索您的审计记录。您可以在此处根据远程 DNS IP 进行 grep

ausearch -k send -i|grep -A2 "serv:53"
Run Code Online (Sandbox Code Playgroud)

在下面的示例中,您可以看到负责系统调用的应用程序称为 dig

ausearch -k send -i|grep -A2 "serv:53"
type=SOCKADDR msg=audit(10/31/2016 15:24:56.264:176998) : saddr=inet host:172.16.0.23 serv:53 
type=SYSCALL msg=audit(10/31/2016 15:24:56.264:176998) : arch=x86_64 syscall=sendmsg success=yes exit=29 a0=14 a1=7fa1919f9ac0 a2=0 a3=7fa1919f9780 items=0 ppid=31729 pid=32047 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts5 ses=52 comm=dig exe=/usr/bin/dig subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=send


comm=dig exe=/usr/bin/dig
Run Code Online (Sandbox Code Playgroud)

区分远程 DNS 请求发送到哪个的方法在这里。所以你只需要为一个特定的 DNS 主机 grep。

saddr=inet host:172.16.0.23 serv:53 
Run Code Online (Sandbox Code Playgroud)

甚至更好 - 看看使用了哪些 DNS 主机(在这个例子中我只有一个)

ausearch -k send -i|grep "serv:53"|awk '{print $6}'|sort|uniq -c
      3 host:172.16.0.23
Run Code Online (Sandbox Code Playgroud)

然后缩小哪些应用程序正在使用这些特定主机。

编辑 1:实际上,我只是对主机进行了简单的 ping 操作。似乎并不总是使用 sendmsg 。这是我看到的

socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.16.0.23")}, 16) = 0
gettimeofday({1477929832, 712018}, NULL) = 0
poll([{fd=4, events=POLLOUT}], 1, 0)    = 1 ([{fd=4, revents=POLLOUT}])
sendto(4, "\3\326\1\0\0\1\0\0\0\0\0\0\tvkontakte\2ru\0\0\1\0\1", 30, MSG_NOSIGNAL, NULL, 0) = 30
poll([{fd=4, events=POLLIN}], 1, 5000)  = 1 ([{fd=4, revents=POLLIN}])
ioctl(4, FIONREAD, [62])                = 0
recvfrom(4, "\3\326\201\200\0\1\0\2\0\0\0\0\tvkontakte\2ru\0\0\1\0\1\300\f"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.16.0.23")}, [16]) = 62
close(4)                                = 0
Run Code Online (Sandbox Code Playgroud)

我之前的示例基于 dig 应用程序,它在系统调用方面采用略有不同的路线。
所以看起来在大多数情况下都是这个规则

auditctl -a exit,always -F arch=b64 -S connect -k connect
Run Code Online (Sandbox Code Playgroud)

其次是ausearch

ausearch -k connect -i|grep saddr|grep "serv:53"|awk '{print $6}'|sort|uniq -c
Run Code Online (Sandbox Code Playgroud)


she*_*n89 1

有很多选项可以netstat显示通过 tcp/udp/两者侦听/打开套接字的组合。就像是:

$> sudo netstat -pan
Active Internet connections (servers and established)
Proto  Recv-Q Send-Q Local Addr            Foreign Addr           State       PID/Program name
...
tcp    0      1      192.168.66.1:39219    192.168.66.139:2003    SYN_SENT    2045/logstash-forwa
Run Code Online (Sandbox Code Playgroud)

...将为您提供大量输出,但包括源、目标、端口号以及拥有这些端口的进程的 PID。

  • 这并不能回答问题。您也许可以看到已建立的连接,但是每 15 分钟恰好发送 1 个 UDP 数据包并且套接字立即关闭的进程又如何呢? (4认同)