Tutorial del comando tcpdump de Linux para principiantes (8 ejemplos)

Cada vez que abres una página web en tu ordenador, se envían y reciben paquetes de datos en tu interfaz de red. A veces, analizar estos paquetes es importante por muchas razones. Afortunadamente, Linux ofrece una utilidad de línea de comandos que vuelca la información relacionada con estos paquetes de datos en la salida.

En este artículo, hablaremos de los fundamentos de la herramienta en cuestión: tcpdump. Pero antes de hacerlo, vale la pena mencionar que todos los ejemplos aquí se han probado en una máquina Ubuntu 18.04 LTS y en Debian 10, pero también funcionará en otras distribuciones de Linux como CentOS, Fedora, Gentoo y Arch Linux.

Comando tcpdump de Linux

El comando tcpdump en Linux te permite volcar el tráfico en una red. A continuación se presenta su sintaxis resumida:

tcpdump [OPTIONS]

Aquí tienes la sintaxis detallada:

tcpdump [ -AbdDefhHIJKlLnNOpqStuUvxX# ] [ -B buffer_size ]
               [ -c count ]
               [ -C file_size ] [ -G rotate_seconds ] [ -F file ]
               [ -i interface ] [ -j tstamp_type ] [ -m module ] [ -M secret ]
               [ --number ] [ -Q in|out|inout ]
               [ -r file ] [ -V file ] [ -s snaplen ] [ -T type ] [ -w file ]
               [ -W filecount ]
               [ -E spi@ipaddr algo:secret,...  ]
               [ -y datalinktype ] [ -z postrotate-command ] [ -Z user ]
               [ --time-stamp-precision=tstamp_precision ]
               [ --immediate-mode ] [ --version ]
               [ expression ]

Y así es como lo explica la página man de la herramienta:

Tcpdump prints out a description of the contents of packets on a network interface that match the 
boolean expression; the description is preceded by a time stamp, printed, by default, as hours,
minutes, seconds, and fractions of a second  since  midnight.  

It can  also  be  run with the -w flag, which causes it to save the packet data to a file for
later analysis, and/or with the -r flag, which causes it to read from a saved packet file rather
than to read packets from a network interface.  It can also be run with the -V  flag,  which causes
it to read a list of saved packet files.

In all cases, only packets that match expression will be processed by tcpdump.

A continuación se presentan algunos ejemplos al estilo de las preguntas y respuestas que deberían darte una mejor idea de cómo funciona el comando tcpdump.

Q1. ¿Cómo utilizar tcpdump?

Antes de utilizar tcpdump para olfatear paquetes de datos, lo ideal es que sepas en qué interfaz de red quieres que funcione la herramienta. Para obtener una lista de las interfaces de red disponibles en el sistema, utiliza la opción de línea de comandos -D con tcpdump.

tcpdump -D

Así es como la página de manual explica esta opción:

Print the list of the network interfaces available on the system and on which tcpdump can capture 
packets. For each network interface, a number and an interface name, possibly followed by a text
description of the interface, is printed. The interface name or the number can be supplied to the
-i flag to specify an interface on which to capture.

This can be useful on systems that don't have a command to list them (e.g., Windows systems, or
UNIX systems lacking  ifconfig -a); the number can be useful on Windows 2000 and later systems,
where the interface name is a somewhat complex string.

The  -D  flag  will not be supported if tcpdump was built with an older version of libpcap that
lacks the pcap_findalldevs() function.

Por ejemplo, en mi caso, se produjo la siguiente salida:

1.wlx18a6f713679b [Up, Running]
2.any (Pseudo-device that captures on all interfaces) [Up, Running]
3.lo [Up, Running, Loopback]
4.enp3s0 [Up]
5.nflog (Linux netfilter log (NFLOG) interface)
6.nfqueue (Linux netfilter queue (NFQUEUE) interface)
7.usbmon1 (USB bus number 1)
8.usbmon2 (USB bus number 2)
9.usbmon3 (USB bus number 3)
10.usbmon4 (USB bus number 4)

Ahora que tienes una lista de interfaces, puedes elegir una y pasar su nombre como entrada a la opción de línea de comandos -i de tcpdump. Por ejemplo:

tcpdump -i wlx18a6f713679b

A continuación se muestra una parte de la salida producida por este comando en mi caso:

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlx18a6f713679b, link-type EN10MB (Ethernet), capture size 262144 bytes
11:53:11.408964 IP 192.168.2.132.52898 > 239.255.255.250.3702: UDP, length 656
11:53:11.409492 IP himanshu.57383 > one.one.one.one.domain: 8572+ [1au] PTR? 250.255.255.239.in-addr.arpa. (57)
11:53:11.409588 IP 192.168.2.140.49690 > 239.255.255.250.1900: UDP, length 174
11:53:11.409954 IP 192.168.2.147.mdns > 224.0.0.251.mdns: 1 [2q] PTR (QU)? _%9E5E7C8F47989526C9BCD95D24084F6F0B27C5ED._sub._googlecast._tcp.local. PTR (QU)? _googlecast._tcp.local. (94)
11:53:11.499220 IP one.one.one.one.domain > himanshu.57383: 8572 NXDomain 0/1/1 (114)
11:53:11.499950 IP himanshu.34201 > one.one.one.one.domain: 12068+ [1au] PTR? 132.2.168.192.in-addr.arpa. (55)
11:53:11.591291 IP one.one.one.one.domain > himanshu.34201: 12068 NXDomain* 0/1/2 (278)
11:53:11.592195 IP himanshu.55501 > one.one.one.one.domain: 31630+ [1au] PTR? 1.1.1.1.in-addr.arpa. (49)
11:53:11.842603 IP himanshu.57253 > one.one.one.one.domain: 16905+ [1au] PTR? 140.2.168.192.in-addr.arpa. (55)
11:53:11.951226 IP himanshu.52662 > one.one.one.one.domain: 52377+ [1au] PTR? 251.0.0.224.in-addr.arpa. (53)
11:53:12.428931 IP 192.168.2.140.49690 > 239.255.255.250.1900: UDP, length 174
11:53:12.437905 IP 192.168.2.147.mdns > 224.0.0.251.mdns: 2 [2q] PTR (QM)? _%9E5E7C8F47989526C9BCD95D24084F6F0B27C5ED._sub._googlecast._tcp.local. PTR (QM)? _googlecast._tcp.local. (94)
11:53:12.438730 IP6 fe80::eccc:59f2:fc78:9e07.52899 > ff02::c.3702: UDP, length 656
11:53:12.439017 IP himanshu.33194 > one.one.one.one.domain: 15679+ [1au] PTR? c.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.f.f.ip6.arpa. (101)
11:53:12.572386 IP one.one.one.one.domain > himanshu.33194: 15679 NXDomain 0/1/1 (165)
11:53:12.642129 IP 192.168.2.11.mdns > 224.0.0.251.mdns: 0*- [0q] 1/0/3 PTR Google-Home-Mini-e3a3ae72a03e3d1c60d24653d4666ca6._googlecast._tcp.local. (356)
...
...

Q2. ¿Cómo hacer que tcpdump salga después de recibir un número determinado de paquetes?

Esto se puede conseguir utilizando la opción de línea de comandos -c. Por ejemplo, si quieres que tcpdump sólo muestre información relacionada con 10 paquetes, puedes hacerlo de la siguiente manera

tcpdump -c 10

Por ejemplo, en mi caso, ejecuté el siguiente comando:

tcpdump -c 10 -i wlx18a6f713679b

A continuación se muestra la salida que se produjo:

Cómo hacer que tcpdump salga después de recibir un número determinado de paquetes

Así puedes ver que se capturaron 10 paquetes.

Q3. ¿Cómo hacer que tcpdump muestre la cabecera a nivel de enlace en la salida?

Esto se puede hacer utilizando la opción de línea de comandos -e. Por ejemplo:

tcpdump -e -i wlx18a6f713679b

Y aquí está la salida producida:

listening on wlx18a6f713679b, link-type EN10MB (Ethernet), capture size 262144 bytes
12:14:07.951396 3c:a8:2a:a7:7b:c1 (oui Unknown) > Broadcast, ethertype IPv4 (0x0800), length 197: 192.168.2.55.17500 > 255.255.255.255.17500: UDP, length 155
12:14:07.952111 3c:a8:2a:a7:7b:c1 (oui Unknown) > Broadcast, ethertype IPv4 (0x0800), length 197: 192.168.2.55.17500 > 192.168.2.255.17500: UDP, length 155
...
...

Así puedes ver que se han producido cabeceras a nivel de enlace en la salida.

Q4. ¿Cómo hacer que tcpdump muestre numéricamente las direcciones IP extranjeras?

Esto se puede conseguir utilizando la opción de línea de comandos -f.

tcpdump -f -i [INTERFACE]

Hacer que tcpdump muestre las direcciones IPv4 «extranjeras» numéricamente en lugar de simbólicamente tiene sus ventajas en determinadas situaciones. Un ejemplo de ello se menciona en la página de manual de la herramienta:

this option is intended to get around serious brain damage in Sun's NIS server — usually it hangs 
forever translating non-local internet numbers

Q5. ¿Cómo hacer que tcpdump produzca números de paquetes en la salida?

Para hacer que tcpdump produzca números de paquetes en la salida, utiliza la opción de línea de comandos –number.

Por ejemplo, he ejecutado el siguiente comando:

tcpdump --number -i wlx18a6f713679b

Y aquí está parte de la salida que se produjo:

listening on wlx18a6f713679b, link-type EN10MB (Ethernet), capture size 262144 bytes
    1  12:38:35.522944 ARP, Request who-has 192.168.2.196 tell _gateway, length 46
    2  12:38:35.523265 IP6 fe80::8ab4:a6ff:fe9d:a6bb > ff02::16: HBH ICMP6, multicast listener report v2, 1 group record(s), length 28
    3  12:38:35.523578 IP6 fe80::8ab4:a6ff:fe9d:a6bb > ip6-allrouters: ICMP6, router solicitation, length 16
    4  12:38:35.523861 ARP, Request who-has 192.168.2.15 tell 192.168.2.170, length 28
...
...
...

Así puedes ver que ahora cada línea empieza con un número.

Q6. ¿Cómo hacer que tcpdump imprima una salida más corta?

Esto se puede hacer utilizando la opción de línea de comandos -q. Así es como lo explica la página man de la herramienta:

Quick (quiet?) output.  Print less protocol information so output lines are shorter.

A continuación se muestra un ejemplo de esta opción:

Cómo hacer que tcpdump imprima una salida más corta

Así puedes ver que esta vez se produjo menos información en la salida.

Q7. ¿Cómo omitir la información de la marca de tiempo en la salida de tcpdump?

Utiliza la opción de línea de comandos -t para ello. Aquí tienes un comando de ejemplo:

tcpdump -t -i wlx18a6f713679b

Y lo siguiente es su salida:

listening on wlx18a6f713679b, link-type EN10MB (Ethernet), capture size 262144 bytes
IP himanshu.56992 > mails11.telegram.org.https: Flags [.], ack 3090054317, win 965, options [nop,nop,TS val 226976758 ecr 3781653930], length 0
IP himanshu.41122 > one.one.one.one.domain: 12755+ [1au] PTR? 22.171.154.149.in-addr.arpa. (56)
IP mails11.telegram.org.https > himanshu.56824: Flags [.], ack 273652159, win 1001, options [nop,nop,TS val 3781656472 ecr 226966324], length 0
ARP, Request who-has 192.168.2.48 tell _gateway, length 46
ARP, Request who-has 192.168.2.135 tell _gateway, length 46
...
...

Así puedes ver que la información de la marca de tiempo (que generalmente está al principio de cada línea) no está presente en la salida ahora.

Q8. ¿Cómo hacer que tcpdump produzca una salida detallada?

En este caso puedes utilizar la opción de línea de comandos -v. A continuación, la página man de la herramienta explica esta opción:

tcpdump -v -i [INTERFACE]
When parsing and printing, produce (slightly more) verbose output. For example, the time to live,
identification, total length and options in an IP packet are printed. Also enables additional
packet integrity checks such as verifying the IP and ICMP header checksum.

When writing to a file with the -w option, report, every 10 seconds, the number of packets captured

Conclusión

Aquí sólo hemos arañado la superficie, ya que el comando tcpdump ofrece un montón de opciones de línea de comandos. Una vez que hayas terminado de practicarlas, puedes dirigirte a la página del manual de la herramienta para aprender más sobre ella.

También te podría gustar...