Bagaimana menemukan ujung sambungan soket unix lainnya?

44

Saya memiliki proses (dbus-daemon) yang memiliki banyak koneksi terbuka melalui soket UNIX. Salah satu koneksi ini adalah 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

Berdasarkan koneksi angka, saya berasumsi bahwa dbus-daemon sebenarnya adalah server. Tidak apa-apa. Tapi bagaimana saya bisa menemukan proses mana yang terhubung dengannya - menggunakan koneksi yang menangani file ke-36 di dbus-launcher? Mencoba lsof dan bahkan greps di / proc / net / unix tapi saya tidak tahu cara untuk menemukan proses klien.


sumber

Jawaban:

25

Baru-baru ini saya menemukan masalah yang sama. Saya terkejut mengetahui bahwa ada kasus-kasus di mana hal ini tidak mungkin dilakukan. Saya menggali komentar dari pencipta lsof (Vic Abell) di mana ia menunjukkan bahwa ini sangat tergantung pada implementasi soket unix. Kadang-kadang apa yang disebut "titik akhir" informasi untuk soket tersedia dan kadang tidak. Sayangnya tidak mungkin di Linux seperti yang dia tunjukkan.

Di Linux, misalnya, di mana lsof harus menggunakan / proc / net / unix, semua soket domain UNIX memiliki jalur terikat, tetapi tidak ada informasi titik akhir. Seringkali tidak ada jalan terikat. Itu sering membuat tidak mungkin untuk menentukan titik akhir lainnya, tetapi itu adalah hasil dari implementasi sistem file Linux / proc.

Jika Anda melihat / proc / net / unix Anda dapat melihat sendiri, bahwa (setidaknya pada sistem saya) ia benar sekali. Saya masih terkejut, karena saya menemukan fitur seperti itu penting ketika melacak masalah server.

Jacek Prucia
sumber
Perhatikan bahwa /proc/net/unixAKAN memberi tahu Anda file target referensi soket domain acak yang telah Anda gali /proc/.../fd/.
i336_
27

Jawaban ini hanya untuk Linux. Berdasarkan jawaban dari Unix & Linux Stack Exchange, saya berhasil mengidentifikasi ujung lain dari soket domain unix menggunakan struktur data in-kernel, diakses menggunakan gdbdan /proc/kcore. Anda perlu mengaktifkan opsi CONFIG_DEBUG_INFOdan CONFIG_PROC_KCOREkernel.

Anda dapat menggunakan lsofuntuk mendapatkan alamat kernel dari soket, yang berbentuk pointer, misalnya 0xffff8803e256d9c0. Angka itu sebenarnya alamat dari struktur atau tipe memori dalam-kernel yang relevan struct unix_sock. Struktur itu memiliki bidang yang disebut peertitik di ujung soket yang lain. Jadi perintahnya

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

akan mencetak alamat ujung koneksi yang lain. Anda dapat menangkap output lsof -Uuntuk nomor itu untuk mengidentifikasi proses dan mengajukan nomor deskripsi dari ujung yang lain.

Beberapa distribusi tampaknya menyediakan simbol debug kernel sebagai paket terpisah, yang akan menggantikan vmlinuxfile dalam perintah di atas.

MvG
sumber
Ini terlihat menarik, tetapi persyaratan untuk mengkompilasi ulang kernel tampaknya merupakan kerja keras. Saya berpikir bahwa mungkin mungkin untuk melakukannya, tanpa kernel buatan tangan, dan tanpa menggunakan gdb, hanya dengan mengintip nilai-nilai dalam kcore dan melakukan beberapa decoding nilai "manual".
3
@depesz, yang perlu Anda ketahui adalah offset peeranggota dalam unix_sockstruktur. Pada sistem x86_64 saya, offset itu adalah 656 byte, jadi saya bisa mendapatkan yang lain menggunakan p ((void**)0xffff8803e256d9c0)[0x52]. Anda masih membutuhkan CONFIG_PROC_KCORE, jelas.
MvG
12

Sebenarnya, ssdari iproute2(pengganti netstat, ifconfig, dll.) Dapat menampilkan informasi ini.

Berikut adalah contoh yang menunjukkan soket domain unix ssh-agent yang sshterhubung dengan proses:

$ 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
sumber
Hmm. Menarik ... Saya telah melewatkan bahwa kolom "Alamat: Port" dapat dicocokkan, meskipun kolom "Peer" sama sekali tidak berguna untuk soket domain unix.
SamB
9

Soket Unix biasanya diberi nomor berpasangan, dan biasanya berturut-turut. Jadi pasangan untuk Anda kemungkinan akan menjadi 1013410 +/- 1. Lihat yang mana dari dua itu yang ada dan tebak pelakunya.

Devdas
sumber
8

Saya menulis sebuah alat yang menggunakan metode gvb MvG untuk mendapatkan informasi socket peer dengan andal, simbol debug kernel tidak diperlukan.

Untuk menghubungkan proses ke soket yang diberikan, berikan nomor inode:

# socket_peer 1013410
3703 thunderbird 

Untuk mengetahui semua proses sekaligus digunakan netstat_unix, itu menambahkan kolom ke output 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       
...

Coba netstat_unix --dumpjika Anda membutuhkan output yang mudah diurai.
Lihat https://github.com/lemonsqueeze/unix_sockets_peers untuk detailnya.

Sebagai info, inode + 1 / -1 hack tidak dapat diandalkan. Ini berfungsi sebagian besar waktu tetapi akan gagal atau (lebih buruk) mengembalikan soket yang salah jika Anda kurang beruntung.

perasan lemon
sumber
1

Edit system.conf Anda

Dalam file ini Anda bisa menambahkan lebih banyak barang untuk tujuan debugging.

Lokasi file: /etc/dbus-1/system.conf

Untuk tujuan debugging, Anda dapat mengedit system.conf Anda untuk mengizinkan penyadapan:

  1. ganti bagian kebijakan dengan:

    <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. Hapus baris yang disertakan: system.d

    <includedir>system.d</includedir>

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


Beberapa hal bermanfaat lainnya tentang soket unix

Cara paling sederhana untuk mengetahui apa yang terjadi di bus adalah dengan menjalankan dbus-monitorprogram, yang datang dengan paket D-Bus

Anda juga dapat mencoba menggunakan dbus-cleanup-socketsuntuk membersihkan soket sisa.

Perintah berikut akan menunjukkan kepada Anda proses mana yang terhubung berapa kali ke soket dbus berdasarkan netstatoutput:

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

(diuji pada Ubuntu)

Cara hardcore: Perintah ini akan menemukan secara manual proses dari / proc dan menunjukkan yang menggunakan sebagian besar koneksi (semua jenis soket):

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

Contoh output:

(hitung, PID dan baris berikutnya berisi detail tentang proses)

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

(diuji pada Ubuntu)

Selamat bersenang-senang.


Lihat juga artikel terkait untuk referensi:

kenorb
sumber