web-dev-qa-db-ja.com

UNIXソケット接続のもう一方の端を見つける方法は?

UNIXソケットを介して多くのオープン接続があるプロセス(dbus-daemon)があります。これらの接続の1つは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

接続数に基づいて、私はdbus-daemonが実際にサーバーであると想定しています。大丈夫です。しかし、どのようにしてそれに接続されているプロセスを見つけることができますか-dbus-launcherの36番目のファイルハンドルである接続を使用して?/proc/net/unixでlsofやgrepsを試しましたが、クライアントプロセスを見つける方法がわかりません。

44
user13185

かなり最近になって、同様の問題に遭遇しました。これが不可能な場合があることを知ってショックを受けました。私はlsof(Vic Abell)の作成者からのコメントを掘り起こしましたが、彼はこれがUNIXソケットの実装に大きく依存していると指摘しました。ソケットのいわゆる「エンドポイント」情報が利用できる場合と利用できない場合があります。彼が指摘するように、残念ながらLinuxではそれは不可能です。

たとえばLinuxでは、lsofが/ proc/net/unixを使用する必要がある場合、すべてのUNIXドメインソケットにはバインドされたパスがありますが、エンドポイント情報はありません。多くの場合、バインドされたパスはありません。それはしばしば他のエンドポイントを決定することを不可能にしますが、それはLinux/procファイルシステムの実装の結果です。

/ proc/net/unixを見ると、自分の目で確認できます(少なくとも私のシステムでは)彼は完全に正しいです。サーバーの問題を追跡する際にそのような機能が不可欠であると思ったので、私はまだショックを受けています。

25
Jacek Prucia

この回答はLinux専用です。 回答 に基づいて、Unix&Linux Stack Exchangeから、私は 正常に識別されました カーネル内データ構造を使用してUNIXドメインソケットのもう一方の端にアクセスし、gdbおよび/proc/kcoreCONFIG_DEBUG_INFOおよびCONFIG_PROC_KCOREカーネルオプションを有効にする必要があります。

lsofを使用して、ソケットのカーネルアドレスを取得できます。これは、ポインタの形式をとります。 0xffff8803e256d9c0。その番号は、実際には関連するカーネル内メモリ構造のアドレスまたはタイプstruct unix_sockです。その構造には、ソケットの反対側を指すpeerというフィールドがあります。したがって、コマンド

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

接続のもう一方の端のアドレスを出力します。その番号のlsof -Uの出力をgrepして、その反対側のプロセスとファイル記述子の番号を特定できます。

一部のディストリビューションは、上記のコマンドのvmlinuxファイルの代わりとなる個別のパッケージとしてカーネルデバッグシンボルを提供しているようです。

27
MvG

実際、iproute2ss(netstat、ifconfigなどの置換)はこの情報を表示できます。

以下は、sshプロセスが接続しているssh-agent unixドメインソケットの例です。

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

Unixソケット通常はペアで番号が割り当てられ、通常は連続しています。したがって、あなたのペアはおそらく1013410 +/- 1になります。これら2つのうちどちらが存在するかを確認し、原因を推測してください。

10
Devdas

私はMvGの gdbメソッド を使用してソケットピア情報を確実に取得する tool を記述しました。カーネルデバッグシンボルは不要です。

プロセスを特定のソケットに接続するには、それにiノード番号を渡します。

# socket_peer 1013410
3703 Thunderbird 

netstat_unixを使用してすべてのプロセスを一度に確認するには、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       
...

解析しやすい出力が必要な場合は、netstat_unix --dumpを試してください。
詳細は https://github.com/lemonsqueeze/unix_sockets_peers を参照してください。

参考までに、 inode + 1/-1 hack は信頼できません。ほとんどの場合は機能しますが、うまくいかない場合は失敗するか、(さらに悪い)間違ったソケットを返します。

8
lemonsqueeze

System.confを編集します

このファイルでは、デバッグ目的でさらに多くのものを追加できます。

ファイルの場所:/etc/dbus-1/system.conf

デバッグの目的で、盗聴を許可するようにsystem.confを編集できます。

  1. ポリシーセクションを次のように置き換えます。

    <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. 含まれている行を削除:system.d

    <includedir>system.d</includedir>

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


UNIXソケットに関するその他の有用なもの

バスで何が起こっているかを理解する最も簡単な方法は、dbus-monitorプログラム、D-Busパッケージに付属

また、dbus-cleanup-sockets残りのソケットをクリーンアップします。

次のコマンドは、netstat出力に基づいて、どのプロセスがdbusソケットに何回接続されているかを示します。

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

(Ubuntuでテスト済み)

ハードコアな方法:このコマンドは手動で/ procからプロセスを見つけ、最も多くの接続(すべてのタイプのソケット)を使用しているプロセスを示します。

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

出力例:

(カウント、PID、次の行にはプロセスの詳細が含まれています)

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

(Ubuntuでテスト済み)

楽しんで。


リファレンスについては、関連記事もご覧ください。

1
kenorb