guest@6admin.io:~$

tcpdump : analyse de trames et filtre BPF

Après Nemesis qui forge et raw sockets qui sniffent à la main, l’outil qui fait tout ça sans écrire une ligne de C: tcpdump. Si vous ne l’avez jamais utilisé, sachez que c’est probablement l’outil de diagnostic le plus rentable de toute votre carrière: une commande, un filtre et vous lisez le réseau en clair.

Le filtre BPF, le concept qui change tout

tcpdump seul affiche TOUT le trafic de l’interface. C’est inutilisable sur un réseau actif: vous êtes noyé en dix secondes. La magie vient du filtre BPF (Berkeley Packet Filter), un langage d’expression compilé à la volée dans le kernel pour ne capturer que ce qui matche:

# Tout le trafic HTTP de mon poste vers un serveur précis
tcpdump -i eth0 host 192.168.1.100 and port 80

# Les SYN (tentatives de connexion) entrants
tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0'

# Le trafic DNS
tcpdump -i eth0 port 53

# Ce qui arrive de l'extérieur
tcpdump -i eth0 src net not 192.168.1.0/24

La syntaxe BPF se lit comme un anglais approximatif: host X, port Y, src, dst, and, or, not. Les opérations bit à bit sur les flags TCP (tcp[tcpflags] & tcp-syn) permettent de sélectionner précisément le type de paquet sans parseur.

Lire les trames

# Verbose, les en-têtes complètes
tcpdump -vvv -i eth0 port 53

# Hex + ASCII, pour les paquets qui ne se laissent pas lire
tcpdump -X -i eth0 port 80

# Limiter à N paquets
tcpdump -c 100 -i eth0

La sortie verbose donne chaque champ décodé: TTL, flags, options et pour le DNS, les enregistrements de la réponse. C’est le mode d’emploi gratuit de n’importe quel protocole: lancez tcpdump, faites l’action dans une autre fenêtre, lisez ce qui passe vraiment.

Ce que ça sert en vrai

Trois diagnostics que j’ai faits cette semaine avec tcpdump et qui auraient pris des heures autrement:

  1. “Le mail ne passe pas”: tcpdump port 25 et on voit le serveur distant répondre RST. Firewall chez l’hébergeur, pas chez nous.
  2. “Le site est lent”: tcpdump port 80 et on voit le serveur répondre en trois paquets puis DNS re-query entre chaque. Cache DNS vide à chaque requête, TTL à zéro.
  3. “On se fait scanné”: tcpdump ’tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack == 0’ et on compte les sources. Plus de dix SYN/s sans ACK depuis la même IP, c’est un scan.

Pour ceux qui écrivent en C

Si vous avez lu l’article sur les raw sockets , vous savez que tcpdump fait ce que votre code C fait: un socket(AF_PACKET, SOCK_RAW), un filtre BPF appliqué via setsockopt(SO_ATTACH_FILTER) et un recvfrom() en boucle. tcpdump ne fait pas de magie, il fait exactement ce que vous savez déjà écrire, mais avec vingt ans de debugging de plus.