Назад | Перейти на главную страницу

Как найти другой конец соединения сокета unix?

У меня есть процесс (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 на самом деле является сервером. Что нормально. Но как я могу узнать, какой процесс к нему подключен - используя соединение, которое является 36-м дескриптором файла в dbus-launcher? Пробовал lsof и даже greps на / proc / net / unix, но я не могу найти способ найти клиентский процесс.

Этот ответ только для Linux.

Обновление для Linux 3.3: Так как Зулакис написал в отдельный ответ (+1 это), вы можете использовать сс из iproute2 чтобы получить пару номеров inode для каждого соединения сокета, идентифицирующего локальный конец и одноранговый узел. Похоже, это основано на том же механизме, что и sock_diag (7) с UNIX_DIAG_PEER атрибут, идентифицирующий однорангового узла. An ответ по Тотор на Unix и Linux Stack Exchange ссылки на соответствующие коммиты в ядро и iproute2 а также упоминает о необходимости UNIX_DIAG настройка конфигурации ядра.

Исходный ответ для Linux до 3.3 следует.

На основе Ответ из Unix и Linux Stack Exchange, я успешно идентифицирован другой конец сокета домена unix с использованием структур данных в ядре, доступ к которым осуществляется с помощью gdb и /proc/kcore. Вам необходимо включить CONFIG_DEBUG_INFO и CONFIG_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 файл в приведенной выше команде.

Совсем недавно я наткнулся на похожую проблему. Я был шокирован, узнав, что бывают случаи, когда это невозможно. Я откопал комментарий создателя lsof (Вик Абелл), в котором он указал, что это сильно зависит от реализации сокета unix. Иногда информация о так называемой "конечной точке" для сокета доступна, а иногда нет. К сожалению, как он указывает, в Linux это невозможно.

В Linux, например, где lsof должен использовать / proc / net / unix, все сокеты домена UNIX имеют связанный путь, но не имеют информации о конечных точках. Часто нет связанного пути. Это часто делает невозможным определение другой конечной точки, но это результат реализации файловой системы Linux / proc.

Если вы посмотрите / proc / net / unix, вы сами убедитесь, что (по крайней мере, в моей системе) он абсолютно прав. Я до сих пор в шоке, потому что считаю такую ​​функцию необходимой при отслеживании проблем с сервером.

Фактически, ss из iproute2 (замена netstat, ifconfig и т. д.) может показать эту информацию.

Вот пример, показывающий сокет домена unix ssh-agent, к которому ssh процесс подключил:

$ 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))

Сокеты Unix обычно присваиваются номера парами и обычно идут подряд. Таким образом, пара для вас, вероятно, будет 1013410 +/- 1. Посмотрите, кто из этих двоих существует, и угадайте виновника.

Я написал инструмент который использует MvG gdb метод для надежного получения информации об узле сокета символы отладки ядра не нужны.

Чтобы подключить процесс к данному сокету, передайте ему номер inode:

# 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 взлома ненадежный. Он работает большую часть времени, но выйдет из строя или (что еще хуже) вернет неправильный сокет, если вам не повезло.

Отредактируйте ваш 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 чтобы очистить оставшиеся сокеты.

Следующая команда покажет вам, какой процесс сколько раз подключается к сокетам dbus на основе netstat вывод:

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)

Радоваться, веселиться.


См. Также соответствующие статьи для справки: