유닉스 도메인 소켓에서 수동적으로 캡처하는 방법 (AF_UNIX 소켓 모니터링)?


13

TCP / IP 및 UDP 캡처는 tcpdump/를 사용하여 dumpcap수행 할 수 있으며 추가 분석을 위해 Wireshark에 제공 할 수있는 pcap / pcapng 파일을 생성합니다. 명명 된 Unix 도메인 소켓에 대해 유사한 도구가 있습니까? (추상 소켓에서 작동하는 일반적인 솔루션도 좋습니다.)

strace그대로는 충분하지 않으며 Unix 도메인 소켓 I / O를 필터링하는 것은 간단하지 않습니다. 기존의 열린 프로그램에 대한 수동 분석이 목표이기 때문에 또는를 사용socat 하는 프록시 도 적합하지 않습니다.

Wireshark에서 분석을 위해 사용할 수있는 패킷 캡처를 어떻게 얻을 수 있습니까? 프로토콜 응용 프로그램의 예는 X11 (Xorg, 현재 응용 프로그램) 및 cURL / PHP (HTTP)입니다. CONFIG_UNIX_DIAGLinux 커널에서 옵션을 보았습니다 .



@ StéphaneChazelas 감사하지만 Xorg가로 시작했기 때문에 -nolisten tcpTCP 소켓이 없습니다. 모두 실패하면 xscope 또는 깔끔한 strace + text2pcap 트릭을 사용하는 것으로 되돌아 갈 것입니다. 그래도 일반 Unix 소켓 캡처에 관심이 있습니다 (사이드 채널 데이터가 아닌 데이터 용).
Lekensteyn

strace 외에도 감사 및 시스템 탭을 볼 수도 있습니다.
Stéphane Chazelas

systemtap 은 거의 GDB 핵처럼 보이지만 커널 수준입니다. 감사에 대해 몰라, 읽기 / 쓰기가 허용되는지 확인한 LSM 후크 만 발견했습니다. (저는 현재 Linux 커널 소스 코드를 파고 있습니다)
Lekensteyn

답변:


12

Linux 커널 v4.2-rc5부터는 libpcap에서 사용중인 인터페이스를 사용하여 직접 캡처 할 수 없습니다. libpcap은 Linux 전용 AF_PACKET(별칭 PF_PACKET) 도메인을 사용하여 " netdevice "(이더넷 인터페이스 등)를 통과하는 데이터의 데이터 만 캡처 할 수 있습니다 .

AF_UNIX소켓 에서 캡처하기위한 커널 인터페이스가 없습니다 . 표준 이더넷 캡처에는 소스 / 대상 등의 이더넷 헤더가 있습니다. 유닉스 소켓에는 그러한 가짜 헤더가 없으며 링크 계층 헤더 유형 레지스트리 에는 이와 관련된 내용이 없습니다.

데이터에 대한 기본 항목 포인트는 unix_stream_recvmsgunix_stream_sendmsg에 대한 SOCK_STREAM( SOCK_DGRAMSOCK_SEQPACKET유사 기능을 명명했다). 데이터가 함수sk->sk_receive_queue 에 버퍼링되고 결국 에는 패킷 캡처를위한 함수 호출로 이어지는 코드가 없습니다 . 일반적인 패킷 캡처 내부에 대한 자세한 내용은 osgx on SO의한이 분석을 참조하십시오 .unix_stream_sendmsgtpacket_rcv

AF_UNIX소켓 모니터링 에 대한 원래 질문으로 돌아가서 주로 응용 프로그램 데이터에 관심이 있다면 몇 가지 옵션이 있습니다.

  • 패시브 (이미 실행중인 프로세스에서도 작동) :
    • straceI / O를 수행 할 수있는 시스템 호출을 사용 하고 캡처합니다. 그들 중 많은이있다, read, pread64, readv, preadv, recvmsg그리고 더 많은 ... 참조 스테판 Chazelas가의 @xterm. 이 방법의 단점은 먼저 파일 디스크립터를 찾아서 시스템 호출을 놓칠 수 있다는 것입니다. 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 ( git , manual )가 있습니다.

제안 된 CONFIG_UNIX_DIAG옵션은 불행히도 여기서도 도움이되지 않습니다. 통계에 따라 실시간 데이터를 수집하지 않고 통계를 수집하는 데만 사용할 수 있습니다 ( linux / unix_diag.h 참조 ).

불행히도 현재 pcap을 생성하는 유닉스 도메인 소켓에 대한 완벽한 추적 프로그램은 없습니다 (내가 아는 한). 소스 / 대상 PID (사용 가능한 경우)와 선택적 추가 데이터 (자격 증명, 파일 설명자) 및 마지막으로 데이터를 포함하는 헤더가있는 libpcap 형식이 이상적입니다. 부족한 점은 syscall 추적입니다.


(관심있는 독자에 대한) 추가 정보, 여기에 몇 백 트레이스가 (GDB가에 속보로 취득 unix_stream_*하고 rbreak packet.c:., 리눅스 QEMU 및 socat 메인 라인 리눅스 4.2 RC5에) :

# 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

그런데 kristrev.github.io/2013/07/26/… 을 읽고 netlink를 통한 링크 알림을 감시하는 지침을 보았고 진단 프로그램이 패킷 스니핑을 제공 할 수 있는지 궁금한 경우, 여전히 대답은 아닙니다 . 이러한 진단은 실시간이 아닌 폴링을 통해 통계를 제공합니다.
Lekensteyn

9

유닉스 도메인 소켓 트래픽을 캡처하고 덤프 하는 도구 를 작성했습니다 . 그것은 사용하는 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
...
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.