我怎么能确定哪个进程在Linux上进行UDP通信?

我的机器正在不断做出udp DNS的stream量请求。 我需要知道的是产生这种stream量的过程的PID。

TCP连接的正常方式是使用netstat / lsof并获得与pid关联的进程

UDP是连接状态,所以,当我打电话给netastat / lsof我可以看到它只有当UDP套接字打开,它正在发送stream量。

我已经尝试了lsof -i UDP和nestat -anpue,但我无法find至极的进程正在做这个请求,因为我需要调用lsof / netstat到udpstream量发送时,如果我打电话给lsof / netstat之前/在发送udp数据报之后,不可能查看打开的UDP套接字。

当3/4 udp数据包发送时正好调用netstat / lsof是不可能的。

我怎么能确定臭名昭着的过程? 我已经检查了stream量,试图从数据包的内容中识别发送的PID,但是不能从stream量的angular度来识别它。

任何人都可以帮助我?

我在这台机器上root FEDORA 12 Linux noise.company.lan 2.6.32.16-141.fc12.x86_64#1 SMP Wed Jul 7 04:49:59 UTC 2010 x86_64 x86_64 x86_64 GNU / Linux

    Linux审计可以提供帮助。 它至less会使用户和进程build立数据报networking连接。 UDP数据包是数据报。

    首先,在你的平台上安装auditd框架,并确保auditctl -l返回一些东西,即使它没有定义规则。

    然后,添加一个规则来观察系统调用socket()并标记它以便稍后查找( -k )。 我需要假设你是在64位体系结构上,但是如果你不是的话,你可以用b32代替b64

     auditctl -a exit,always -F arch=b64 -F a0=2 -F a1=2 -S socket -k SOCKET 

    你必须select手册页和头文件来构build它,但是它捕获的实质上是这个系统调用: socket(PF_INET, SOCK_DGRAM, X)其中第三个参数是未指定的,但是通常为零。 PF_INET是2, SOCK_DGRAMSOCK_STREAM连接将使用SOCK_STREAM ,它将设置a1=1-k SOCKET是我们稍后search审计跟踪时要使用的关键字。 它可以是任何东西,但我喜欢保持简单。

    让我们花点时间回顾一下审计线索。 可选地,您可以通过在networking上ping一个主机来强制几个数据包,这将导致发生DNS查找,该查找使用UDP,这应该跳过我们的审计警报。

     ausearch -i -ts today -k SOCKET 

    和下面的部分相似的输出将会出现。 我正在缩写它来突出重要的部分

     type=SYSCALL ... arch=x86_64 syscall=socket success=yes exit=1 a0=2 a1=2 ... pid=14510 ... auid=zlagtime uid=zlagtime ... euid=zlagtime ... comm=ping exe=/usr/bin/ping key=SOCKET 

    在上面的输出中,我们可以看到ping命令导致套接字打开。 如果它仍在运行,我可以在该进程上运行strace -p 14510ppid (父进程ID)也被列出,以防它是一个产生问题孩子的脚本。

    现在,如果你有大量的UDPstream量,这还不够好,你将不得不求助于OProfile或SystemTap ,这两者目前都超出了我的专业知识。

    这应该有助于在一般情况下缩小范围。

    完成后,通过使用与创build该行相同的行来删除审计规则,只能用-dreplace-a

     auditctl -d exit,always -F arch=b64 -F a0=2 -F a1=2 -S socket -k SOCKET 

    您可以使用netstat,但您需要正确的标志,并且只有在发送数据的进程仍然存在的情况下才有效。 它不会find短暂的事情的踪迹,发送UDPstream量,然后走开。 它还需要本地root权限。 那就是说:

    这里是我在本地主机上启动一个ncat,发送UDPstream量到一个(不存在的)机器上的端口2345 10.11.12.13:

     [madhatta@risby]$ ncat -u 10.11.12.13 2345 < /dev/urandom 

    以下是一些tcpdump输出,certificatestream量正在进行:

     [root@risby ~]# tcpdump -n -n port 2345 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes 12:41:32.391750 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192 12:41:32.399723 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192 12:41:32.401817 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192 12:41:32.407051 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192 12:41:32.413492 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192 12:41:32.417417 IP 192.168.3.11.57550 > 10.11.12.13.2345: UDP, length 8192 

    这是有用的位 ,使用带有-a标志的netstat(查看端口详细信息)和-p标志来查看进程ID详细信息。 这是需要root权限的-p标志:

     [root@risby ~]# netstat -apn|grep -w 2345 udp 0 0 192.168.3.11:57550 10.11.12.13:2345 ESTABLISHED 9152/ncat 

    正如你所看到的,pid 9152被指派为在指定的远程主机上连接到端口2345的连接。 Netstat也可以通过ps运行,告诉我进程名是ncat

    希望这有一些用处。

    我有完全相同的问题,不幸的是, auditd对我没有太大的帮助。

    我的一些服务器的stream量已经达到了google的DNS地址8.8.8.88.8.4.4 。 现在,我的networkingpipe理员有轻微的强迫症,他想清除所有不必要的stream量,因为我们有我们的实习DNScaching。 他想为除了那些caching服务器以外的每个人禁用传出端口53。

    所以,在auditctl失败后,我深入到systemtap 。 我想出了以下脚本:

     # cat >> udp_detect_domain.stp <<EOF probe udp.sendmsg { if ( dport == 53 && daddr == "8.8.8.8" ) { printf ("PID %5d (%s) sent UDP to %15s 53\n", pid(), execname(), daddr) } } EOF 

    然后只需运行:

     stap -v udp_detect_domain.stp 

    这是我得到的输出:

     PID 3501 (python) sent UDP to 8.8.8.8 53 PID 3501 (python) sent UDP to 8.8.8.8 53 PID 3506 (python) sent UDP to 8.8.8.8 53 

    而已! 在改变resolv.conf那些PID没有select改变。

    希望这可以帮助 :)

    我会使用像tcpdump或wireshark的networking嗅探器来查看DNS请求。 查询的内容可以给出什么程序正在发布他们的想法。

    这是一个systemtap选项,使用stap verson 1.8和更高版本中提供的netfilter探针。 另请参见man probe::netfilter.ip.local_out

     # stap -e 'probe netfilter.ip.local_out { if (dport == 53) # or parametrize printf("%s[%d] %s:%d\n", execname(), pid(), daddr, dport) }' ping[24738] 192.168.1.10:53 ping[24738] 192.168.1.10:53 ^C 

    请注意,在使用autitctl时,例如,在进行DNS查询时,nscd在套接字系统调用中使用稍微不同的参数:

     socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) 

    因此,为了确保您能够捕获上面提到的查询,可以添加一个额外的filter,如果需要,可以使用相同的名称:

     auditctl -a exit,always -F arch=b64 -F a0=2 -F a1=2050 -S socket -k SOCKET 

    这里2050是SOCK_DGRAM (2)和SOCK_NONBLOCK (2048)的按位或。

    然后search将find两个具有相同键的filter, SOCKET

     ausearch -i -ts today -k SOCKET 

    我在这里find的套接字常量的hex值: https : //golang.org/pkg/syscall/#pkg-constants

    由于我没有名誉点评论我加了这个。