tcpdump_logo

O tcpdump é um sniffer (ferramenta para captura do tráfego de rede) textual disponível em qualquer distribuição do Linux e é uma excelente ferramenta para troubleshoot – não necessariamente a melhor (depende do tipo de análise que se deseja). Neste texto farei uma introdução básica desta excelente ferramenta, demonstrando as principais opções de filtragem.

Existem outros sniffers poderosos, como: “ngrep, ettercap ou wireshark“, por exemplo. Mas, todos contam algo em comum: “a biblioteca libpcap“. Logo, como são soluções baseadas na mesma biblioteca de rede, a sintaxe de filtragem tende ser a mesma, facilitando o trabalho (e aprendizado) do administrador.

A sintaxe de filtragem segue um padrão conhecido como BPF ou Berkeley Packet Filter. Uma vez que você domine este padrão, terá maior facilidade para trabalhar com diferentes ferramentas. Sistemas de IPS/IDS, como Suricata ou Snort, permitem a utilização de filtros globais BPF para selecionar qual tráfego será inspecionado.

É possível trabalhar com filtros extremamente flexíveis. Você pode até duvidar (risos), mas a habilidade na construção ou combinação destes filtros será proporcional a sua habilidade em lógica de programação, por causa dos operadores lógicos. Para quem sente dificuldade, uma alternativa é estudar e treinar TABELA VERDADE.

No wireshark, a complexidade é um pouco maior porque a ferramenta oferece recursos de filtragem para captura de pacotes e análise do tráfego capturado (exibição). Portanto, o administrador pode incluir um filtro BPF para estabelecer qual fluxo de pacotes será capturado (via libpcap), mas o filtro sobre o resultado exibido segue padrões estabelecidos pela ferramenta.

A escolha da ferramenta depende do tipo de análise. Para diagnosticar a “reação de um firewall” ou disponibilidade de um serviço qualquer, começo a avaliação com o tcpdump (por exemplo). Na maioria das vezes, obtenho a resposta que desejo rapidamente e sem grandes complicações. Caso o resultado não seja conclusivo e eu necessite de uma avaliação de conteúdo (obtendo a resposta do servidor, por exemplo), opto pelo ngrep. Em casos mais específicos (de difícil diagnóstico), direciono a saída do tcpdump para arquivo (em formato pcap) e avalio posteriormente via ngrep ou wireshark.

Suponhamos que uma aplicação específica esteja indisponível e você precisa certificar que o firewall não está impedindo tal conexão. Neste caso, como temos um alvo fixo e avaliaremos apenas a conexão em tempo real, não compensa trabalhar com ferramentas de alto nível (avaliação de conteúdo/aplicação).

1. Política de acesso (firewall): Default DROP
2. Servidor: 192.168.0.100
3. Interface por onde as requisições originam: eth0
4. Interface pertencente a rede 192.168.0.0/24 (ou caminho): eth1

– Para confirmação de recebimento

tcpdump -i eth0 host 192.168.0.100 -n

– Para confirmação de encaminhamento

tcpdump -i eth1 host 192.168.0.100 -n

Em um firewall configurado com política de acesso default drop, o comum é descartar silenciosamente (DROP) qualquer fluxo que não seja previamente autorizado. Logo, caso o bloqueio aconteça, nenhum pacote de resposta será retornado e observaremos uma retransmissão frequente. Esta característica já revela muita coisa…

No primeiro exemplo, na maioria das vezes, se capturarmos um pacote TCP com sinalização de conexão (SYN) e, logo em seguida, uma resposta de desconexão forçada com RESET (RST), podemos encerrar a análise e solicitar ao analista a verificação da disponibilidade do serviço. Quando você solicita acesso a um socket TCP que não está disponível no momento, o servidor devolve um RST.

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
10:23:45.282808 IP 10.0.0.10.58092 > 192.168.0.100.443: Flags [S], seq 135198062, win 29200, options [mss 1460,sackOK,TS val 13045642 ecr 0,nop,wscale 7], length 0
10:23:45.283043 IP 192.168.0.100.443 > 10.0.0.10.58092: Flags [R.], seq 0, ack 135198063, win 0, length 0

Uma resposta como a anterior pode ser gerada pelo firewall caso o administrador configure uma regra com alvo REJECT prevendo o fluxo analisado. Eu aplico este tipo de filtro em casos muito específicos, quando identifico a necessidade de encerrar uma conexão imediatamente, sem que isto cause grande delay aos clientes.

Mas, na maioria das vezes, opto pelo “descarte silencioso”. Portanto, no meu caso, este resultado seria conclusivo rapidamente. 😉

O segundo exemplo, para confirmação de encaminhamento, é útil quando a primeira captura não exibe resposta alguma e desejamos certificar que o firewall não impediu o roteamento.

Caso a primeira captura revele sucessivas retransmissões, refaça o processo selecionando, agora, a interface por onde o pacote deve ser encaminhado. Caso você não visualize esta retransmissão, é sinal que o firewall está impedindo o encaminhamento – chega por uma interface, mas não é encaminhado por outra. Dependendo da criticidade do momento, o ideal é abrir dois terminais remotos e executar os comandos simultaneamente.

Simples, não? Mas, em muitos casos, será inviável – para não dizer impossível – acompanhar o tráfego que envolve determinado servidor sem trabalhar com operadores lógicos para selecionar apenas o tráfego desejado.

# O primeiro exemplo permite capturar o tráfego de qualquer pacote que envolva o servidor 192.168.0.100, desde que a porta seja diferente da 22.
# No segundo exemplo, ao invés de negar apenas uma porta (permitindo todas as demais), limitamos a captura às portas 25 ou 587 simultaneamente.

tcpdump -i any host 192.168.0.100 and not port 22 -n
tcpdump -i any "host 192.168.0.100 and (port 25 or 587)" -n
# No próximo exemplo a essência lógica foi preservada. Porém, limitando aos hosts.
# Percebam que a utilização do "and" entre os hosts resultaria em uma sentença sempre falsa (esta condição não pode ser verdadeira para dois endereços diferentes no mesmo fluxo de pacotes)

tcpdump -i any net 10.0.0.0/24 and host 192.168.0.100 -n 
tcpdump -i any "net 10.0.0.0/24 and (host 192.168.0.100 or 192.168.0.101)" -n
# Neste último exemplo, explorei um pouco mais os operadores lógicos...
# O mesmo filtro permite capturar dois fluxos de conexão:
# - Tráfego da rede 10.0.0.0/24 que envolva a porta TCP 80; ou
# - Tráfego da rede 10.0.0.0/24 e servidores 192.168.0.100 ou 192.168.0.101

tcpdump -i any "net 10.0.0.0/24 and (tcp port 80 or (host 192.168.0.100 or 192.168.0.101))" -n

Em alguns casos, para facilitar a análise, podemos direcionar a saída para um arquivo específico e filtrar cada fluxo individualmente. É possível ler o arquivo pelo tcpdump e, a qualquer momento, aplicar todos os recursos de filtragem disponíveis na captura em tempo real.

– Para direcionar a saída para um arquivo, utilize a opção -w:

tcpdump -i eth0 host 192.168.0.100 -s 1500 -w /tmp/host100.pcap -n

– Para ler o conteúdo de um arquivo pcap, utilize a opção -r:

tcpdump -r /tmp/host100.pcap host 192.168.0.100 -s 1500 -n
tcpdump -r /tmp/host100.pcap host 192.168.0.100 and udp port 53 -n

Ainda podemos “ler” o tráfego armazenado em determinado arquivo, filtrar novamente e “escrever” em outro arquivo. Feito a análise inicial, o administrador pode entender que o único tráfego que lhe interessa avaliar mais criteriosamente está relacionado ao protocolo UDP.

Neste caso, é possível direcionar para outro arquivo e analisar no wireshark:

tcpdump -r /tmp/host100.pcap udp -w /tmp/host100udp.pcap -s 1500 -n