我知道某个进程正在向某个 unix 域套接字 ( /var/run/asterisk/asterisk.ctl
) 写入数据,但我不知道发送者的 pid。如何才能找出谁在向套接字写入数据?我尝试过:
sudo lsof /var/run/asterisk/asterisk.ctl
但它只列出了套接字的所有者。我想知道谁在写入/读取此套接字,我还想嗅探数据。这可能吗?
答案1
简短的回答是:不可以,而且不容易。
在 Linux 上,lsof 依赖于/proc/net/unix
检索有关 UNIX 域套接字的信息。此接口列出了所有绑定的套接字,但它不是跟踪端点。因此你能可以看到有哪些套接字,但看不到与它们相连的是什么。这些信息是跟踪,必须跟踪,否则套接字连接将无法工作。我还没有找到任何机制来检索连接信息。
嗅探问题稍微有趣一些,但同样令人失望。我说的“不容易”是指不存在任何钩子可以潜入并获取该数据。最接近的模拟是使用 tcpdump 或 Wireshark,它们都使用 libpcap 来完成繁重的工作。虽然网络 (AF_INET) 和 UNIX 域 (AF_UNIX) 都是使用函数socket()
调用创建的,都用于connect()
连接、使用read()
和write()
处理数据,但它们由不同的内核子系统处理。这有一个不幸的副作用,即 libpcap 不是为与 UNIX 域套接字一起工作而设计的。
这个问题还有一点不那么暗淡的一面。看一下手册页。这是一个利用的recv(2)
低级系统调用。存在一个称为的标志。这将允许您嗅探通过 UNIX 域套接字的流量。所以这是好的一面,阴暗的一面是,据我所知,目前还没有任何应用程序被设计来执行此操作。所以你正在考虑一些开发工作。read()
recv()
MSG_PEEK
我真的希望曾是针对您问题的两个部分,可以简单地回答“是”。
答案2
是的,你可以这样做。你只需要 systemtap。
考虑一下systemtap 脚本示例这将打印读取或写入指定 inode 的任何程序的 PID 和进程名称(而你的 Unix 域套接字就是这样的东西)。
您可以轻松修改此脚本以打印正在读取/写入的实际数据;我将把这个操作留给读者作为练习。
答案3
我知道这并没有回答主要问题,但我还是来到这里,只搜索嗅探套接字上的通信。我决定为像我这样的人发帖。以下是我的做法:
$> sudo socat -t100 -x -v UNIX-LISTEN:/var/run/php5-fpm.sock.socat,mode=777,reuseaddr,fork UNIX-CONNECT:/var/run/php5-fpm.sock
您可以删除 -x 并只保留 -v 以进行 ascii 通信。希望这对某些人有帮助。
答案4
您可以使用的一个选项是使用unix转储它使用 eBPF 捕获往返于 unix 套接字的流量。