00 tcpdump nedir — libpcap ve BPF
tcpdump, network interface'den geçen paketleri gerçek zamanlı yakalayan ve konsolda gösteren bir komut satırı aracıdır.
Üç temel bileşen üzerine çalışır:
NIC (network card)
↓
Kernel BPF → filtre (sadece eşleşen paketler kullanıcı alanına geçer)
↓
libpcap → kullanıcı alanı yakalama kütüphanesi
↓
tcpdump → decode + göster / .pcap dosyasına yaz
libpcap (Linux Packet CAPture), tcpdump'ın temel aldığı kullanıcı alanı kütüphanesidir. Wireshark, nmap ve çoğu ağ aracı da aynı kütüphaneyi kullanır. BPF (Berkeley Packet Filter) ise kernel içinde çalışan sanal makinedir — filtreyi kernel'da değerlendirerek eşleşmeyen paketlerin kullanıcı alanına hiç geçmesini engeller. Bu sayede yüksek trafik altında bile performans kaybı minimumdur.
Promiscuous mode: Normalde bir NIC yalnızca kendi MAC adresine veya broadcast/multicast adreslerine gelen paketleri alır. tcpdump, interface'i promiscuous mode'a alarak ağ üzerindeki tüm trafiği yakalar. Bu davranışı `-p` flag'i ile kapatabilirsin (yalnızca kendi trafiğini gör).
tcpdump çalıştırmak için root ya da CAP_NET_RAW ve CAP_NET_ADMIN yetkisi gerekir. Üretim sistemlerinde sudo tcpdump yerine özel bir servis hesabına sadece bu capability'leri ver: setcap cap_net_raw,cap_net_admin+eip /usr/bin/tcpdump
Kurulum
# Debian / Ubuntu
apt-get install tcpdump
# Alpine Linux (embedded için sık kullanılır)
apk add tcpdump
# Versiyon kontrol
tcpdump --version
# tcpdump version 4.99.4
# libpcap version 1.10.4
01 Temel kullanım ve çıktı formatı
tcpdump'ın en sık kullanılan flaglerini öğren ve çıktıyı doğru oku.
Temel flagler
-i any tüm interface'leri dinler (Linux'a özgü).80 yerine http yazmasın.-s 0 tüm paketi yakalar (varsayılan 262144). Küçük değer disk/bellek tasarrufu sağlar.Temel örnekler
# eth0 üzerindeki tüm trafiği izle (DNS çözümlemesiz)
sudo tcpdump -nn -i eth0
# Sadece 20 paket al ve çık
sudo tcpdump -nn -i eth0 -c 20
# Tüm interface'leri dinle, verbose çıktı
sudo tcpdump -nn -v -i any
# Ethernet header'larını da göster
sudo tcpdump -nn -e -i eth0
# HTTP içeriğini ASCII olarak gör
sudo tcpdump -nn -A -i eth0 port 80
Çıktı formatını okumak
Tipik bir TCP satırı şöyle görünür:
14:32:07.123456 IP 192.168.1.10.54321 > 93.184.216.34.80: Flags [S], seq 123456789, win 64240, length 0
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ └─ payload uzunluğu
│ │ │ │ │ │ └─ TCP window size
│ │ │ │ │ └─ sequence numarası
│ │ │ │ └─ TCP flags: [S]=SYN [.]=ACK [P]=PSH [F]=FIN [R]=RST
│ │ │ └─ hedef IP:port
│ │ └─ kaynak IP:port
│ └─ protokol (IP / ARP / IPv6)
└─ zaman damgası (mikrosaniye hassasiyette)
Varsayılan format HH:MM:SS.ffffff'tir. -t ile timestamp'i kaldır, -tt ile epoch saniye, -ttt ile paketler arası delta zamanı göster. Log analizinde -tt özellikle yararlıdır.
02 BPF filtresi yazımı
BPF filtresi, hangi paketlerin yakalanacağını kernel seviyesinde belirler. Doğru filtre hem performansı korur hem de analizi odaklar.
Temel filtre primitifleri
tcp, udp, icmpMantıksal operatörler
# and / or / not (ya da && / || / !)
# Hem kaynak 10.0.0.1 hem de port 443
sudo tcpdump -nn 'src host 10.0.0.1 and port 443'
# Port 80 veya 443 olan paketler
sudo tcpdump -nn 'port 80 or port 443'
# ARP haricindeki tüm paketler
sudo tcpdump -nn 'not arp'
# Parantezle gruplama (shell yorumlamasından kaçmak için tırnak zorunlu)
sudo tcpdump -nn '(port 80 or port 443) and not host 127.0.0.1'
# 10.0.0.0/8 ağından gelmeyen TCP trafiği
sudo tcpdump -nn 'tcp and not src net 10.0.0.0/8'
Ham BPF / byte offset erişimi
BPF, paket içindeki belirli byte'lara erişmenizi sağlar. Sözdizimi: proto[offset:size]. Bu sayede sadece belirli flag kombinasyonlarını yakalamak mümkündür.
# TCP header offset 13 = flags byte
# SYN biti: 0x02, ACK biti: 0x10, RST: 0x04, FIN: 0x01, PSH: 0x08
# Sadece SYN paketleri (SYN=1, ACK=0)
sudo tcpdump -nn 'tcp[13] = 0x02'
# SYN+ACK paketleri (three-way handshake 2. adımı)
sudo tcpdump -nn 'tcp[13] = 0x12'
# RST biti set olan paketler (bağlantı sıfırlaması)
sudo tcpdump -nn 'tcp[13] & 0x04 != 0'
# PSH biti set olan paketler (veri içeren paketler)
sudo tcpdump -nn 'tcp[13] & 0x08 != 0'
# ICMP echo request (ping)
sudo tcpdump -nn 'icmp[icmptype] = icmp-echo'
Yazdığın BPF filtresi kernel'a gönderilmeden önce derlenip doğrulanır. Hatalı bir filtre tcpdump: syntax error döner ve hiç paket yakalamadan çıkar. tcpdump -d 'filter' komutuyla BPF bytecode'unu insan-okunabilir formatta görebilirsin.
03 Çıktı kaydetme ve okuma
Canlı analiz yerine trafiği dosyaya kaydet, sonra analiz et. .pcap formatı standart — Wireshark da aynı formatı okur.
-w ile kaydetme
# Tüm trafiği capture.pcap dosyasına yaz
sudo tcpdump -nn -i eth0 -w capture.pcap
# Belirli trafiği kaydet (port 443)
sudo tcpdump -nn -i eth0 -w tls.pcap 'port 443'
# 1000 paket sonra dur
sudo tcpdump -nn -i eth0 -c 1000 -w sample.pcap
# Dönen dosyalar: 10 MB'dan büyüyünce yeni dosya aç, en fazla 5 dosya tut
# (ring buffer — embedded disk dolmaması için önemli)
sudo tcpdump -nn -i eth0 -C 10 -W 5 -w /tmp/cap.pcap
-r ile okuma
# Kayıtlı dosyayı oku ve göster
tcpdump -nn -r capture.pcap
# Dosyadan okurken de BPF filtresi uygulayabilirsin
tcpdump -nn -r capture.pcap 'port 80'
# Verbose ile tüm TCP oturumlarını listele
tcpdump -nn -v -r capture.pcap 'tcp'
# Paket sayısını öğren
tcpdump -r capture.pcap --count 'tcp'
Wireshark ile açma
.pcap dosyası endüstri standardıdır. Wireshark, tshark, scapy ve çoğu ağ analiz aracı bu formatı doğrudan açar. Embedded cihazda tcpdump ile yakala, .pcap'ı SCP ile geliştirme makinene kopyala, Wireshark'ta analiz et.
# Embedded cihazdan geliştirme makinesine kopyala
scp root@192.168.1.100:/tmp/capture.pcap ./
# tshark ile komut satırından gelişmiş analiz
tshark -r capture.pcap -T fields -e ip.src -e ip.dst -e tcp.dstport
# .pcap dosyasını .pcapng formatına dönüştür (editcap ile)
editcap -F pcapng capture.pcap capture.pcapng
Yoğun trafikte -w korumasız bırakılırsa disk hızla dolar. Ring buffer kullan (-C + -W) ya da yakalama süresini -G saniye ile sınırla. Embedded sistemlerde /tmp çoğunlukla tmpfs (RAM)tır — dikkatli ol.
04 Protocol decode — TCP, ARP, ICMP, DNS
tcpdump yakaladığı paketi protokolüne göre çözer ve anlamlı çıktı üretir.
TCP flags tablosu
ARP decode
# ARP request: "192.168.1.1'in MAC adresi kim?"
14:55:01.001 ARP, Request who-has 192.168.1.1 tell 192.168.1.10, length 28
# ARP reply: "192.168.1.1 benim, MAC adresim şu"
14:55:01.002 ARP, Reply 192.168.1.1 is-at aa:bb:cc:dd:ee:ff, length 28
# Sadece ARP trafiğini izlemek için
sudo tcpdump -nn -e -i eth0 'arp'
ICMP decode
# ping gönderme (echo request)
14:55:10.100 IP 192.168.1.10 > 8.8.8.8: ICMP echo request, id 1234, seq 1, length 64
# ping yanıtı (echo reply)
14:55:10.115 IP 8.8.8.8 > 192.168.1.10: ICMP echo reply, id 1234, seq 1, length 64
# TTL exceeded (traceroute'un ürettiği mesaj)
14:55:10.200 IP 10.0.0.1 > 192.168.1.10: ICMP time exceeded in-transit, length 68
# Port unreachable (kapalı UDP portuna erişim)
14:55:10.300 IP 10.0.0.2 > 192.168.1.10: ICMP 10.0.0.2 udp port 12345 unreachable, length 36
DNS sorgu/cevap decode
# DNS A sorgusu (client → server)
14:56:00.001 IP 192.168.1.10.52341 > 8.8.8.8.53: 12345+ A? example.com. (28)
# txid type soru
# DNS A cevabı (server → client)
14:56:00.020 IP 8.8.8.8.53 > 192.168.1.10.52341: 12345 1/0/0 A 93.184.216.34 (44)
# txid ans/auth/add yanıt
05 Pratik: HTTP trafiğini yakala
Şifreli olmayan HTTP trafiğini yakalayarak header ve body içeriğini görmek tcpdump'ın en klasik kullanımlarından biridir.
# Port 80 trafiğini ASCII olarak göster
sudo tcpdump -nn -A -i eth0 'port 80'
# Sadece PSH flag'li paketler — veri içeren paketler (HTTP request/response gövdesi)
sudo tcpdump -nn -A -i eth0 'port 80 and tcp[13] & 8 != 0'
# Sadece HTTP GET ve POST içeren paketler
# tcp[20:4] = TCP payload'ının ilk 4 byte'ı
sudo tcpdump -nn -A -i eth0 'tcp port 80 and (tcp[20:4] = 0x47455420 or tcp[20:4] = 0x504f5354)'
# 0x47455420 = "GET " (ASCII) 0x504f5354 = "POST"
# Bir sunucuya port 80 trafiğini dosyaya kaydet
sudo tcpdump -nn -i eth0 -w http.pcap 'host 192.168.1.50 and port 80'
Örnek bir HTTP request çıktısı şöyle görünür:
15:01:23.456789 IP 192.168.1.10.55001 > 192.168.1.50.80: Flags [P.], seq 1:78, ...
GET /api/status HTTP/1.1
Host: 192.168.1.50
User-Agent: curl/7.88.1
Accept: */*
HTTPS (port 443) trafiği şifrelendiği için tcpdump içeriği göremez — yalnızca TLS handshake görünür. İçerik analizi için Wireshark + pre-master secret log veya mitmproxy kullanmak gerekir.
06 Pratik: DNS sorgu izle
DNS trafiğini izlemek hem ağ sorunlarını teşhis etmek hem de cihazın hangi domain'lere sorgu yaptığını görmek için kullanılır.
# Port 53 UDP trafiğini izle
sudo tcpdump -nn -i eth0 'port 53'
# Sadece DNS sorguları (UDP)
sudo tcpdump -nn -i eth0 'udp port 53'
# Belirli bir DNS sunucusuna giden sorgular
sudo tcpdump -nn -i eth0 'dst host 8.8.8.8 and udp port 53'
# DNS cevaplarında NXDomain (çözülemeyen domain) bul
# DNS header byte 3, bit 0-3 = rcode: 3 = NXDOMAIN
sudo tcpdump -nn -v -i eth0 'udp port 53' | grep 'NXDomain\|NXDOMAIN'
# mDNS izle (embedded Zeroconf / Avahi)
sudo tcpdump -nn -i eth0 'udp port 5353'
DNS yanıt süresini ölçmek için timestamp farkına bak:
# -ttt ile paketler arası zaman farkını göster
sudo tcpdump -ttt -nn -i eth0 'port 53'
# 00:00:00.000000 IP ... 53: sorgu
# 00:00:00.015234 IP ... 53: cevap ← 15 ms yanıt süresi
DNS cevapları 512 bayttan büyükse (DNSSEC imzalı kayıtlar gibi) TCP port 53 kullanılır. port 53 filtresi hem UDP hem TCP'yi kapsar. Yalnızca TCP DNS için tcp port 53 kullan.
07 Pratik: SYN tarama tespiti
SYN taraması (half-open scan), nmap'in varsayılan tarama yöntemidir. Hedef porta SYN gönderir, SYN-ACK gelirse portu açık sayar ve RST ile bağlantıyı sonlandırır — tam bağlantı kurmaz.
Belirtisi: kısa sürede çok sayıda farklı porta SYN paketi, düşük sayıda SYN-ACK veya ACK paketi.
# Gelen SYN paketlerini sayım şeklinde izle
sudo tcpdump -nn -i eth0 'tcp[13] = 0x02' -l | \
awk '{print $3}' | \
cut -d. -f1-4 | \
sort | \
uniq -c | \
sort -rn
# Kısa sürede aynı kaynak IP'den 100+ SYN görüyorsan tarama var
# Belirli bir kaynaktan SYN'leri ve hedef portları göster
sudo tcpdump -nn -i eth0 'src host 10.0.0.5 and tcp[13] = 0x02'
# RST paketlerini izle — tarayıcı SYN-ACK alınca RST gönderir
sudo tcpdump -nn -i eth0 'tcp[13] & 0x04 != 0'
# SYN taramasının istatistik özeti için pcap kaydet ve analiz et
sudo tcpdump -nn -i eth0 -c 5000 -w /tmp/syn_scan.pcap 'tcp[13] = 0x02'
SYN taraması farklı portlara gider. SYN flood ise tek bir porta binlerce SYN gönderir (DoS). tcpdump'ta hedef portların dağılımına bak: tek port → flood, çok port → scan.
08 Embedded kullanım — busybox tcpdump
Embedded sistemlerde tam tcpdump olmayabilir. busybox tcpdump daha az özellik sunar ama çoğu kullanım için yeterlidir.
busybox tcpdump farkları
Minimal libpcap ile derleme (Buildroot / Yocto)
# Buildroot menuconfig'de
# BR2_PACKAGE_LIBPCAP=y
# BR2_PACKAGE_TCPDUMP=y
# ARM cross-compile örneği (manuel)
./configure --host=arm-linux-gnueabihf --without-crypto \
--disable-ipv6 --with-pcap=linux
make
# Statik binary (libpcap gömülü — rootfs'e libpcap koymak gerekmez)
make LDFLAGS="-static"
Cihazda çalıştırma — pratik senaryo
# Embedded cihaza tcpdump binary'sini kopyala
scp tcpdump root@192.168.1.100:/tmp/
ssh root@192.168.1.100 "chmod +x /tmp/tcpdump"
# Cihazda çalıştır, çıktıyı yerel makineye pipe'la
ssh root@192.168.1.100 "/tmp/tcpdump -nn -i eth0 -w - 'port 80'" | \
wireshark -k -i -
# Cihazda yakala, gerçek zamanlı Wireshark'ta izle
# SSH üzerinden canlı yakalama (Wireshark olmadan)
ssh root@192.168.1.100 "/tmp/tcpdump -nn -i eth0 -w - -c 500" > remote.pcap
Düşük işlemcili embedded cihazlarda tcpdump CPU'yu zorlayabilir. -s 96 ile sadece header'ları yakala (tam payload gerekmiyorsa), -nn ile DNS çözümlemesini kapat, BPF filtresiyle trafiği daralt. Ring buffer (-C + -W) ile tmpfs dolmasını önle.