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_STREAM( SOCK_DGRAMSOCK_SEQPACKET비슷한 이름의 함수가 있습니다). 데이터는 다음 위치에 버퍼링되어 있습니다 sk->sk_receive_queue.unix_stream_sendmsg기능, 궁극적으로 호출로 이어지는 코드가 없습니다.tpacket_rcv기능패킷 캡처용. 바라보다SO의 osgx 분석일반 패킷 캡처 내부에 대한 자세한 내용입니다.

AF_UNIX소켓 모니터링에 대한 원래 질문 으로 돌아가서 주로 애플리케이션 데이터에 관심이 있는 경우 몇 가지 옵션이 있습니다.

  • 수동(이미 실행 중인 프로세스에도 적용됨):
    • straceI/O를 수행하는 가능한 시스템 호출을 사용 하고 캡처합니다. read,,,,,, pread64그리고 readv더 많은 것들이 있습니다 preadv... recvmsg확인해 보세요@stefanchazerasxterm. 이 접근 방식의 단점은 먼저 파일 설명자를 찾아야 하고 그 후에도 시스템 호출을 놓칠 수 있다는 것입니다. strace를 사용하면 -e trace=file대부분을 사용할 수 있습니다 ( pread방금 소개했지만 -e trace=desc대부분의 프로그램은 Unix 소켓에 사용하지 않을 것입니다).
    • 중단/수정 unix_stream_recvmsg, unix_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옵션은 여기서도 도움이 되지 않습니다. 이는 실시간 데이터를 얻는 것이 아니라 통계를 수집하는 데만 사용할 수 있습니다(참조:리눅스/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
...

관련 정보