O tcpdump é uma ferramenta de linha de comando notável para a inspeção de tráfego de rede. Ele se estabeleceu como um padrão na indústria para a captura e análise de pacotes TCP/IP.
Esta ferramenta pode ser incrivelmente útil na resolução de problemas de rede. Os pacotes podem ser armazenados em um arquivo para posterior análise. É aconselhável executar essa ferramenta periodicamente para monitorar a sua rede.
Entendendo a Saída do tcpdump
tcpdump permite examinar os cabeçalhos dos pacotes TCP/IP. A ferramenta exibe uma linha para cada pacote capturado e continua a operar até que você a interrompa com Ctrl+C.
Vamos analisar uma linha de exemplo da saída:
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 contém:
- O registro de data e hora Unix (20:58:26.765637)
- O protocolo (IP)
- O endereço IP ou nome do host de origem e o número da porta (10.0.0.50.80)
- O endereço IP ou nome do host de destino e o número da porta (10.0.0.1.53181)
- Os sinalizadores TCP (Flags [F.]). Estes indicam o estado da conexão, podendo incluir múltiplos valores. Neste exemplo, [F.] significa FIN-ACK. Este campo pode apresentar os seguintes valores:
- S – SIN. O primeiro passo para estabelecer a conexão.
- F-FIN. O encerramento da conexão.
- . – ACK. Confirmação de um pacote recebido com sucesso.
- P – PUSH. Instrui o receptor a processar os pacotes imediatamente, sem armazená-los em buffer.
- R – RST. Indica que a comunicação foi interrompida.
- O número de sequência dos dados no pacote (seq 1)
- O número de confirmação (ack 2)
- O tamanho da janela (win 453), representando o número de bytes disponíveis no buffer de recebimento, seguido pelas opções TCP.
- O comprimento da carga útil de dados (length 0).
Processo de Instalação
Em sistemas baseados em Debian, o tcpdump pode ser instalado através do comando APT:
# apt install tcpdump -y
Em sistemas baseados em RPM, a instalação é feita com YUM:
# yum install tcpdump -y
Ou, se estiver usando RHEL 8, use DNF:
# dnf install tcpdump -y
Opções do Comando tcpdump
É necessário ter privilégios de root para executar o tcpdump. A ferramenta inclui diversas opções e filtros. Ao executá-la sem opções, todos os pacotes que trafegam pela interface padrão serão capturados.
Para verificar a lista de interfaces de rede disponíveis para captura, use:
# 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]
Este comando é particularmente útil em sistemas onde não há um comando nativo para listar as interfaces.
Para capturar pacotes que passam por uma interface específica, utilize o parâmetro -i seguido do nome da interface. Se a interface não for especificada com -i, o tcpdump selecionará a primeira interface de rede encontrada.
# 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 parâmetro -v aumenta a quantidade de informações exibidas sobre os pacotes, e -vv fornece ainda mais detalhes.
Por padrão, o tcpdump tenta resolver endereços IP em nomes de host e também usa nomes de serviço em vez de números de porta. Para evitar pesquisas de nome, utilize 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 um número específico de linhas, use o parâmetro -c, por exemplo, para capturar 5 linhas:
#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 padrão do tcpdump utiliza timestamps Unix. Para visualizar os pacotes com timestamps legíveis por humanos, utilize:
# 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
As expressões de filtro determinam quais cabeçalhos de pacote serão exibidos. Sem filtros, todos os cabeçalhos são exibidos. Filtros comuns incluem porta, host, src, dst, tcp, udp, e icmp.
Filtragem por Porta
Para visualizar pacotes que chegam a 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
Filtragem por Host
Para capturar todos os pacotes que entram ou saem de um host com o endereço IP 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 protocolo específico, como 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 Filtros
Filtros podem ser combinados com os operadores AND, OR e NOT, permitindo isolar pacotes com maior precisão.
Para pacotes de um IP específico 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 Pacotes em Arquivo
Como a saída do tcpdump pode passar rapidamente pela tela, você pode armazenar os cabeçalhos dos pacotes em um arquivo com o parâmetro -w. Os arquivos para salvar a saída usam o formato pcap e têm a extensão .pcap.
PCAP significa captura de pacotes. O seguinte comando salva 10 linhas da 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
O arquivo pode ser lido com o parâmetro -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 o Conteúdo dos Pacotes
Até agora, vimos apenas os cabeçalhos dos pacotes. Para visualizar o conteúdo, utilize a opção -A. Isso imprime o conteúdo do pacote em ASCII, o que pode auxiliar na solução de problemas de rede. Alternativamente, -X pode ser usado para exibir a saída em formato hexadecimal, útil se a conexão nã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 é uma ferramenta de fácil configuração que, após a compreensão da sua saída, diversos parâmetros e filtros, pode ser uma ferramenta valiosa na resolução de problemas e na segurança da rede.