วิธีจับภาพเฉยๆจากซ็อกเก็ตโดเมน Unix (การตรวจสอบซ็อกเก็ต AF_UNIX)


13

การจับ TCP / IP และ UDP สามารถทำได้โดยใช้tcpdump/ dumpcapและสร้างไฟล์ pcap / pcapng ซึ่งสามารถป้อนให้ Wireshark สำหรับการวิเคราะห์เพิ่มเติม มีเครื่องมือที่คล้ายกันนี้อยู่ในซ็อกเก็ตโดเมนชื่อ Unix หรือไม่? (โซลูชันทั่วไปที่ใช้กับซ็อกเก็ตแบบนามธรรมจะดีเช่นกัน)

straceตาม - ไม่เพียงพอไม่ตรงไปตรงมาเพื่อกรองสำหรับซ็อกเก็ตโดเมน Unix I / O พร็อกซี่ใช้socatหรือเหมือนกันยังไม่เหมาะที่จะเป็นเป้าหมายคือการวิเคราะห์เรื่อย ๆ สำหรับโปรแกรมที่เปิดมีอยู่

ฉันจะขอรับการจับแพ็คเก็ตที่ฉันสามารถใช้ใน Wireshark เพื่อการวิเคราะห์ได้อย่างไร ตัวอย่างการใช้งานโพรโทคอลคือ X11 (Xorg แอปพลิเคชันปัจจุบันของฉัน) และ cURL / PHP (HTTP) ฉันเห็นCONFIG_UNIX_DIAGตัวเลือกในเคอร์เนล Linux นี่เป็นการใช้งานหรือไม่?



@ StéphaneChazelasขอบคุณ แต่ตั้งแต่ Xorg เริ่มต้นด้วย-nolisten tcpไม่มีซ็อกเก็ต TCP หากทั้งหมดล้มเหลวฉันอาจจะกลับไปใช้ xscope หรือเคล็ดลับ strace + text2pcap ที่เรียบร้อยของคุณ ฉันจะยังคงสนใจในการจับซ็อกเก็ต Unix ทั่วไป (สำหรับข้อมูลเพียงไม่ใช่ข้อมูลช่องทางด้านข้าง)
Lekensteyn

นอกจาก strace คุณยังสามารถดู auditd และ systemtap
Stéphane Chazelas

systemtapเกือบดูเหมือนแฮ็ค GDB แต่จากนั้นในระดับเคอร์เนล ไม่ทราบเกี่ยวกับการตรวจสอบฉันพบเฉพาะเบ็ด LSM ที่ตรวจสอบว่าคุณได้รับอนุญาตให้อ่าน / เขียน (ขณะนี้ฉันกำลังขุดในซอร์สโค้ดเคอร์เนล Linux)
Lekensteyn

คำตอบ:


12

ในฐานะที่เป็นเคอร์เนล Linux v4.2-rc5 มันเป็นไปไม่ได้ที่จะจับภาพโดยตรงโดยใช้ส่วนต่อประสานที่ใช้งานโดย libpcap libpcap ใช้โดเมนเฉพาะLinux AF_PACKET(นามแฝงPF_PACKET) ซึ่งอนุญาตให้คุณรวบรวมข้อมูลสำหรับข้อมูลที่ผ่าน " netdevice " (เช่นอินเทอร์เฟซอีเทอร์เน็ต)

ไม่มีอินเตอร์เฟสเคอร์เนลสำหรับการจับภาพจากAF_UNIXซ็อกเก็ต การจับภาพอีเธอร์เน็ตมาตรฐานมีหัวต่อ Ethernet พร้อมแหล่งที่มา / ปลายทาง ฯลฯ ซ็อกเก็ต Unix ไม่มีส่วนหัวปลอมดังกล่าวและการลงทะเบียนประเภทส่วนหัวของเลเยอร์ลิงก์ไม่แสดงรายการอะไรที่เกี่ยวข้องกับสิ่งนี้

จุดเข้าใช้งานพื้นฐานสำหรับข้อมูลเป็นunix_stream_recvmsgและunix_stream_sendmsgสำหรับSOCK_STREAM( SOCK_DGRAMและSOCK_SEQPACKETมีฟังก์ชั่นที่มีชื่อคล้ายกัน) ข้อมูลถูกบัฟเฟอร์ในsk->sk_receive_queueและในunix_stream_sendmsgฟังก์ชั่นไม่มีรหัสที่นำไปสู่การเรียกใช้tpacket_rcvฟังก์ชั่นสำหรับการจับแพ็คเก็ตในที่สุด ดูการวิเคราะห์นี้โดย osgx บน SOสำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการจับแพกเก็ตโดยทั่วไป

กลับไปที่คำถามดั้งเดิมเกี่ยวกับAF_UNIXการตรวจสอบซ็อกเก็ตหากคุณสนใจข้อมูลแอปพลิเคชันเป็นหลักคุณมีตัวเลือกดังนี้:

  • พาสซีฟ (ใช้ได้กับกระบวนการที่รันอยู่แล้ว):
    • ใช้straceและจับการเรียกระบบที่เป็นไปได้ที่ดำเนินการ I / O มีจำนวนมากของพวกเขามีread, pread64, readv, preadv, recvmsgและอื่น ๆ อีกมากมาย ... ดู@ Stéphane Chazelasxtermตัวอย่างสำหรับ ข้อเสียของวิธีการนี้คือคุณต้องค้นหาตัวอธิบายไฟล์ของคุณก่อนแล้วจึงยังอาจพลาดสายระบบ ด้วย strace คุณสามารถใช้งานได้-e trace=fileกับส่วนใหญ่ ( preadครอบคลุมเฉพาะ-e trace=descแต่อาจไม่ใช้สำหรับซ็อกเก็ต Unix ตามโปรแกรมส่วนใหญ่)
    • ทำลายบน / แก้ไขunix_stream_recvmsg, unix_stream_sendmsg(หรือunix_dgram_*หรือunix_seqpacket_*) ในเคอร์เนลและส่งออกข้อมูลที่ไหนสักแห่ง คุณสามารถใช้ SystemTap สำหรับการตั้งค่าจุดติดตามนี่คือตัวอย่างการตรวจสอบข้อความที่ส่งออก ต้องสนับสนุนเคอร์เนลและความพร้อมของสัญลักษณ์การแก้จุดบกพร่อง
  • Active (ใช้ได้กับกระบวนการใหม่เท่านั้น):

    • ใช้พร็อกซีที่เขียนไฟล์ด้วย คุณสามารถเขียนมัลติเพล็กเซอร์ด่วนด้วยตัวคุณเองหรือแฮ็คสิ่งนี้ที่ส่งเอาต์พุต pcap (ระวังข้อ จำกัด เช่นAF_UNIXสามารถส่งไฟล์ descriptors 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 )

น่าเสียดายที่ตอนนี้ไม่มีเครื่องมือสืบค้นที่สมบูรณ์แบบสำหรับซ็อกเก็ตโดเมน Unix ที่สร้าง pcaps (เพื่อความรู้ที่ดีที่สุดของฉัน) โดยอุดมคติแล้วจะมีรูปแบบ libpcap ที่มีส่วนหัวที่ประกอบด้วย source / dest PID (เมื่อมี) ตามด้วยข้อมูลเพิ่มเติมเพิ่มเติม (ข้อมูลประจำตัว, ตัวอธิบายไฟล์) และข้อมูลในที่สุด สิ่งที่ดีที่สุดที่ทำได้คือการติดตาม syscall


ข้อมูลเพิ่มเติม (สำหรับผู้อ่านที่สนใจ) ต่อไปนี้เป็น backtraces บางส่วน (ที่ได้มาจากการทำลาย GDB unix_stream_*และrbreak packet.c:.Linux ใน QEMU และ socat บน mainline Linux 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

ฉันเขียนเครื่องมือในการจับภาพและถ่ายโอนข้อมูลปริมาณการใช้ซ็อกเก็ตโดเมน 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
...
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.