如何找到Unix套接字连接的另一端?


44

我有一个进程(dbus-daemon),该进程通过UNIX套接字具有许多打开的连接。这些连接之一是fd#36:

=$ ps uw -p 23284
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
depesz   23284  0.0  0.0  24680  1772 ?        Ss   15:25   0:00 /bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session

=$ ls -l /proc/23284/fd/36 
lrwx------ 1 depesz depesz 64 2011-03-28 15:32 /proc/23284/fd/36 -> socket:[1013410]

=$ netstat -nxp | grep 1013410
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
unix  3      [ ]         STREAM     CONNECTED     1013410  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD

=$ netstat -nxp | grep dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013953  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013825  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013726  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013471  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1013410  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1012325  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1012302  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1012289  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1012151  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011957  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011937  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011900  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011775  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011771  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011769  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011766  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011663  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011635  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011627  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011540  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011480  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011349  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011312  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011284  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011250  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011231  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011155  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011061  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011049  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011035  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1011013  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1010961  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD
unix  3      [ ]         STREAM     CONNECTED     1010945  23284/dbus-daemon   @/tmp/dbus-3XDU4PYEzD

基于数字连接,我假设dbus-daemon实际上是服务器。没关系 但是,如何使用dbus-launcher中第36个文件句柄的连接找到连接到哪个进程?在/ proc / net / unix上尝试了lsof甚至是grep,但是我找不到找到客户端进程的方法。


这在U&L 上得到了
sch

Answers:


25

最近,我偶然发现了一个类似的问题。我震惊地发现,在某些情况下这可能是不可能的。我从lsof(Vic Abell)的创建者那里挖了一条评论,他指出这在很大程度上取决于unix套接字的实现。有时,套接字的所谓“端点”信息可用,有时则不可用。他指出,不幸的是在Linux中是不可能的。

例如,在Linux上,lsof必须使用/ proc / net / unix,所有UNIX域套接字都具有绑定路径,但是没有端点信息。通常没有束缚之路。这通常使得无法确定另一个端点,但这是Linux / proc文件系统实现的结果。

如果您查看/ proc / net / unix,您会发现自己(至少在我的系统上)绝对是正确的。我仍然感到震惊,因为在跟踪服务器问题时我发现该功能至关重要。



请注意,这/proc/net/unix将告诉您从中挖出的随机域套接字引用的目标文件/proc/.../fd/
i336_

26

此答案仅适用于Linux。根据Unix&Linux Stack Exchange 的回答,我成功地使用内核数据结构(通过gdb和访问)识别了Unix域套接字的另一端/proc/kcore。您需要启用CONFIG_DEBUG_INFOCONFIG_PROC_KCORE内核选项。

您可以lsof用来获取套接字的内核地址,该地址采用指针的形式,例如0xffff8803e256d9c0。该数字实际上是相关内核内存结构或类型的地址struct unix_sock。该结构具有一个称为的字段peer,该字段指向套接字的另一端。所以命令

# gdb /usr/src/linux/vmlinux /proc/kcore
(gdb) p ((struct unix_sock*)0xffff8803e256d9c0)->peer

将打印连接另一端的地址。您可以grep该lsof -U号码的输出,以识别另一端的进程和文件描述符号码。

一些发行版似乎将内核调试符号作为单独的软件包提供,它将代替vmlinux上述命令中的文件。


这看起来很有趣,但是要求重新编译内核似乎是一个过大的选择。我在想,如果不手工制作内核,也不需要使用gdb,也许可以这样做,只需查看kcore中的值并对值进行一些“手动”解码即可。

3
@depesz,您只需要知道peer成员在unix_sock结构中的偏移量即可。在我的x86_64系统上,该偏移量为656字节,因此我可以使用来获得另一端p ((void**)0xffff8803e256d9c0)[0x52]CONFIG_PROC_KCORE显然,您仍然需要。
MvG 2012年

11

实际上,ssfrom iproute2(替换为netstat,ifconfig等)可以显示此信息。

这是显示ssh进程已连接到的ssh-agent UNIX域套接字的示例:

$ sudo ss -a --unix -p
Netid  State      Recv-Q Send-Q Local                             Address:Port          Peer    Address:Port
u_str  ESTAB      0      0      /tmp/ssh-XxnMh2MdLBxo/agent.27402 651026                *       651642                users:(("ssh-agent",pid=27403,fd=4)
u_str  ESTAB      0      0       *                                651642                *       651026                users:(("ssh",pid=2019,fd=4))

嗯 有趣的是...我错过了“ Address:Port”列可以匹配的情况,即使“ Peer”列对于unix域套接字完全没有用。
SamB

9

Unix套接字通常成对分配编号,并且通常是连续的。因此,您的货币对可能是1013410 +/- 1。看看这两个中的哪一个存在,并猜测罪魁祸首。


8

我写了一个工具,它使用MvG的gdb方法可靠地获取套接字对等信息,不需要内核调试符号。

要将进程连接到给定的套接字,请向其传递索引节点号:

# socket_peer 1013410
3703 thunderbird 

要一次使用查找所有进程netstat_unix,它将在netstat的输出中添加一列:

# netstat_unix
Proto RefCnt Flags       Type       State         I-Node   PID/Program name     Peer PID/Program name  Path
unix  3      [ ]         STREAM     CONNECTED     6825     982/Xorg             1497/compiz            /tmp/.X11-unix/X0
unix  3      [ ]         STREAM     CONNECTED     6824     1497/compiz          982/Xorg                 
unix  3      [ ]         SEQPACKET  CONNECTED     207142   3770/chromium-brows  17783/UMA-Session-R       
unix  3      [ ]         STREAM     CONNECTED     204903   1523/pulseaudio      3703/thunderbird       
unix  3      [ ]         STREAM     CONNECTED     204902   3703/thunderbird     1523/pulseaudio           
unix  3      [ ]         STREAM     CONNECTED     204666   1523/pulseaudio      3703/thunderbird       
...

尝试netstat_unix --dump是否需要易于解析的输出。
有关详细信息,请参见https://github.com/lemonsqueeze/unix_sockets_peers

对于信息,inode + 1 / -1 hack是不可靠的。它在大多数情况下都有效,但是如果运气不好,它将失败或(错误)返回错误的套接字。


1

编辑您的system.conf

在此文件中,您可以添加更多东西以进行调试。

档案位置: /etc/dbus-1/system.conf

为了调试,您可以编辑system.conf以允许监听:

  1. 将政策部分替换为:

    <policy context="default">

    <!-- Allow everything to be sent -->

    <allow send_destination="*" eavesdrop="true"/>

    <!-- Allow everything to be received -->

    <allow eavesdrop="true"/>

    <!-- Allow anyone to own anything -->

    <allow own="*"/>

    <!-- XXX: Allow all users to connect -->

    <allow user="*"/> </policy>

  2. 删除包含的行:system.d

    <includedir>system.d</includedir>

资料来源:http : //old.nabble.com/dbus-send-error-td29893862.html


有关Unix套接字的其他一些有用的东西

弄清楚总线上发生了什么的最简单方法是运行dbus-monitor程序,该程序随D-Bus软件包一起提供

您也可以尝试用来dbus-cleanup-sockets清理剩余的套接字。

以下命令将根据netstat输出显示与dbus套接字连接了多少个进程:

sudo netstat -nap | grep dbus | grep CONNECTED | awk '{print $8}' | sort | uniq -c

(在Ubuntu上测试)

核心方式:此命令将从/ proc手动查找进程,并显示使用最多连接(所有类型的套接字)的进程:

ls -lR */fd/* | grep socket | sed -r "s@([0-9{1}]+)/fd/@_\1_@g" | awk -F_ '{print $2}' | uniq -c | sort -n | awk '{print $1" "$2; print system("ps "$2"|tail -n1")}'

输出示例:

(计数,PID和下一行包含有关过程的详细信息)

25 3732
 3732 ?        Ss     0:38 /usr/bin/wineserver
89 1970
 1970 ?        Ss     0:02 //bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session

(在Ubuntu上测试)

玩得开心。


另请参阅相关文章以供参考:

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.