このUnixソケットペアのもう一方の端は誰ですか?


54

UNIXソケットのもう一方の端があるプロセスを判別したい。

具体的には、で作成されたものについて尋ねてsocketpair()いますが、問題はどのUNIXソケットでも同じです。

、およびparentを作成するプログラムがあります。親プロセスは閉じて、通信を続けます。子供は反対のことをします。次に、子は別のプログラムを実行します。2人は、このソケットペアを介して相互に通信できます。socketpair(AF_UNIX, SOCK_STREAM, 0, fds)fork()fds[1]fds[0]close(fds[0]); s=fds[1]exec()child1

さて、私は誰parentが知っているとしましょうが、私は誰が誰かを知りたいと思いchild1ます。どうすればいいですか?

私が自由に使えるツールはいくつかありますが、どのプロセスがソケットの反対側にあるのかを知ることはできません。私が試してみました:

  • lsof -c progname
  • lsof -c parent -c child1
  • ls -l /proc/$(pidof server)/fd
  • cat /proc/net/unix

基本的に、2つのソケットとそれらに関するすべてを見ることができますが、それらが接続されていることはわかりません。親のどのFDがどの子プロセスと通信しているかを判断しようとしています。

回答:


27

カーネル3.3以降では、ssまたはlsof-4.89それ以上を使用できます—StéphaneChazelasの回答を参照してください。

の著者によると、古いバージョンでlsofはこれを見つけることは不可能でした。Linuxカーネルはこの情報を公開していません。出典:comp.unix.adminの2003スレッド

に表示される/proc/$pid/fd/$fd番号は、仮想ソケットファイルシステム内のソケットのiノード番号です。パイプまたはソケットのペアを作成すると、各端はiノード番号を連続して受け取ります。番号は順番に割り当てられるため、番号が1ずつ異なる可能性が高くなりますが、これは保証されません(最初のソケットがNでN +1がラッピングのために既に使用されているか、他のスレッドが2つのiノード割り当ての間でスケジュールされ、そのスレッドもいくつかのiノードを作成しました)。

カーネル2.6.39の定義socketpairを確認しましたが、ソケットの両端は、タイプ固有のsocketpairメソッドを除いて相関していません。UNIXソケットの場合、それunix_socketpairはにありnet/unix/af_unix.cます。


2
@Gilllesに感謝します。私はそのことについてしばらく前に読んだことを思い出しますが、再び見つけることができませんでした。/ proc / net / unixのパッチを書く必要があるかもしれません。
ジョナサンラインハート

そして、はい、増加するiノード数でその観察を行いましたが、現在はそれを扱っています。ただし、あなたが述べたように、それは保証されていません。私が見ているプロセスには、少なくとも40の開いているUNIXソケットがあり、N + 1が当てはまらないインスタンスを見ました。残念。
ジョナサンラインハート

1
@JonathonReinhart の定義socketpairを確認しましが、ソケットの両端は、タイプ固有のsocketpairメソッドを除いて相関していません。UNIXソケットの場合、それunix_socketpairは `net / unix / af_unix.cにあります。パイプについてもこの情報があると便利です。
ジル 'SO-悪であるのをやめる'

36

lsofここで説明する両方のアプローチを組み合わせたラッパーを維持し、https://github.com/stephane-chazelas/misc-scripts/blob/master/lsofcでループバックTCP接続のピアの情報も追加します

Linux-3.3以降。

Linuxでは、カーネルバージョン3.3(およびUNIX_DIAG機能がカーネルに組み込まれている場合)以降、新しいnetlinkベースのAPI を使用して、特定のUNIXドメインソケット(ソケットペアを含む)のピアを取得できます。

lsof バージョン4.89がそのAPIを利用できるため:

lsof +E -aUc Xorg

次のXorgような形式で、いずれかの末尾で名前が始まるプロセスを持つすべてのUnixドメインソケットをリストします。

Xorg       2777       root   56u  unix 0xffff8802419a7c00      0t0   34036 @/tmp/.X11-unix/X0 type=STREAM ->INO=33273 4120,xterm,3u

のバージョンがlsof古すぎる場合は、さらにいくつかのオプションがあります。

ssユーティリティ(からはiproute2)ピア情報を含むシステム上のUNIXドメインソケットのリストについての情報を取得し、表示するために、その同じAPIを利用します。

ソケットは、iノード番号によって識別されます。ソケットファイルのファイルシステムのiノードとは関係がないことに注意してください。

例えば:

$ ss -x
[...]
u_str  ESTAB    0    0   @/tmp/.X11-unix/X0 3435997     * 3435996

ソケット3435997(それはABSTRACTソケットにバインドされていた/tmp/.X11-unix/X0)がソケット3435996に接続されていると-p言います。オプションは、どのプロセスがそのソケットを開いているかを伝えることができます。いくつかreadlinkのsを/proc/$pid/fd/*実行することでそれを行いますので、所有しているプロセスでのみ実行できます(を使用している場合を除くroot)。例えばここに:

$ sudo ss -xp
[...]
u_str  ESTAB  0  0  @/tmp/.X11-unix/X0 3435997 * 3435996 users:(("Xorg",pid=3080,fd=83))
[...]
$ sudo ls -l /proc/3080/fd/23
lrwx------ 1 root root 64 Mar 12 16:34 /proc/3080/fd/83 -> socket:[3435997]

3435996のプロセスを調べるには、次の出力で独自のエントリを検索できますss -xp

$ ss -xp | awk '$6 == 3435996'
u_str  ESTAB  0  0  * 3435996  * 3435997 users:(("xterm",pid=29215,fd=3))

このスクリプトをラッパーとして使用してlsof、関連する情報を簡単に表示することもできます。

#! /usr/bin/perl
# lsof wrapper to add peer information for unix domain socket.
# Needs Linux 3.3 or above and CONFIG_UNIX_DIAG enabled.

# retrieve peer and direction information from ss
my (%peer, %dir);
open SS, '-|', 'ss', '-nexa';
while (<SS>) {
  if (/\s(\d+)\s+\*\s+(\d+) ([<-]-[->])$/) {
    $peer{$1} = $2;
    $dir{$1} = $3;
  }
}
close SS;

# Now get info about processes tied to sockets using lsof
my (%fields, %proc);
open LSOF, '-|', 'lsof', '-nPUFpcfin';
while (<LSOF>) {
  if (/(.)(.*)/) {
    $fields{$1} = $2;
    if ($1 eq 'n') {
      $proc{$fields{i}}->{"$fields{c},$fields{p}" .
      ($fields{n} =~ m{^([@/].*?)( type=\w+)?$} ? ",$1" : "")} = "";
    }
  }
}
close LSOF;

# and finally process the lsof output
open LSOF, '-|', 'lsof', @ARGV;
while (<LSOF>) {
  chomp;
  if (/\sunix\s+\S+\s+\S+\s+(\d+)\s/) {
    my $peer = $peer{$1};
    if (defined($peer)) {
      $_ .= $peer ?
            " ${dir{$1}} $peer\[" . (join("|", keys%{$proc{$peer}})||"?") . "]" :
            "[LISTENING]";
    }
  }
  print "$_\n";
}
close LSOF or exit(1);

例えば:

$ sudo that-lsof-wrapper -ad3 -p 29215
コマンドPIDユーザーFDタイプデバイスサイズ/オフノード名
xterm 29215 stephane 3u unix 0xffff8800a07da4c0 0t0 3435996 type = STREAM <-> 3435997 [Xorg、3080、@ / tmp / .X11-unix / X0]

linux-3.3より前

UNIXソケット情報を取得する古いLinux APIは、/proc/net/unixテキストファイル経由です。すべてのUnixドメインソケット(ソケットペアを含む)をリストします。そこの最初のフィールド(kernel.kptr_restrictsysctlパラメーターで非スーパーユーザーに隠されていない場合)は、@ Totorによって既に説明さているように、対応するpeerを指すフィールドunix_sockを含む構造のカーネルアドレスを含みます。また、Unixソケットの列に出力するものでもあります。peer unix_socklsofDEVICE

現在、そのpeerフィールドの値を取得するということは、カーネルメモリを読み取っpeerて、unix_sockアドレスに関するそのフィールドのオフセットを知ることができることを意味します。

いくつかのgdbベースおよびsystemtapベースのソリューションがすでに提供されていますが、それらはインストールされている実行中のカーネルにgdb/ systemtapおよびLinuxカーネルデバッグシンボルを必要とします。

オフセットのハードコーディングは、カーネルバージョンによって異なるため、実際にはオプションではありません。

これで、オフセットの決定にヒューリスティックなアプローチを使用できます:ツールにダミーを作成させsocketpair(両方のピアのアドレスを知っている)、オフセットを決定するために相手側のメモリの周りのピアのアドレスを検索します。

以下は、まさにそれを使用する概念実証スクリプトですperl(i386ではカーネル2.4.27および2.6.32、amd64では3.13および3.16でテストが成功しました)。上記のように、それは周りのラッパーとして機能しますlsof

例えば:

$ that-lsof-wrapper -aUc nm-applet
コマンドPIDユーザーFDタイプデバイスサイズ/オフノード名
NM-アプレット4183ステファンの4U UNIX 0xffff8800a055eb40 0t0 36888タイプ= STREAM - > 0xffff8800a055e7c0 [DBUSデーモン、4190、@ / TMP / DBUS-AiBCXOnuP6] 
NM-アプレット4183ステファンの7U UNIX 0xffff8800a055e440 0t0 36890タイプ= STREAM - > 0xffff8800a055e0c0 [Xorgの、 3080、@ / tmp / .X11-unix / X0] 
nm-applet 4183 stephane 8u unix 0xffff8800a05c1040 0t0 36201 type = STREAM-> 0xffff8800a05c13c0 [dbus-daemon、4118、@ / tmp / dbus-yxxNr1NkYC] 
nm-applet 4183 unix 0xffff8800a055d080 0t0 36219 type = STREAM- > 0xffff8800a055d400 [dbus-daemon、4118、@ / tmp / dbus-yxxNr1NkYC] 
nm-applet 4183 stephane 12u unix 0xffff88022e0df036268type = STREAM > / run / dbus / system_bus_socket]
nm-applet 4183 stephane 13u unix 0xffff88022e0f80c0 0t0 37025 type = STREAM-> 0xffff88022e29ec00 [dbus-daemon、2268、/ var / run / dbus / system_bus_socket]

スクリプトは次のとおりです。

#! /usr/bin/perl
# wrapper around lsof to add peer information for Unix
# domain sockets. needs lsof, and superuser privileges.
# Copyright Stephane Chazelas 2015, public domain.
# example: sudo this-lsof-wrapper -aUc Xorg
use Socket;

open K, "<", "/proc/kcore" or die "open kcore: $!";
read K, $h, 8192 # should be more than enough
 or die "read kcore: $!";

# parse ELF header
my ($t,$o,$n) = unpack("x4Cx[C19L!]L!x[L!C8]S", $h);
$t = $t == 1 ? "L3x4Lx12" : "Lx4QQx8Qx16"; # program header ELF32 or ELF64
my @headers = unpack("x$o($t)$n",$h);

# read data from kcore at given address (obtaining file offset from ELF
# @headers)
sub readaddr {
  my @h = @headers;
  my ($addr, $length) = @_;
  my $offset;
  while (my ($t, $o, $v, $s) = splice @h, 0, 4) {
    if ($addr >= $v && $addr < $v + $s) {
      $offset = $o + $addr - $v;
      if ($addr + $length - $v > $s) {
        $length = $s - ($addr - $v);
      }
      last;
    }
  }
  return undef unless defined($offset);
  seek K, $offset, 0 or die "seek kcore: $!";
  my $ret;
  read K, $ret, $length or die "read($length) kcore \@$offset: $!";
  return $ret;
}

# create a dummy socketpair to try find the offset in the
# kernel structure
socketpair(Rdr, Wtr, AF_UNIX, SOCK_STREAM, PF_UNSPEC)
 or die "socketpair: $!";
$r = readlink("/proc/self/fd/" . fileno(Rdr)) or die "readlink Rdr: $!";
$r =~ /\[(\d+)/; $r = $1;
$w = readlink("/proc/self/fd/" . fileno(Wtr)) or die "readlink Wtr: $!";
$w =~ /\[(\d+)/; $w = $1;
# now $r and $w contain the socket inodes of both ends of the socketpair
die "Can't determine peer offset" unless $r && $w;

# get the inode->address mapping
open U, "<", "/proc/net/unix" or die "open unix: $!";
while (<U>) {
  if (/^([0-9a-f]+):(?:\s+\S+){5}\s+(\d+)/) {
    $addr{$2} = hex $1;
  }
}
close U;

die "Can't determine peer offset" unless $addr{$r} && $addr{$w};

# read 2048 bytes starting at the address of Rdr and hope to find
# the address of Wtr referenced somewhere in there.
$around = readaddr $addr{$r}, 2048;
my $offset = 0;
my $ptr_size = length(pack("L!",0));
my $found;
for (unpack("L!*", $around)) {
  if ($_ == $addr{$w}) {
    $found = 1;
    last;
  }
  $offset += $ptr_size;
}
die "Can't determine peer offset" unless $found;

my %peer;
# now retrieve peer for each socket
for my $inode (keys %addr) {
  $peer{$addr{$inode}} = unpack("L!", readaddr($addr{$inode}+$offset,$ptr_size));
}
close K;

# Now get info about processes tied to sockets using lsof
my (%fields, %proc);
open LSOF, '-|', 'lsof', '-nPUFpcfdn';
while (<LSOF>) {
  if (/(.)(.*)/) {
    $fields{$1} = $2;
    if ($1 eq 'n') {
      $proc{hex($fields{d})}->{"$fields{c},$fields{p}" .
      ($fields{n} =~ m{^([@/].*?)( type=\w+)?$} ? ",$1" : "")} = "";
    }
  }
}
close LSOF;

# and finally process the lsof output
open LSOF, '-|', 'lsof', @ARGV;
while (<LSOF>) {
  chomp;
  for my $addr (/0x[0-9a-f]+/g) {
    $addr = hex $addr;
    my $peer = $peer{$addr};
    if (defined($peer)) {
      $_ .= $peer ?
            sprintf(" -> 0x%x[", $peer) . join("|", keys%{$proc{$peer}}) . "]" :
            "[LISTENING]";
      last;
    }
  }
  print "$_\n";
}
close LSOF or exit(1);

1
@mikeserv、それはそのコメントのフォローアップです。UNIXソケットのもう一方の端を見つけることができないことは、常に私を悩ませています(多くの場合、Xクライアントを見つけようとして、それについての最近の質問がありまし)。同様のアプローチを疑似端末に使用できるかどうかを確認し、作成lsof者に提案します。
ステファンシャゼル

1
カーネル自体がこれを提供していないとはまだ信じられません!パッチがまだ存在しない理由を発見する以外に、本当にパッチを提出する必要があります。
ジョナサンラインハート

1
これをしssませんか?それは私の頭の上にありss -pxますが、次のようなピア情報を持つ多くのUNIXソケットをリストします:users: ("nacl_helper",pid=18992,fd=6),("chrome",pid=18987,fd=6),("chrome",pid=18975,fd=5)) u_str ESTAB\t0\t0\t/run/dbus/system_bus_socket 8760\t\t* 15068列見出しはState\tRecv-Q\tSend-Q\tLocal Address:Port\tPeer Address:Port
...-mikeserv

1
また、もし私lsof -c terminologyが見るterminolo 12731\tmikeserv\t12u\tunix\t0xffff880600e82680\t0t0\t1312426\ttype=STREAMならば、私は見ることができますが、もし私が得ればss -px | grep terminologyu_str\tESTAB\t0\t0\t* 1312426\t*1315046\tusers:(("terminology",pid=12731,fd=12))
mikeserv

1
@mikeserv、確かにそうです!...私は最近、多くの時間を無駄にしてきたようだ
ステファンChazelas


8

カーネル3.3以降

あなたは可能 になりましたし、この情報を取得しますss

# ss -xp

これで、Peer列内の別のIDに対応するID(inode番号)がLocal列に表示されます。一致するIDは、ソケットの両端です。

注:このUNIX_DIAGオプションは、カーネルで有効にする必要があります。

カーネル3.3より前

Linuxはこの情報をユーザーランドに公開しませんでした。

ただし、カーネルメモリを調べると、この情報にアクセスできます。

注:この回答はを使用して行われますが、@StéphaneChazelasの回答gdbご覧ください。

# lsof | grep whatever
mysqld 14450 (...) unix 0xffff8801011e8280 (...) /var/run/mysqld/mysqld.sock
mysqld 14450 (...) unix 0xffff8801011e9600 (...) /var/run/mysqld/mysqld.sock

2つの異なるソケットがあり、1つはリッスンし、1つは確立されています。16進数は、対応するカーネルunix_sock構造体へのアドレスであり、peer属性はソケットのもう一方の端unix_sock構造体インスタンス)のアドレスです。

カーネルメモリ内のgdb検索に使用できますpeer

# gdb /usr/lib/debug/boot/vmlinux-3.2.0-4-amd64 /proc/kcore
(gdb) print ((struct unix_sock*)0xffff8801011e9600)->peer
$1 = (struct sock *) 0xffff880171f078c0

# lsof | grep 0xffff880171f078c0
mysql 14815 (...) unix 0xffff880171f078c0 (...) socket

ソケットのもう一方の端はmysql、PID 14815 によって保持されています。

KCORE_ELFを使用するには、カーネルをコンパイルする必要があります/proc/kcore。また、デバッグシンボルを含むカーネルイメージのバージョンが必要です。Debian 7では、apt-get install linux-image-3.2.0-4-amd64-dbgこのファイルが提供されます。

デバッグ可能なカーネルイメージは必要ありません...

システム上にデバッグカーネルイメージがない(または保持したくない)gdb場合、peer値に「手動で」アクセスするためのメモリオフセットを与えることができます。このオフセット値は通常、カーネルのバージョンまたはアーキテクチャによって異なります。

私のカーネルでは、オフセットが680バイト、つまり64ビットの85倍であることを知っています。だから私はできる:

# gdb /boot/vmlinux-3.2.0-4-amd64 /proc/kcore
(gdb) print ((void**)0xffff8801011e9600)[85]
$1 = (void *) 0xffff880171f078c0

Voilà、上記と同じ結果。

同じカーネルを複数のマシンで実行している場合、デバッグイメージは必要なく、オフセット値のみが必要なので、このバリアントを使用する方が簡単です。

最初に(簡単に)このオフセット値を検出するには、デバッグイメージが必要です。

$ pahole -C unix_sock /usr/lib/debug/boot/vmlinux-3.2.0-4-amd64
struct unix_sock {
  (...)
  struct sock *              peer;                 /*   680     8 */
  (...)
}

680バイト、これは85 x 64ビット、または170 x 32ビットです。

この答えの大部分はMvGに当てられます。


2
オフセットを取得する別のアプローチは、ソケットペアを作成し、/ proc / pif / fd / *のreadlinkからのiノード番号に基づいて/ proc / net / unixの対応するエントリを特定し、1つのソケットのアドレスの周りのメモリをスキャンすることです他のアドレス。これにより、lsof自体で実装できる合理的な移植性(Linuxのバージョンとアーキテクチャ間)を実現できます。PoCを考えてみます。
ステファンシャゼル

2
私は今、私がテストしたシステムでうまく動作するように見えるようなPoCを追加しました。
ステファンシャゼル

5

このソリューションは機能しますが、最近の十分なシステムタップがある場合、ssベースの アプローチを使用できる最近の十分なカーネルがあり、古いカーネルを使用している場合は、他の解決策は、ハッキングが多いほど動作する可能性が高く、追加のソフトウェアは必要ありません。

systemtapこの種のタスクに使用する方法のデモンストレーションとして引き続き有用です。

systemtap(1.8以降)が動作する最近のLinuxシステムでは、以下のスクリプトを使用して、次の出力を後処理できますlsof

例えば:

$ lsof -aUc nm-applet | sudo that-script
コマンドPIDユーザーFDタイプデバイスサイズ/オフノード名
NM-アプレット4183ステファンの4U UNIX 0xffff8800a055eb40 0t0 36888タイプ= STREAM - > 0xffff8800a055e7c0 [DBUSデーモン、4190、@ / TMP / DBUS-AiBCXOnuP6] 
NM-アプレット4183ステファンの7U UNIX 0xffff8800a055e440 0t0 36890タイプ= STREAM - > 0xffff8800a055e0c0 [Xorgの、 3080、@ / tmp / .X11-unix / X0] 
nm-applet 4183 stephane 8u unix 0xffff8800a05c1040 0t0 36201 type = STREAM-> 0xffff8800a05c13c0 [dbus-daemon、4118、@ / tmp / dbus-yxxNr1NkYC] 
nm-applet 4183 unix 0xffff8800a055d080 0t0 36219 type = STREAM- > 0xffff8800a055d400 [dbus-daemon、4118、@ / tmp / dbus-yxxNr1NkYC] 
nm-applet 4183 stephane 12u unix 0xffff88022e0df036268type = STREAM > / run / dbus / system_bus_socket]
nm-applet 4183 stephane 13u unix 0xffff88022e0f80c0 0t0 37025 type = STREAM-> 0xffff88022e29ec00 [dbus-daemon、2268、/ var / run / dbus / system_bus_socket]

(上記の0xffffの代わりに0x0000000000000000 kernel.kptr_restrictが表示される場合、システムにsysctlパラメーターが設定されているため、カーネルポインターが非特権プロセスから隠されます。この場合lsof、rootとして実行して、意味のある結果)。

このスクリプトは、改行文字を含むソケットファイル名に対処しようとしませんが、しませんlsoflsof空白やコロンには対処しません)。

systemtapここでは、カーネルunix_sock内のunix_socket_tableハッシュ内のすべての構造のアドレスとピアアドレスをダンプするために使用されます。

systemtap 2.6のLinux 3.16 amd64および2.3の3.13でのみテストされています。

#! /usr/bin/perl
# meant to process lsof output to try and find the peer of a given
# unix domain socket. Needs a working systemtap, lsof, and superuser
# privileges. Copyright Stephane Chazelas 2015, public domain.
# Example: lsof -aUc X | sudo this-script
open STAP, '-|', 'stap', '-e', q{
  probe begin {
    offset = &@cast(0, "struct sock")->__sk_common->skc_node;
    for (i = 0; i < 512; i++) 
      for (p = @var("unix_socket_table@net/unix/af_unix.c")[i]->first;
           p;
           p=@cast(p, "struct hlist_node")->next
          ) {
        sock = p - offset;
        printf("%p %p\n", sock, @cast(sock, "struct unix_sock")->peer);
    }
    exit()
  }
};  
my %peer;
while (<STAP>) {
  chomp;
  my ($a, $b) = split;
  $peer{$a} = $b;
}
close STAP;

my %f, %addr;
open LSOF, '-|', 'lsof', '-nPUFpcfdn';
while (<LSOF>) {
  if (/(.)(.*)/) {
    $f{$1} = $2;
    if ($1 eq 'n') {
      $addr{$f{d}}->{"$f{c},$f{p}" . ($f{n} =~ m{^([@/].*?)( type=\w+)?$} ? ",$1" : "")} = "";
    }
  }
}
close LSOF;

while (<>) {
  chomp;
  for my $addr (/0x[0-9a-f]+/g) {
    my $peer = $peer{$addr};
    if (defined($peer)) {
      $_ .= $peer eq '0x0' ?
            "[LISTENING]" :
            " -> $peer\[" . join("|", keys%{$addr{$peer}}) . "]";
      last;
    }
  }
  print "$_\n";
}

parse error: unknown statistic operator @var:何か不足していますか?
トーター

@Totorは、@var(最新の2.7である)のSystemTap 1.8、2012年6月17日に追加されました
ステファンChazelas

2

lsofの4.89は、エンドポイントオプションの表示をサポートしています。

lsof.8から引用:

+|-E +E specifies that process intercommunication channels should be
     displayed with endpoint information and the channels
     of the endpoints should also be displayed.  Currently
     only pipe on Linux is implemented.

     Endpoint information is displayed in the NAME column
     in the form "PID,cmd,FDmode".  PID is the endpoint
     process ID; cmd is the endpoint process command; FD is
     the endpoint file's descriptor; and mode is the
     endpoint file's access mode.  Multiple occurrences of
     this information can appear in a file's NAME column.

     -E specfies that Linux pipe files should only be
     displayed with endpoint information.

出力の例:

mozStorag 21535 22254  yamato    6u     unix 0xf...       0t0     348924 type=STREAM pino=351122 4249,dbus-daem,55u
mozStorag 21535 22254  yamato   10u     unix 0xf...       0t0     356193 type=STREAM pino=356194 21535,gdbus,11u
mozStorag 21535 22254  yamato   11u     unix 0xf...       0t0     356194 type=STREAM pino=356193 21535,gdbus,10u
mozStorag 21535 22254  yamato   21u     unix 0xf...       0t0     355141 type=STREAM pino=357544 4249,dbus-daem,60u
mozStorag 21535 22254  yamato   26u     unix 0xf...       0t0     351134 type=STREAM pino=355142 5015,gdbus,17u
mozStorag 21535 22254  yamato   69u     unix 0xf...       0t0     469354 type=STREAM pino=468160 4545,alsa-sink,21u
mozStorag 21535 22254  yamato   82u     unix 0xf...       0t0     449383 type=STREAM pino=449384 12257,Chrome_Ch,3u
mozStorag 21535 22254  yamato   86u     unix 0xf...       0t0     355174 type=SEQPACKET pino=355175 21535,gdbus,95u
mozStorag 21535 22254  yamato   95u     unix 0xf...       0t0     355175 type=SEQPACKET pino=355174 21535,gdbus,86u 12257,Chrome_Ch,4u
mozStorag 21535 22254  yamato  100u     unix 0xf...       0t0     449389 type=STREAM pino=456453 3614,Xorg,38u
mozStorag 21535 22254  yamato  105u     unix 0xf...       0t0     582613 type=STREAM pino=586261
obexd     22163        yamato    1u     unix 0xf...       0t0     361859 type=STREAM pino=365931
obexd     22163        yamato    2u     unix 0xf...       0t0     361860 type=STREAM pino=365934
obexd     22163        yamato    3u     unix 0xf...       0t0     361241 type=DGRAM pino=10028
obexd     22163        yamato    6u     unix 0xf...       0t0     361242 type=STREAM pino=361864 4249,dbus-daem,70u

2

Linuxカーネル4.2以降CONFIG_UNIX_DIAG、UNIXドメインソケットに関する追加情報、つまりVirtual File System(VFS)情報を提供します。これには、パスからプロセスへのiノードをリンクするためのこれまでにない情報が含まれています。バージョンv4.19.0〜55以降のiproute2ssツールを使用して、すでに照会できます。

$ ss --processes --unix --all --extened
...
Netid  State   Recv-Q  Send-Q  Local Address:Port      Peer Address:Port
u_str  LISTEN  0       5         /tmp/socket 13381347             * 0     users:(("nc",pid=12550,fd=3)) <-> ino:1569897 dev:0/65025 peers:

取得できるデバイス番号とパスのiノード

$ stat -c 'ino:%i dev:0/%d' /tmp/socket
ino:1569946 dev:0/65025

ss フィルタリングもサポートしています:

 ss --processes --unix --all --extended 'sport = /tmp/socket'

しかし、邪悪なプロセスが元のソケットの名前を変更し、それを独自の邪悪なソケットに置き換える可能性があるため、これはあなたのための正しいソケットをリストしない可能性があることに注意してください:

mv /tmp/socket /tmp/socket.orig
nc -U -l /tmp/socket.evil &
mv /tmp/socket.evil /tmp/socket

lsof /tmp/socketfuser /tmp/socketおよびss --processes --unix --all --extended 'sport = /tmp/socket'すべての元のプロセス、一覧表示されますない悪の交換を。代わりに次のようなものを使用します。

id=$(stat -c 'ino:%i dev:0/%d' /tmp/socket)
ss --processes --unix --all --extended | grep -F "$id"

または、man 7 sock_diagに含まれるテンプレートに基づいて独自のリッテプログラムを作成します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.