Como encontrar outra extremidade da conexão de soquete unix?

44

Eu tenho um processo (dbus-daemon) que possui muitas conexões abertas nos soquetes UNIX. Uma dessas conexões é 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

Com base em conexões numéricas, presumo que o dbus-daemon seja realmente servidor. O que é bom. Mas como posso encontrar qual processo está conectado a ele - usando a conexão que é a 36ª manipulação de arquivos no dbus-launcher? Tentei lsof e até mesmo greps em / proc / net / unix, mas não consigo descobrir uma maneira de encontrar o processo do cliente.


fonte
Isso é respondido no U&L: Quem tem o outro lado desse soquete unix?
sch 12/10

Respostas:

25

Recentemente, me deparei com um problema semelhante. Fiquei chocado ao descobrir que há casos em que isso pode não ser possível. Eu descobri um comentário do criador de lsof (Vic Abell), onde ele apontou que isso depende muito da implementação do soquete unix. Às vezes, as informações "endpoint" para soquete estão disponíveis e outras não. Infelizmente, é impossível no Linux, como ele aponta.

No Linux, por exemplo, onde lsof deve usar / proc / net / unix, todos os soquetes de domínio UNIX têm um caminho vinculado, mas nenhuma informação de terminal. Freqüentemente não há caminho vinculado. Isso geralmente torna impossível determinar o outro terminal, mas é o resultado da implementação do sistema de arquivos Linux / proc.

Se você olhar para / proc / net / unix, poderá ver por si mesmo que (pelo menos no meu sistema) ele está absolutamente certo. Ainda estou chocado, porque acho esse recurso essencial ao rastrear problemas no servidor.

Jacek Prucia
fonte
Observe que /proc/net/unixo arquivo de destino de uma referência de soquete de domínio aleatório foi extraído /proc/.../fd/.
I336_
27

Esta resposta é apenas para Linux. Com base em uma resposta do Unix e Linux Stack Exchange, identifiquei com êxito a outra extremidade de um soquete de domínio unix usando estruturas de dados no kernel, acessadas usando gdbe /proc/kcore. Você precisa habilitar as opções CONFIG_DEBUG_INFOe do CONFIG_PROC_KCOREkernel.

Você pode usar lsofpara obter o endereço do kernel do soquete, que assume a forma de um ponteiro, por exemplo 0xffff8803e256d9c0. Esse número é realmente o endereço da estrutura ou tipo de memória relevante no kernel struct unix_sock. Essa estrutura tem um campo chamado peerque aponta na outra extremidade do soquete. Então os comandos

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

imprimirá o endereço da outra extremidade da conexão. Você pode receber a saída lsof -Udesse número para identificar o número do processo e do descritor de arquivo dessa outra extremidade.

Algumas distribuições parecem fornecer símbolos de depuração do kernel como um pacote separado, que substituirá o vmlinuxarquivo no comando acima.

MvG
fonte
Parece interessante, mas o requisito de recompilar o kernel parece ser um exagero. Estou pensando que talvez fosse possível fazê-lo, sem o kernel feito à mão e sem usar o gdb, apenas espiando os valores no kcore e fazendo uma decodificação "manual" dos valores.
3
@depesz, tudo que você precisa saber é o deslocamento do peermembro na unix_sockestrutura. No meu sistema x86_64, esse deslocamento é de 656 bytes, para que eu pudesse obter essa outra extremidade usando p ((void**)0xffff8803e256d9c0)[0x52]. Você ainda precisa CONFIG_PROC_KCORE, obviamente.
MvG 02/09/12
12

Na verdade, ssde iproute2(substituição de netstat, ifconfig, etc.) pode mostrar essas informações.

Aqui está um exemplo mostrando um soquete de domínio ssh-agent unix ao qual um sshprocesso se conectou:

$ 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))
Zulakis
fonte
Hmm. Interessante ... Percebi que as colunas "Address: Port" podem ser correspondidas, mesmo que a coluna "Peer" seja totalmente inútil para soquetes de domínio unix.
SamB 26/10/16
9

Soquetes Unix geralmente recebem números em pares e geralmente são consecutivos. Portanto, o par para você provavelmente seria 1013410 +/- 1. Veja qual desses dois existe e adivinhe o culpado.

Devdas
fonte
8

Eu escrevi uma ferramenta que usa o método gdb do MvG para obter informações confiáveis ​​de pares de soquetes, não são necessários símbolos de depuração do kernel.

Para conectar o processo a um determinado soquete, passe o número do inode:

# socket_peer 1013410
3703 thunderbird 

Para descobrir todos os processos de uma só vez netstat_unix, ele adiciona uma coluna à saída do 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       
...

Tente netstat_unix --dumpse você precisar de uma saída fácil de analisar.
Consulte https://github.com/lemonsqueeze/unix_sockets_peers para obter detalhes.

Para informações, o inode + 1 / -1 hack não é confiável. Funciona na maioria das vezes, mas falha ou (pior) retorna o soquete errado se você não tiver sorte.

limões
fonte
1

Edite seu system.conf

Nesse arquivo, você pode adicionar mais itens para fins de depuração.

Localização de arquivo: /etc/dbus-1/system.conf

Para fins de depuração, você pode editar o system.conf para permitir a interceptação:

  1. substitua a seção de política por:

    <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. Remova a linha incluída: system.d

    <includedir>system.d</includedir>

Fonte: http://old.nabble.com/dbus-send-error-td29893862.html


Algumas outras coisas úteis sobre soquetes unix

A maneira mais simples de descobrir o que está acontecendo no barramento é executar o dbus-monitorprograma, que vem com o pacote D-Bus

Além disso, você pode tentar usar dbus-cleanup-socketspara limpar os soquetes restantes.

O comando a seguir mostrará qual processo está conectado quantas vezes aos soquetes do dbus com base na netstatsaída:

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

(testado no Ubuntu)

Maneira hardcore: Este comando encontrará manualmente os processos de / proc e mostrará quais estão usando mais conexões (todos os tipos de soquetes):

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")}'

Exemplo de saída:

(contagem, PID e a próxima linha contém detalhes sobre o processo)

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

(testado no Ubuntu)

Diverta-se.


Consulte também artigos relacionados para a referência:

kenorb
fonte