Unixドメインソケットで手動でキャプチャ(AF_UNIXソケットを監視)する方法は?

Unixドメインソケットで手動でキャプチャ(AF_UNIXソケットを監視)する方法は?

TCP / IPおよびUDPキャプチャを使用して、さらに分析するためにWiresharkに提供できるpcap / pcapngファイルを生成できtcpdumpますdumpcap。 Unixドメインソケット名を指定するための同様のツールはありますか? (抽象ソケットの一般的な解決策も良いでしょう。)

straceあるだけでは十分ではないため、UnixドメインソケットI / Oをフィルタリングするのは簡単ではありません。 ㅏプロキシの使用socatまたは類似また、既存の公開プログラムの受動的分析が目的であるため、適切ではない。

Wiresharkで分析に使用できるパケットキャプチャをどのように取得しますか?サンプルプロトコルアプリケーションは、X11(Xorg、現在のアプリケーション)とcURL / PHP(HTTP)です。一つ見たことがあるCONFIG_UNIX_DIAGLinuxカーネルのオプションは便利ですか?

答え1

Linuxカーネルv4.2-rc5以降、libpcapが使用するインタフェースを使用して直接キャプチャすることは不可能です。 libpcapはLinuxのみを使用します。AF_PACKET(エイリアスPF_PACKET)渡されるデータのみをキャプチャできるドメインインターネット機器"(例:イーサネットインターフェイス)。

ソケットからAF_UNIXキャプチャするためのカーネルインタフェースはありません。標準イーサネットキャプチャには、ソース/ターゲットなどを含むイーサネットヘッダがあります。 Unixソケットにはそのような誤ったヘッダがありません。リンクレイヤーヘッダータイプレジストリこれに関連する内容は記載されていません。

データのデフォルトエントリポイントは次のとおりです。unix_stream_recvmsgそしてunix_stream_sendmsgfor SOCK_STREAMSOCK_DGRAMSOCK_SEQPACKET同様の名前の関数があります)。データは次の場所にバッファリングされていますsk->sk_receive_queueunix_stream_sendmsg機能、最終的に呼び出しにつながるコードはありません。tpacket_rcv機能パケットキャプチャ用。バラよりSOのosgx分析一般的なパケットキャプチャ内の詳細です。

AF_UNIXソケットモニタリングに関する元の質問に戻り、主にアプリケーションデータに興味がある場合は、いくつかのオプションがあります。

  • 手動(すでに実行中のプロセスにも適用されます):
    • straceI / Oを実行する可能性のあるシステムコールを使用してキャプチャします。read、、、、、、、pread64そしてreadvもっとたくさんありますpreadv...recvmsg確認してくださいおめでとうございますはいxterm。このアプローチの欠点は、最初にファイル記述子を見つける必要があり、その後もシステムコールを見逃す可能性があることです。 straceを使用すると、-e trace=fileほとんどを使用できます(preadちょうど紹介しましたが、-e trace=descほとんどのプログラムはUnixソケットには使用しません)。
    • 中断/修正unix_stream_recvmsgunix_stream_sendmsg(またはunix_dgram_*またはunix_seqpacket_*コアどこかにデータを出力します。 SystemTap を使用して、これらのトレースポイントを設定できます。一例発信メッセージを監視します。必要カーネルサポートとデバッグシンボルの可用性
  • アクティビティ(新しいプロセスのみ):

    • ファイルに書き込むことができるプロキシを使用してください。クイックマルチプレクサを直接作成したり、pcapを出力したりする同様のものをハッキングすることもできます(制限に注意してください。たとえば、AF_UNIXファイル記述子を渡すことはできますが、渡すことAF_INETはできません)。

      # fake TCP server connects to real Unix socket
      socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CONNECT:some.sock
      # start packet capture on said port
      tcpdump -i lo -f 'tcp port 6000'
      # clients connect to this Unix socket
      socat UNIX-LISTEN:fake.sock,fork TCP-CONNECT:127.0.0.1:6000
      
    • 専用アプリケーションプロキシを使用してください。 X11の場合、xscope(手動)。

残念ながら、提案されたCONFIG_UNIX_DIAGオプションはここでも役に立ちません。これはリアルタイムデータを取得するのではなく、統計を収集するためにのみ使用できます(参照:Linux/unix_diag.h)。

残念ながら、現在pcapを生成するUnixドメインソケットの完全なトラッカーはありません。理想的には、libpcap形式のヘッダーには、ソース/ターゲットPID(利用可能な場合)、オプションの追加データ(資格情報、ファイル記述子)、最後にデータが含まれます。これが不足している場合、最良の方法はシステムコールトレースです。


追加情報(興味のある読者のために)については、次のいくつかのバックトレース(GDB割り込みunix_stream_*rbreak packet.c:.QEMUのLinux、およびメインラインLinux 4.2-rc5のsocatを介して取得)を参照してください。

# echo foo | socat - UNIX-LISTEN:/foo &
# echo bar | socat - UNIX-CONNECT:/foo
unix_stream_sendmsg at net/unix/af_unix.c:1638
sock_sendmsg_nosec at net/socket.c:610
sock_sendmsg at net/socket.c:620
sock_write_iter at net/socket.c:819
new_sync_write at fs/read_write.c:478
__vfs_write at fs/read_write.c:491
vfs_write at fs/read_write.c:538
SYSC_write at fs/read_write.c:585
SyS_write at fs/read_write.c:577
entry_SYSCALL_64_fastpath at arch/x86/entry/entry_64.S:186

unix_stream_recvmsg at net/unix/af_unix.c:2210
sock_recvmsg_nosec at net/socket.c:712
sock_recvmsg at net/socket.c:720
sock_read_iter at net/socket.c:797
new_sync_read at fs/read_write.c:422
__vfs_read at fs/read_write.c:434
vfs_read at fs/read_write.c:454
SYSC_read at fs/read_write.c:569
SyS_read at fs/read_write.c:562

# tcpdump -i lo &
# echo foo | socat - TCP-LISTEN:1337 &
# echo bar | socat - TCP-CONNECT:127.0.0.1:1337
tpacket_rcv at net/packet/af_packet.c:1962
dev_queue_xmit_nit at net/core/dev.c:1862
xmit_one at net/core/dev.c:2679
dev_hard_start_xmit at net/core/dev.c:2699
__dev_queue_xmit at net/core/dev.c:3104
dev_queue_xmit_sk at net/core/dev.c:3138
dev_queue_xmit at netdevice.h:2190
neigh_hh_output at include/net/neighbour.h:467
dst_neigh_output at include/net/dst.h:401
ip_finish_output2 at net/ipv4/ip_output.c:210
ip_finish_output at net/ipv4/ip_output.c:284
ip_output at net/ipv4/ip_output.c:356
dst_output_sk at include/net/dst.h:440
ip_local_out_sk at net/ipv4/ip_output.c:119
ip_local_out at include/net/ip.h:119
ip_queue_xmit at net/ipv4/ip_output.c:454
tcp_transmit_skb at net/ipv4/tcp_output.c:1039
tcp_write_xmit at net/ipv4/tcp_output.c:2128
__tcp_push_pending_frames at net/ipv4/tcp_output.c:2303
tcp_push at net/ipv4/tcp.c:689
tcp_sendmsg at net/ipv4/tcp.c:1276
inet_sendmsg at net/ipv4/af_inet.c:733
sock_sendmsg_nosec at net/socket.c:610
sock_sendmsg at net/socket.c:620
sock_write_iter at net/socket.c:819
new_sync_write at fs/read_write.c:478
__vfs_write at fs/read_write.c:491
vfs_write at fs/read_write.c:538
SYSC_write at fs/read_write.c:585
SyS_write at fs/read_write.c:577
entry_SYSCALL_64_fastpath at arch/x86/entry/entry_64.S:186

tpacket_rcv at net/packet/af_packet.c:1962
dev_queue_xmit_nit at net/core/dev.c:1862
xmit_one at net/core/dev.c:2679
dev_hard_start_xmit at net/core/dev.c:2699
__dev_queue_xmit at net/core/dev.c:3104
dev_queue_xmit_sk at net/core/dev.c:3138
dev_queue_xmit at netdevice.h:2190
neigh_hh_output at include/net/neighbour.h:467
dst_neigh_output at include/net/dst.h:401
ip_finish_output2 at net/ipv4/ip_output.c:210
ip_finish_output at net/ipv4/ip_output.c:284
ip_output at net/ipv4/ip_output.c:356
dst_output_sk at include/net/dst.h:440
ip_local_out_sk at net/ipv4/ip_output.c:119
ip_local_out at include/net/ip.h:119
ip_queue_xmit at net/ipv4/ip_output.c:454
tcp_transmit_skb at net/ipv4/tcp_output.c:1039
tcp_send_ack at net/ipv4/tcp_output.c:3375
__tcp_ack_snd_check at net/ipv4/tcp_input.c:4901
tcp_ack_snd_check at net/ipv4/tcp_input.c:4914
tcp_rcv_state_process at net/ipv4/tcp_input.c:5937
tcp_v4_do_rcv at net/ipv4/tcp_ipv4.c:1423
tcp_v4_rcv at net/ipv4/tcp_ipv4.c:1633
ip_local_deliver_finish at net/ipv4/ip_input.c:216
ip_local_deliver at net/ipv4/ip_input.c:256
dst_input at include/net/dst.h:450
ip_rcv_finish at net/ipv4/ip_input.c:367
ip_rcv at net/ipv4/ip_input.c:455
__netif_receive_skb_core at net/core/dev.c:3892
__netif_receive_skb at net/core/dev.c:3927
process_backlog at net/core/dev.c:4504
napi_poll at net/core/dev.c:4743
net_rx_action at net/core/dev.c:4808
__do_softirq at kernel/softirq.c:273
do_softirq_own_stack at arch/x86/entry/entry_64.S:970

答え2

私は書いたツールUNIXドメインソケットトラフィックをキャプチャしてダンプします。bpf/kprobeカーネル機能を調査unix_stream_sendmsgし、トラフィックをユーザースペースにダンプするために使用されます。

このツールは次のように異なります。bccそのため、bccまずインストールする必要があります。

例を実行してください:

$ sudo ./sockdump.py /var/run/docker.sock # run "docker ps" in another terminal
>>> docker[3412] len 83
GET /_ping HTTP/1.1
Host: docker
User-Agent: Docker-Client/18.06.1-ce (linux)

>>> dockerd[370] len 215
HTTP/1.1 200 OK
Api-Version: 1.38
Docker-Experimental: false
Ostype: linux
Server: Docker/18.06.1-ce (linux)
Date: Tue, 25 Sep 2018 07:05:03 GMT
Content-Length: 2
Content-Type: text/plain; charset=utf-8

OK
...

関連情報