GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie finde ich das andere Ende der Unix-Socket-Verbindung?

Lösung 1:

Diese Antwort gilt nur für Linux.

Update für Linux 3.3: Wie Zulakis in einer separaten Antwort schrieb (+1 that), können Sie ss von iproute2 verwenden, um ein Paar Inode-Nummern für jede Socket-Verbindung zu erhalten, die das lokale Ende und den Peer identifizieren. Dies scheint auf der gleichen Maschinerie wie sock_diag(7) mit dem UNIX_DIAG_PEER zu basieren Attribut, das den Peer identifiziert. Eine Antwort von Totor drüben bei Unix &Linux Stack Exchange verlinkt auf die relevanten Commits in Kernel und iproute2 und erwähnt auch die Notwendigkeit des UNIX_DIAG Kernel-Konfigurationseinstellung.

Originalantwort für Linux vor 3.3 folgt.

Basierend auf einer Antwort von Unix &Linux Stack Exchange habe ich erfolgreich das andere Ende eines Unix-Domain-Sockets mithilfe von In-Kernel-Datenstrukturen identifiziert, auf die mit gdb zugegriffen wird und /proc/kcore . Sie müssen den CONFIG_DEBUG_INFO aktivieren und CONFIG_PROC_KCORE Kernel-Optionen.

Sie können lsof verwenden um die Kernel-Adresse des Sockets zu erhalten, die die Form eines Zeigers hat, z. 0xffff8803e256d9c0 . Diese Nummer ist eigentlich die Adresse der relevanten In-Kernel-Speicherstruktur oder Typ struct unix_sock . Diese Struktur hat ein Feld namens peer die auf das andere Ende der Buchse zeigt. Also die Befehle

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

druckt die Adresse des anderen Endes der Verbindung. Sie können die Ausgabe von lsof -U abrufen für diese Nummer, um den Prozess und die Dateideskriptornummer dieses anderen Endes zu identifizieren.

Einige Distributionen scheinen Kernel-Debug-Symbole als separates Paket bereitzustellen, das den Platz von vmlinux einnehmen würde Datei im obigen Befehl.

Lösung 2:

Vor kurzem bin ich auf ein ähnliches Problem gestoßen. Ich war schockiert, als ich herausfand, dass es Fälle gibt, in denen dies möglicherweise nicht möglich ist. Ich habe einen Kommentar des Schöpfers von lsof (Vic Abell) ausgegraben, in dem er darauf hinwies, dass dies stark von der Unix-Socket-Implementierung abhängt. Manchmal sind sogenannte „Endpoint“-Informationen für Sockets verfügbar und manchmal nicht. Leider ist es unter Linux unmöglich, wie er betont.

Unter Linux zum Beispiel, wo lsof /proc/net/unix verwenden muss, haben alle UNIX-Domänen-Sockets einen gebundenen Pfad, aber keine Endpunktinformationen. Oft gibt es keinen gebundenen Weg. Das macht es oft unmöglich, den anderen Endpunkt zu bestimmen, aber es ist ein Ergebnis der Implementierung des Linux /proc-Dateisystems.

Wenn Sie sich /proc/net/unix ansehen, können Sie selbst sehen, dass er (zumindest auf meinem System) absolut Recht hat. Ich bin immer noch schockiert, weil ich solche Funktionen für die Verfolgung von Serverproblemen unerlässlich finde.

Lösung 3:

Eigentlich ss ab iproute2 (Ersatz für netstat, ifconfig, etc.) kann diese Informationen anzeigen.

Hier ist ein Beispiel, das einen ssh-Agent-Unix-Domain-Socket zeigt, an den ein ssh Prozess hat verbunden:

$ 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))

Lösung 4:

Unix-Sockets normalerweise werden paarweise mit Nummern versehen und sind in der Regel fortlaufend. Das Paar für Sie wäre also wahrscheinlich 1013410+/-1. Finden Sie heraus, welche der beiden existiert, und raten Sie auf den Übeltäter.

Lösung 5:

Ich habe ein Tool geschrieben, das die gdb-Methode von MvG verwendet, um Socket-Peer-Informationen zuverlässig zu erhalten, Kernel-Debug-Symbole werden nicht benötigt.

Um den Prozess mit einem bestimmten Socket zu verbinden, übergeben Sie ihm die Inode-Nummer:

# socket_peer 1013410
3703 thunderbird 

Um dies für alle Prozesse auf einmal herauszufinden, verwenden Sie netstat_unix , fügt es der Ausgabe von netstat eine Spalte hinzu:

# 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       
...

Versuchen Sie es mit netstat_unix --dump Wenn Sie eine Ausgabe benötigen, die einfach zu analysieren ist.
Siehe https://github.com/lemonsqueeze/unix_sockets_peers für Details.

Zur Info, der Inode +1/-1 Hack ist nicht zuverlässig. Es funktioniert die meiste Zeit, wird aber fehlschlagen oder (noch schlimmer) den falschen Socket zurückgeben, wenn Sie Pech haben.


Linux
  1. So finden und löschen Sie leere Verzeichnisse und Dateien in Unix

  2. Wie finde ich das Home-Verzeichnis eines Benutzers unter Linux oder Unix?

  3. So finden Sie die Socket-Puffergröße von Linux

  4. Wie entferne ich eine CLOSE_WAIT-Socket-Verbindung?

  5. Finden Sie heraus, welcher Prozess sich am anderen Ende einer Pipe befindet

So finden Sie Dateien unter Linux

So finden Sie heraus, ob ein Paket unter Linux und Unix installiert ist oder nicht

So finden Sie die IP-Adresse unter Linux

So finden Sie den Hostnamen unter Linux

So wechseln Sie PHP-FPM Listen auf Unix Socket

So finden Sie Dateien in Debian