Unix alan soketlerinden (AF_UNIX soket izleme) pasif olarak nasıl yakalanır?


13

TCP / IP ve UDP yakalamaları tcpdump/ kullanılarak yapılabilir dumpcapve daha fazla analiz için Wireshark'a beslenebilen bir pcap / pcapng dosyası üretir. Adlandırılmış Unix etki alanı yuvaları için benzer bir araç var mı? (Soyut soketler için çalışan genel bir çözüm de güzel olurdu.)

straceolduğu gibi yeterli değilse, Unix etki alanı soket G / Ç'lerine filtre uygulamak kolay değildir. Amaç, mevcut açık programlar için pasif analiz olduğu için veya benzeri bir proxysocat de uygun değildir.

Analiz için Wireshark'ta kullanabileceğim bir paket yakalamayı nasıl edinebilirim? Örnek protokol uygulamaları X11 (Xorg, mevcut uygulamam) ve cURL / PHP (HTTP). CONFIG_UNIX_DIAGLinux çekirdeğinde bir seçenek gördüm , bu biraz işe yarar mı?



@ StéphaneChazelas Teşekkürler, ancak Xorg başlatıldığından beri -nolisten tcpTCP soketi yoktur. Hepsi başarısız olursa, muhtemelen xscope veya düzgün strace + text2pcap hilenizi kullanmaya geri döneceğim. Yine de genel bir Unix soket yakalamasıyla ilgileniyorum (sadece veri için, yan kanal verileri için değil).
Lekensteyn

Strace'nin yanı sıra denetleme ve systemtap'a da bakabilirsiniz.
Stéphane Chazelas

systemtap neredeyse bir GDB kesmek gibi görünüyor, ama sonra çekirdek seviyesinde. Denetim hakkında bilmiyorum, sadece okuma / yazma izniniz olup olmadığını kontrol eden bir LSM kancası buldum. (Şu anda Linux çekirdeği kaynak kodunu
kazıyorum

Yanıtlar:


12

Linux çekirdeği v4.2-rc5 itibariyle libpcap tarafından kullanılan arabirimleri kullanarak doğrudan yakalamak mümkün değildir. libpcap yalnızca bir " netdevice " (Ethernet arayüzleri gibi) üzerinden gelen veriler için veri yakalamanızı sağlayan Linux'a özgü AF_PACKET(takma ad PF_PACKET) etki alanını kullanır .

AF_UNIXSoketlerden çekim yapmak için bir çekirdek arabirimi yoktur . Standart Ethernet yakalamalarında kaynak / hedef vb. İçeren bir Ethernet başlığı vardır. Unix soketlerinde böyle sahte bir başlık yoktur ve bağlantı katmanı başlık türleri kayıt defterinde bununla ilgili hiçbir şey listelenmez.

Veriler için temel giriş noktaları unix_stream_recvmsgve unix_stream_sendmsgiçindir SOCK_STREAM( SOCK_DGRAMve SOCK_SEQPACKETbenzer şekilde adlandırılmış işlevlere sahiptir). Veriler arabellekte sk->sk_receive_queueve unix_stream_sendmsgfonksiyonda tamponlanır , sonuçta paket yakalama tpacket_rcvfonksiyonunu çağırmaya yol açan bir kod yoktur . Genel olarak paket yakalamanın iç kısımları hakkında daha fazla ayrıntı için SO üzerinde osgx tarafından yapılan bu analize bakın .

AF_UNIXSoket izleme hakkındaki orijinal soruya geri dönerseniz, esas olarak uygulama verileriyle ilgileniyorsanız, bazı seçenekleriniz vardır:

  • Pasif (ayrıca zaten çalışan işlemler için de çalışır):
    • straceG / Ç gerçekleştiren olası sistem çağrılarını kullanın ve yakalayın. Bunlardan çok var, read, pread64, readv, preadv, recvmsgve daha birçok ... See Stéphane Chazelas @ örneğin xterm. Bu yaklaşımın dezavantajı, önce dosya tanımlayıcınızı bulmanız ve ardından sistem çağrılarını kaçırabilir olmanızdır. Strace ile -e trace=fileçoğu için kullanabilirsiniz ( preadsadece kaplıdır -e trace=desc, ancak muhtemelen programların çoğu tarafından Unix soketleri için kullanılmaz).
    • Çekirdeği kırın / değiştirin unix_stream_recvmsg, unix_stream_sendmsg(veya unix_dgram_*veya unix_seqpacket_*) ve verileri bir yerlerde çıktılayın. Bu tür izleme noktalarını ayarlamak için SystemTap kullanabilirsiniz, işte giden iletileri izlemek için bir örnek . Çekirdek desteği ve hata ayıklama simgelerinin kullanılabilirliğini gerektirir .
  • Etkin (yalnızca yeni işlemler için çalışır):

    • Ayrıca dosya yazan bir proxy kullanın. Kendiniz hızlı bir çoklayıcı yazabilir veya bir pcap çıktısı veren böyle bir şeyi hackleyebilirsiniz (sınırlamalara dikkat edin, örneğin AF_UNIXdosya tanımlayıcılarını geçebilir, AF_INETyapamaz):

      # 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
      
    • Özel bir uygulama proxy'si kullanın. X11 için xscope ( git , manual ) vardır.

Önerilen CONFIG_UNIX_DIAGseçenek maalesef burada da yararlı değildir, sadece istatistik toplamak için kullanılabilir, akarken gerçek zamanlı veriler elde etmek için kullanılamaz (bkz. Linux / unix_diag.h ).

Ne yazık ki şu anda pcap üreten Unix alan soketleri için mükemmel bir izleyici yok (en iyi bilgime göre). İdeal olarak, kaynak / dest PID'yi (varsa) ve ardından isteğe bağlı ek verileri (kimlik bilgileri, dosya tanımlayıcıları) ve son olarak verileri içeren bir başlığı olan bir libpcap formatı olacaktır. Bunun olmaması için yapılabilecek en iyi şey sistemli takiptir.


Ek bilgi (ilgilenen okuyucu için), bazı geri çekimler (GDB kırılma unix_stream_*ve rbreak packet.c:.QEMU'daki Linux ve ana hat Linux 4.2-rc5'teki socat ile edinilmiş):

# 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

Bu arada, kristrev.github.io/2013/07/26/… 'ı okuduysanız ve netlink yoluyla bağlantı bildirimlerini izlemek için talimatlar gördüyseniz ve teşhislerin paket kokusu sağlayıp sağlayamayacağını merak ettiyseniz, cevap hala hayır . Bu tanılamalar, gerçek zamanlı olarak değil, yoklama yoluyla istatistikler sağlar.
Lekensteyn

9

Unix etki alanı soket trafiğini yakalamak ve boşaltmak için bir araç yazdım . Bu kullandığı bpf/kprobeçekirdek fonksiyonunu incelemek için unix_stream_sendmsgkullanıcı uzaya ve dökümü trafiği.

Araç bağlıdır bcc, bu yüzden bccönce yüklemeniz gerekir .

Örnek bir çalışma:

$ 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
...
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.