Como administrador de redes e implementador de tecnologias VoIP (um tal de asterisk, saca? ), raramente há um dia no qual eu não utilize o tcpdump para detectar problemas ou depurar o tráfego de rede.
Este software, disponível em tcpdump.org possibilita visualizar a informação que trafega pelas interfaces de rede, dando ao administrador condições de compreender a origem e destino dos pacotes, portas origem/destino, e constatar o bom funcionamento da rede ou detectar e corrigir eventuais problemas.
Por fazer uso da libpcap, (disponível no mesmo site do tcpdump), o sistema de filtros que irei descrever aqui pode ser utilizado em praticamente qualquer sniffer que faça uso da libpcap, como o Wireshark, Etherape* e outros.
Bom, se você executar o comando tcpdump (como root ou usando o sudo) na sua estação de trabalho, devem aparecer algumas coisas não tão emocionantes assim, como um eventual acesso a uma página web ou ssh para outro servidor.
Dica: Se você tiver acesso a um servidor/firewall/roteador baseado em linux, as coisas irão ficar mais divertidas ;)
Dica2: O parametro -i na linha abaixo específica a interface de rede, no caso, en1.
bash-3.2# tcpdump -i en1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en1, link-type EN10MB (Ethernet), capture size 96 bytes
16:37:41.820798 IP hermes.jabber.org.jabber-client > 172.25.50.1.49185: Flags [P.], ack 101, win 501, options [nop,nop,TS val 2786794633 ecr 32003128], length 314
16:37:41.820868 IP 172.25.50.1.49185 > hermes.jabber.org.jabber-client: Flags [.], ack 315, win 65535, options [nop,nop,TS val 32003131 ecr 2786794633], length 0
Aqui, temos o IP 172.25.50.1, na porta 49185 conversando com o servidor hermes.jabber.org na porta jabber-client (!?), ou seja, a notação do tcpdump é a seguinte:
ip_origem.porta > ip_destino.porta
É exatamente neste momento que entra a importancia de conhecer alguns parámetros bacanas e os filtros.
No próximo exemplo, usarei o parametro -n, para não resolver nomes.
bash-3.2# tcpdump -i -n en1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en1, link-type EN10MB (Ethernet), capture size 96 bytes
16:54:49.305931 IP 208.68.163.220.5222 > 172.25.50.1.49478: Flags [P.], ack 3024, win 501, options [nop,nop,TS val 2787051513 ecr 32013390], length 234
16:54:49.306025 IP 172.25.50.1.49478 > 208.68.163.220.5222: Flags [.], ack 40285, win 65535, options [nop,nop,TS val 32013393 ecr 2787051513], length 0
Creio que fizemos algum progresso, certo?
Sabemos como olhar origem/destino, sem resolver nomes, porém, se você fizer isso em uma tarde movimentada em um servidor com muitos acessos, você vai literalmente ter uma enxorrada de caracteres em sua tela.
É ai que entram os filtros.
Como o próprio nome diz, os filtros são capazes de capturar e exibir apenas os pacotes dentro de um padrão especificado por vossa mercê logo após os parametros.
O comando abaixo tem como objetivo capturar apenas os pacotes que tenham como origem o IP 172.25.50.1.
bash-3.2# tcpdump -i en1 -n src 172.25.50.1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en1, link-type EN10MB (Ethernet), capture size 96 bytes
17:03:57.966875 IP 172.25.50.1.49478 > 208.68.163.220.5222: Flags [P.], ack 1791748800, win 65535, options [nop,nop,TS val 32018873 ecr 2787180975], length 101
17:03:58.125112 IP 172.25.50.1.49478 > 208.68.163.220.5222: Flags [.], ack 315, win 65535, options [nop,nop,TS val 32018875 ecr 2787188714], length 0
17:03:58.402324 IP 172.25.50.1.49186 > 207.46.124.87.1863: Flags [P.], ack 4218053211, win 65535, options [nop,nop,TS val 32018878 ecr 40801509], length 5
17:03:58.592978 IP 172.25.50.1.49186 > 207.46.124.87.1863: Flags [.], ack 9, win 65535, options [nop,nop,TS val 32018880 ecr 40801810], length 0
Agora, mais filtros.
Capturando pacotes com origem em 172.25.50.1 e destino sendo 201.XXX.XXX.XXX
bash-3.2# tcpdump -i en1 -n src 172.25.50.1 and dst 201.XXX.XXX.XXX
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en1, link-type EN10MB (Ethernet), capture size 96 bytes
17:24:41.016407 IP 172.25.50.1.49593 > 201.XXX.XXX.XXX.22: Flags [P.], ack 482545008, win 65535, options [nop,nop,TS val 32031289 ecr 121570066], length 48
Capturando pacotes com origem em 172.25.50.1 e destino 201.XXX.XXX.XXX, com exeção da porta 22 ;)
bash-3.2# tcpdump -i en1 -n src 172.25.50.1 and dst 201.XXX.XXX.XXX and port not 22
(Ok, eu usei um telnet para testar ;)
17:29:04.685025 IP 172.25.50.1.49614 > 201.XXX.XXX.XXX.23: Flags [S], seq 982381860, win 65535, options [mss 1460,nop,wscale 3,nop,nop,TS val 32033923 ecr 0,sackOK,eol], length 0
Capturando pacotes do tipo DNS. (udp, porta 53)
bash-3.2# tcpdump -i en1 -n udp and host 4.2.2.2 and port 53
(o comando usado para testar foi: dig -t any google.com.br. @4.2.2.2 )
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en1, link-type EN10MB (Ethernet), capture size 96 bytes
17:30:42.622847 IP 172.25.50.1.57322 > 4.2.2.2.53: 38414+ ANY? www.google.com.br. (35)
17:30:42.772963 IP 4.2.2.2.53 > 172.25.50.1.57322: 38414 1/0/0 CNAME[|domain]
Felizmente, o tcpdump é um software com uma curva de aprendizado incrivelmente curta e de uma utilidade imensa. Para maiores referencias, consulte esta documentação aqui, que relata os filtros existentes para a libpcap/tcpdump.
http://www.cs.ucr.edu/~marios/ethereal-tcpdump.pdf
Em 2006, eu escrevi este artigo aqui, sobre o etherape (ignore a parte que eu falo mal dos filtros, coisa de iniciante ;)
http://www.vivaolinux.com.br/artigo/Apresentando-o-monitor-de-redes-EtherApe/