Как узнать, какая программа на другом конце локального сокета?

Процесс в моей системе Linux, говорит мне strace, говорит о сокет, который имеет дескриптор файла 10. lsof говорит мне, что это unix-сокет с inode 11085, а netstat далее сообщает мне, что inode 11085 - и что он подключен.

Учитывая, что в этом процессе нет других потоков, в системе должен быть еще один процесс, связанный с другим концом этого сокета. Как узнать, что это такое?

Update:

Там некоторое освещение от автора lsof здесь. По сути, кажется, что Linux просто не предоставляет эту информацию.

Ответы

Ответ 1

ss -p

расскажет. (Если сокет не принадлежит самому ядру.)

Ответ 2

Помогает ли netstat -p?

Из Manpage:

  -p,
  --program Show the PID and name of the program to which each socket belongs.

Ответ 3

Как насчет этого: grep 11085 /proc/net/unix. Предполагая, что существует непустой путь, присутствующий в строке, с интересующим вас inode, grep для этого пути в /proc/net/unix, чтобы найти inode для другого конца соединения, затем используйте метод @efficientjelly для сопоставьте другой индекс inode с pid.

Ключевым моментом здесь является тот факт, что каждый из двух подключенных сокетов будет иметь разные номера inode.

Ответ 4

Похоже, если вы действительно в отчаянии, вы можете получить эту информацию непосредственно из памяти ядра Linux, используя некоторый отладчик ядра. С инструментом RHEL5 "сбой":

  • получить несжатое vmlinux изображение (например, установить kernel-debuginfo rpm или извлечь файл vmlinux из этого числа оборотов в минуту)
  • run crash /path/to/vmlinux
  • net -s 12345 перечислены все сокеты для PID 12345
  • найдите интересный сокет (должен быть семейства/типа UNIX:STREAM) и обратите внимание на его значение SOCK:
    • PID: 12345 TASK: e903d000 CPU: 0 COMMAND: "someapp"
    • FD SOCKET SOCK FAMILY:TYPE SOURCE-PORT DESTINATION-PORT
    • 36 cadd0240 c8a64040 UNIX:STREAM
  • теперь у вас есть адрес unix_sock struct для этого сокета
    • в основном, unix_sock.peer.name - это структура имени другого конца сокета
    • напечатайте его с помощью p *(*(*((struct unix_sock*)( (struct unix_sock*)0xc8a64040)->peer)).addr).name

Действительно печально, что эта информация напрямую не экспортируется в пользовательское пространство.

Ответ 5

Я заметил, что:

Инод fd, который называется connect() на стороне клиента, всегда точно больше, чем тот, который вы получили от вызова accept() на стороне сервера.

Пример вывода из моей проги:

client_fd=4
/proc/4436/fd/4
inode=3072
is socket
node: 3072 socket: /tmp/unix.socket
f0be8960: 00000003 00000000 00000000 0001 03  3072 /tmp/unix.socket

/proc/9293/fd/43
fd:43
inode=3073
is socket
node: 3073 socket: 
f0be81e0: 00000003 00000000 00000000 0001 03  3073

Связанный путь не отображается в /proc/net/unix, хотя.

YMMV и я не исследовали основную механику.

Ответ 6

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

Чтобы связать процесс с данным сокетом, передайте ему номер inode:

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

Ответ 7

Если по какой-то причине вам не повезло с соответствующими параметрами lsof и netstat, вы также можете сделать следующее:

find /proc -lname '*11085*' 2> /dev/null

Ответ 8

lsof | grep 11085

lsof должен выполняться как root.

Я экспериментировал с lsof в своей Linux-системе, а lsof -U показывает, что все числа под столбцом NODE уникальны.