Sniff UNIX доменный сокет

9

Я знаю, что какой-то процесс пишет в определенный сокет домена unix ( /var/run/asterisk/asterisk.ctl), но я не знаю pid отправителя. Как я могу узнать, кто пишет в сокет? Я пытался с:

sudo lsof /var/run/asterisk/asterisk.ctl

но это просто список владельцев сокета. Я хотел бы знать, кто пишет / читает в этот сокет, и я также хотел бы прослушать данные. Это возможно?

dangonfast
источник

Ответы:

4

Коротких ответов нет и не легко.

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

Вопрос об нюхании немного интереснее, но не менее разочаровывает. То, что я имел в виду под «не легко», - это то, что не существует какого-либо крючка, чтобы проникнуть и захватить эти данные. Ближайшим аналогом является использование tcpdump или Wireshark, оба из которых используют libpcap для выполнения тяжелой работы. Хотя сеть (AF_INET) и домен UNIX (AF_UNIX) созданы с использованием socket()вызова функции, оба используют connect()для подключения, как для обработки , так read()и write()для обработки данных, они обрабатываются различными подсистемами ядра. Это имеет неприятный побочный эффект, что libpcap не предназначен для работы с сокетами домена UNIX.

Есть немного менее смутная сторона проблемы. Взгляните на справочную страницу для recv(2). Это системный вызов более низкого уровня, который read()использует. Существует флаг для recv()вызова MSG_PEEK. Это позволит вам прослушивать трафик, проходящий через сокет домена UNIX. Так что это светлая сторона, темная сторона в том, что, насколько мне известно, не существует ни одного текущего приложения, предназначенного для этого. Итак, вы смотрите на некоторые усилия по разработке.

Я действительно хочу там был хороший простой ответ F'YEAH к обеим частям вашего вопроса.

Скотт Пак
источник
11

Да, ты можешь это сделать. Все, что вам нужно, это systemtap.

Рассмотрим один из примеров сценариев systemtap, который будет печатать PID и имя процесса любой программы, которая читает или записывает указанный inode (и ваш сокет домена Unix - именно такая вещь).

Вы можете тривиально изменить этот скрипт для печати фактических данных, которые читаются / пишутся; Я оставлю это в качестве упражнения для читателя.

Майкл Хэмптон
источник
4

Я знаю, что это не отвечает на главный вопрос, но я закончил здесь, ища просто сниффинг связи в сокете. Я решил опубликовать для других, как я. Вот как я это сделал:

$> 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. Надеюсь, что это помогает кому-то.

Антон Валкк
источник
отлично работает
JSmyth
-1

socat -t100 UNIX-LISTEN: /tmp/file.sock,mode=777,reuseaddr,fork STDOUT

Нет дублирования вывода, нет циклического вывода. Ошибка предыдущего комментария ".sock.socat"

srvf
источник
2
Хотя это может быть полезной командой, пожалуйста, добавьте некоторые пояснения / пояснения (и чем это отличается от этого ответа ?)
HBruijn
Мне жаль. Нет дублирования вывода, нет циклического вывода. Ошибка предыдущего комментария ".sock.socat"
srvf