Como capturar e analisar o tráfego de rede com tcpdump?

tcpdump é uma incrível ferramenta de linha de comando para sniffing de rede. É um padrão da indústria para capturar e analisar pacotes TCP/IP.

A ferramenta tcpdump pode ser de grande ajuda ao resolver problemas de rede. Os pacotes podem ser salvos em um arquivo e posteriormente analisados. É uma boa ideia executar esta ferramenta ocasionalmente para vigiar sua rede.

Como é a saída do tcpdump?

tcpdump permite examinar os cabeçalhos dos pacotes TCP/IP. Ele imprime uma linha para cada pacote e o comando continua em execução até que você pressione Ctrl+C para terminar.

Vamos examinar uma linha de uma saída de exemplo:

20:58:26.765637 IP 10.0.0.50.80 > 10.0.0.1.53181: Flags [F.], seq 1, ack 2, win 453, options [nop,nop,TS val 3822939 ecr 249100129], length 0

Cada linha inclui

  • Carimbo de data/hora Unix (20:58:26.765637)
  • protocolo (IP)
  • o nome do host ou IP de origem e o número da porta (10.0.0.50.80)
  • nome do host ou IP de destino e número da porta (10.0.0.1.53181)
  • Sinalizadores TCP (Bandeiras [F.]). Os sinalizadores indicam o estado da conexão. Isso pode incluir mais de um valor, como neste exemplo [F.] para FIN-ACK. Este campo pode ter os seguintes valores:
    • S – SIN. O primeiro passo para estabelecer a conexão.
    • F-FIN. Terminação da conexão.
    • . – ACK. Pacote de confirmação recebido com sucesso.
    • P – EMPURRAR. Diz ao receptor para processar pacotes em vez de armazená-los em buffer.
    • R – RST. A comunicação parou.
  • Número de sequência dos dados no pacote. (seq 1)
  • Número de confirmação (ack 2)
  • Tamanho da janela (win 453). O número de bytes disponíveis no buffer de recebimento. Isso é seguido pelas opções de TCP.
  • Comprimento da carga de dados. (comprimento 0)

Instalação

Em distribuições baseadas em Debian, o tcpdump pode ser instalado com o comando APT:

# apt install tcpdump -y

Em distribuições baseadas em RPM, o tcpdump pode ser instalado com YUM:

# yum install tcpdump -y

Ou usando DNF se RHEL 8

# dnf install tcpdump -y

opções de comando tcpdump

Você precisa ser root para executar o tcpdump. Inclui muitas opções e filtros. A execução do tcpdump sem nenhuma opção capturará todos os pacotes que fluem pela interface padrão.

Para ver a lista de interfaces de rede disponíveis no sistema e nas quais o tcpdump pode capturar pacotes.

# tcpdump -D

Ou

# Tcpdump --list-interfaces
1.eth0
2.nflog (Linux netfilter log (NFLOG) interface)
3.nfqueue (Linux netfilter queue (NFQUEUE) interface)
4.eth1
5.any (Pseudo-device that captures on all interfaces)
6.lo [Loopback]

Isso é especialmente útil em sistemas que não possuem um comando para listar interfaces.

  Por que as lentes de boas câmeras são tão importantes?

Para capturar pacotes que fluem por uma interface específica, use o sinalizador -i com o nome da interface. Sem a interface -i, o tcpdump selecionará a primeira interface de rede que encontrar.

# tcpdump -i eth1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
01:06:09.278817 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 4761, seq 1, length 64
01:06:09.279374 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 4761, seq 1, length 64
01:06:10.281142 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 4761, seq 2, length 64

O sinalizador -v aumenta as informações que você vê sobre os pacotes, -vv fornece ainda mais detalhes.

Por padrão, o tcpdump resolve endereços IP para nomes de host e também usa nomes de serviço em vez de números de porta. Se o DNS estiver quebrado ou você não quiser que o tcpdump execute pesquisas de nome, use a opção -n.

# tcpdump -n
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
04:19:07.675216 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 2186733178:2186733278, ack 204106815, win 37232, length 100
04:19:07.675497 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 100, win 65535, length 0
04:19:07.675747 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 100:136, ack 1, win 37232, length 36
04:19:07.675902 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 136, win 65535, length 0
04:19:07.676142 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 136:236, ack 1, win 37232, length 100

Para capturar apenas um conjunto de linhas, digamos 5, use o sinalizador -c:

#tcpdump -c 5
04:19:07.675216 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 2186733178:2186733278, ack 204106815, win 37232, length 100
04:19:07.675497 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 100, win 65535, length 0
04:19:07.675747 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 100:136, ack 1, win 37232, length 36
04:19:07.675902 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 136, win 65535, length 0
04:19:07.676142 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 136:236, ack 1, win 37232, length 100
5 packets captured

A saída tcpdump padrão usa timestamps Unix. Para capturar pacotes com timestamp legível por humanos:

# tcpdump -tttt
2020-07-06 04:30:12.203638 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 2186734102:2186734138, ack 204107103, win 37232, length 36
2020-07-06 04:30:12.203910 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 36, win 65535, length 0
2020-07-06 04:30:12.204292 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 36:72, ack 1, win 37232, length 36
2020-07-06 04:30:12.204524 IP 10.0.2.2.50422 > 10.0.2.15.22: Flags [.], ack 72, win 65535, length 0
2020-07-06 04:30:12.204658 IP 10.0.2.15.22 > 10.0.2.2.50422: Flags [P.], seq 72:108, ack 1, win 37232, length 36

expressões de filtro tcpdump

As expressões de filtro selecionam quais cabeçalhos de pacote serão exibidos. Se nenhum filtro for aplicado, todos os cabeçalhos de pacote serão exibidos. Os filtros comumente usados ​​são porta, host, src, dst, tcp, udp, icmp.

  Como cancelar o envio de mensagens no iPhone, iPad e Mac

filtro de porta

Use o filtro de porta para ver os pacotes que chegam em uma porta específica:

# Tcpdump -i eth1 -c 5 port 80
23:54:24.978612 IP 10.0.0.1.53971 > 10.0.0.50.80: Flags [SEW], seq 53967733, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 256360128 ecr 0,sackOK,eol], length 0
23:54:24.978650 IP 10.0.0.50.80 > 10.0.0.1.53971: Flags [S.E], seq 996967790, ack 53967734, win 28960, options [mss 1460,sackOK,TS val 5625522 ecr 256360128,nop,wscale 6], length 0
23:54:24.978699 IP 10.0.0.1.53972 > 10.0.0.50.80: Flags [SEW], seq 226341105, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 256360128 ecr 0,sackOK,eol], length 0
23:54:24.978711 IP 10.0.0.50.80 > 10.0.0.1.53972: Flags [S.E], seq 1363851389, ack 226341106, win 28960, options [mss 1460,sackOK,TS val 5625522 ecr 256360128,nop,wscale 6], length 0

filtro de host

Para capturar todos os pacotes que chegam ou saem do host com endereço IP de 10.0.2.15:

# tcpdump host 10.0.2.15
03:48:06.087509 IP 10.0.2.15.22 > 10.0.2.2.50225: Flags [P.], seq 3862934963:3862934999, ack 65355639, win 37232, length 36
03:48:06.087806 IP 10.0.2.2.50225 > 10.0.2.15.22: Flags [.], ack 36, win 65535, length 0
03:48:06.088087 IP 10.0.2.15.22 > 10.0.2.2.50225: Flags [P.], seq 36:72, ack 1, win 37232, length 36
03:48:06.088274 IP 10.0.2.2.50225 > 10.0.2.15.22: Flags [.], ack 72, win 65535, length 0
03:48:06.088440 IP 10.0.2.15.22 > 10.0.2.2.50225: Flags [P.], seq 72:108, ack 1, win 37232, length 36

Para capturar pacotes de um tipo de protocolo específico, por exemplo, icmp, na interface eth1:

# tcpdump -i eth1 icmp
04:03:47.408545 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 2812, seq 75, length 64
04:03:47.408999 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 2812, seq 75, length 64
04:03:48.408697 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 2812, seq 76, length 64
04:03:48.409208 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 2812, seq 76, length 64
04:03:49.411287 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 2812, seq 77, length 64

Combinando expressões de filtro

Você pode combinar essas expressões de filtro com os operadores AND, OR e NOT. Isso permitirá que você escreva comandos que podem isolar pacotes com mais precisão:

  Você pode desativar as chamadas de emergência 911 em um iPhone?

Pacotes de um IP específico e destinados a uma porta específica:

# tcpdump -n -i eth1 src 10.0.0.1 and dst port 80
00:18:17.155066 IP 10.0.0.1.54222 > 10.0.0.50.80: Flags [F.], seq 500773341, ack 2116767648, win 4117, options [nop,nop,TS val 257786173 ecr 5979014], length 0
00:18:17.155104 IP 10.0.0.1.54225 > 10.0.0.50.80: Flags [S], seq 904045691, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 257786173 ecr 0,sackOK,eol], length 0
00:18:17.157337 IP 10.0.0.1.54221 > 10.0.0.50.80: Flags [P.], seq 4282813257:4282813756, ack 1348066220, win 4111, options [nop,nop,TS val 257786174 ecr 5979015], length 499: HTTP: GET / HTTP/1.1
00:18:17.157366 IP 10.0.0.1.54225 > 10.0.0.50.80: Flags [.], ack 1306947508, win 4117, options [nop,nop,TS val 257786174 ecr 5983566], length 0

Para capturar todos os pacotes, exceto ICMP, use o operador NOT:

# tcpdump -i eth1 not icmp

Salvando cabeçalhos de pacotes em um arquivo

Como a saída do tcpdump pode rolar pela tela rapidamente, você pode armazenar cabeçalhos de pacotes em um arquivo com o sinalizador -w. Os arquivos para salvar a saída usam o formato pcap e têm uma extensão .pcap.

PCAP significa captura de pacotes. O comando a seguir salva 10 linhas de saída na interface eth1 para icmp.pcap.

# tcpdump -i eth1 -c 10 -w icmp.pcap
tcpdump: listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes
10 packets captured
10 packets received by filter
0 packets dropped by kernel

Você pode ler este arquivo com o sinalizador -r:

tcpdump -r icmp.pcap
reading from file icmp.pcap, link-type EN10MB (Ethernet)
05:33:20.852732 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 3261, seq 33, length 64
05:33:20.853245 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 3261, seq 33, length 64
05:33:21.852586 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 3261, seq 34, length 64
05:33:21.853104 IP 10.0.0.51 > vagrant-ubuntu-trusty-64: ICMP echo reply, id 3261, seq 34, length 64
05:33:22.852615 IP vagrant-ubuntu-trusty-64 > 10.0.0.51: ICMP echo request, id 3261, seq 35, length 64

Visualizando detalhes do pacote

Até agora, vimos apenas os cabeçalhos dos pacotes, para visualizar o conteúdo dos pacotes, use a opção -A. Isso imprime o conteúdo do pacote em ASCII, o que pode ajudar na solução de problemas de rede. Além disso, o sinalizador -X pode ser usado para exibir a saída em formato hexadecimal. Isso pode não ser de muita ajuda se a conexão estiver criptografada.

# tcpdump -c10 -i eth1 -n -A port 80
23:35:53.109306 IP 10.0.0.1.53916 > 10.0.0.50.80: Flags [P.], seq 2366590408:2366590907, ack 175457677, win 4111, options [nop,nop,TS val 255253117 ecr 5344866], length 499: HTTP: GET / HTTP/1.1
E..'[email protected]@.%.
...
..2...P..M.
uE............
.6.}.Q.bGET / HTTP/1.1
Host: 10.0.0.50
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
If-Modified-Since: Tue, 04 Mar 2014 11:46:45 GMT

Conclusão

O tcpdump é fácil de configurar e, depois de entender a saída, os vários sinalizadores e filtros, ele pode ser usado para resolver problemas de rede e proteger sua rede.