Могу ли я отслеживать локальный сокет домена Unix, например, tcpdump?

59

Я хотел бы отслеживать ответы в Unix-сокете, не нарушая исходные соединения, и направлять их в сценарий для обработки.

Я знаю, как сделать это с tcpdump для соединений tcp, но я не могу найти решение для локальных сокетов unix.

Это вообще возможно?

ck_
источник

Ответы:

15

Есть парень, который утверждает, что делает это, создавая приложение, которое действует как шлюз между двумя сокетами, и регистрирует все данные, которые передаются. Таким образом, вы не можете нажать на сокет, но если вы можете перезапустить сервис и настроить его для использования этого приложения, вы сможете увидеть весь трафик.

Вот ссылка на пост: Unix Socket Sniffer

Есть еще один способ, который требует, чтобы вы нашли идентификатор процесса, подключенный к сокету, затем найдите с помощью lsof дескриптор файла сокета и затем коснитесь дескриптора файла, используя strace.

Если вы можете остановить любой клиент / сервер, использующий сокет, и перенастроить его, я бы порекомендовал всегда первый метод, второй метод сложен и требует от вас прикосновения к текущему процессу, который в некоторых приложениях может вызвать его сбой.

Надеюсь, кто-то просветит нас другим способом :)

Удачи

доблесть
источник
Да, вы можете использовать метод посредника также с помощью socat, но я надеюсь на более прямой путь без изменения существующих настроек в другом месте.
ck_
1
Тогда я знаю, что это единственный способ. Следите за производством, когда вы отсоединяете strace от процесса, убедитесь, что все продолжает работать после этого.
Доблесть
3
Еще немного покопавшись, я нашел похожий вопрос с некоторыми подробностями о том, почему это невозможно напрямую в stackoverflow stackoverflow.com/questions/8394613/…
ck_
80

Вы можете использовать socat.

sudo mv /path/to/sock /path/to/sock.original
sudo socat -t100 -x -v UNIX-LISTEN:/path/to/sock,mode=777,reuseaddr,fork UNIX-CONNECT:/path/to/sock.original

Что происходит выше: сначала переместите оригинальную розетку в sock.original. Socat создает новый сокет («UNIX-LISTEN») в месте расположения оригиналов и перенаправляет все в оригинал («UNIX-connect»). -V указывает socat также печатать вывод в STDERR.

storoj
источник
3
Хотите добавить немного больше объяснений?
Казарк
4
Это легко, когда исходный сокет unix имеет путь к файловой системе. но что, если это абстрактный сокет пространства имен Unix, который вы не можете переместить?
Валерио Скьявони,
6

Вы также можете попробовать использовать strace в одном из процессов по обе стороны сокета, так как это позволит вам наблюдать за тем, что пишется / читается. Я обнаружил в своей производственной среде, у меня нет socat, но есть strace.

Для любой полезной цели установка -s на что-то большое является обязательным.

omnigrok
источник
Это сработало хорошо для меня, и легко сделать. Используйте strace -p <pid>для просмотра запущенного процесса.
Мэтт Мансон
Быстрая команда: strace -s9999 -f $(for i in $( pidof php5-fpm ) ; do echo -n " -p $i "; done ) 2>&1 | tee /tmp/php.logа затем запустите тесты. У вас есть /tmp/php.log, чтобы медленно проверять, не слишком ли большой журнал. Если вы получаете слишком большой трафик, сделайте запрос со строкой запроса с вашим именем или чем-то таким, чтобы вы могли искать его в журналах
higuita
1
@higuita Я знаю, что это было давно, но вместо этого цикла вы можете позволить printfповторяться. printf " -p %s" $(pidof php5-fpm)префикс каждого аргумента pid -pи гораздо более практичный для написания.
JoL
2
// backup the socket
sudo mv /var/run/docker.sock /var/run/docker.sock.original

// use tcp port 8089 proxy the original socket
sudo socat TCP-LISTEN:8089,reuseaddr,fork UNIX-CONNECT:/var/run/docker.sock.original

// use the new socket to proxy the 8089 port
sudo socat UNIX-LISTEN:/var/run/docker.sock,fork TCP-CONNECT:127.0.0.1:8089

тогда:

sudo tcpdump -i lo -netvv port 8089
任喜军
источник
1
Эль Магнифеко! Спасибо
typelogic