Capturing network traffic on Linux reveals the actual packets traversing an interface, making connection problems, latency issues, and unexpected communication patterns visible. Packet-level inspection helps validate firewall rules, confirm application behavior, and detect suspicious or misconfigured traffic on a host or segment.

The tcpdump utility is a classic command-line packet sniffer that hooks into libpcap to capture traffic from a chosen network interface. Filters based on hosts, ports, and protocols keep the output focused, while options such as -n and -v control how much metadata is decoded and displayed during the capture.

Packet capture usually requires elevated privileges and can expose sensitive information such as cookies, credentials, or session tokens. Encrypting transport layers (for example, TLS) hides payloads but still leaves headers visible, so choosing the correct interface, narrowing the filters, and storing captured .pcap files securely is essential for safe analysis.

Steps to capture network traffic in Linux:

  1. Open a terminal with access to sudo privileges.
    $ whoami
    user
  2. Identify the network interface that carries the traffic of interest.
    $ ip address show
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host noprefixroute 
           valid_lft forever preferred_lft forever
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
        link/ether 02:00:00:00:00:10 brd ff:ff:ff:ff:ff:ff
        inet 192.0.2.40/24 metric 100 brd 192.0.2.255 scope global dynamic eth0
           valid_lft 1470sec preferred_lft 1470sec
        inet6 fe80::20/64 scope link 
           valid_lft forever preferred_lft forever

    Choose the interface that corresponds to the network being investigated, for example eth0.

  3. Ensure tcpdump is available on the system.
    $ sudo apt update && sudo apt install --assume-yes tcpdump

    On Ubuntu and Debian, tcpdump is provided by the standard apt repositories; other distributions offer it via their own package managers.

  4. Capture all packets on the selected interface using tcpdump.
    $ sudo tcpdump --interface=eth0
    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
    listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    06:05:01.879528 IP host.example.net > api.example.net: ICMP echo request, id 10045, seq 1, length 64
    06:05:01.885099 IP api.example.net > host.example.net: ICMP echo reply, id 10045, seq 1, length 64
    06:05:01.955311 IP host.example.net.45939 > 192.0.2.53.domain: 56044+ PTR? 50.113.0.203.in-addr.arpa. (42)
    06:05:01.963291 IP 192.0.2.53.domain > host.example.net.45939: 56044 NXDomain 0/0/0 (42)
    06:05:02.888187 IP host.example.net > api.example.net: ICMP echo request, id 10045, seq 2, length 64
    06:05:02.893497 IP api.example.net > host.example.net: ICMP echo reply, id 10045, seq 2, length 64
    6 packets captured
    9 packets received by filter
    0 packets dropped by kernel

    This command captures all traffic on eth0 and displays packets in real time; use ctrl + C to stop the capture.

    Packet captures may include credentials and other sensitive data, so restrict access to the terminal session and any stored capture files.

  5. Disable IP address name resolution for clearer, faster output.
    $ sudo tcpdump --interface=eth0 -n
    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
    listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    06:05:05.930858 IP 192.0.2.40 > 203.0.113.50: ICMP echo request, id 10051, seq 1, length 64
    06:05:05.936415 IP 203.0.113.50 > 192.0.2.40: ICMP echo reply, id 10051, seq 1, length 64
    06:05:06.940730 IP 192.0.2.40 > 203.0.113.50: ICMP echo request, id 10051, seq 2, length 64
    06:05:06.945856 IP 203.0.113.50 > 192.0.2.40: ICMP echo reply, id 10051, seq 2, length 64
    06:05:07.951647 IP 192.0.2.40 > 203.0.113.50: ICMP echo request, id 10051, seq 3, length 64
    06:05:07.956585 IP 203.0.113.50 > 192.0.2.40: ICMP echo reply, id 10051, seq 3, length 64
    13 packets captured
    16 packets received by filter
    0 packets dropped by kernel

    The -n option disables DNS lookups, which reduces noise and avoids delays caused by reverse name resolution.

  6. Filter network traffic by a specific IP address to focus on one host.
    $ sudo tcpdump --interface=eth0 -n host 203.0.113.50
    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
    listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    06:05:09.969914 IP 192.0.2.40 > 203.0.113.50: ICMP echo request, id 10057, seq 1, length 64
    06:05:09.976649 IP 203.0.113.50 > 192.0.2.40: ICMP echo reply, id 10057, seq 1, length 64
    06:05:10.971282 IP 192.0.2.40 > 203.0.113.50: ICMP echo request, id 10057, seq 2, length 64
    06:05:10.976304 IP 203.0.113.50 > 192.0.2.40: ICMP echo reply, id 10057, seq 2, length 64
    
    4 packets captured
    4 packets received by filter
    0 packets dropped by kernel
  7. Filter traffic further by restricting to a specific port on that host.
    $ sudo tcpdump --interface=eth0 -n host 203.0.113.50 and port 443
    tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
    listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    06:05:14.004283 IP 192.0.2.40.46188 > 203.0.113.50.443: Flags [S], seq 3248983991, win 64240, options [mss 1460,sackOK,TS val 1980452645 ecr 0,nop,wscale 7], length 0
    06:05:14.009120 IP 203.0.113.50.443 > 192.0.2.40.46188: Flags [S.], seq 525594375, ack 3248983992, win 32768, options [mss 1460,wscale 1,nop], length 0
    06:05:14.009147 IP 192.0.2.40.46188 > 203.0.113.50.443: Flags [.], ack 1, win 502, length 0
    06:05:14.010216 IP 192.0.2.40.46188 > 203.0.113.50.443: Flags [P.], seq 1:518, ack 1, win 502, length 517
    06:05:14.010439 IP 203.0.113.50.443 > 192.0.2.40.46188: Flags [.], ack 518, win 16384, length 0
    06:05:14.016982 IP 203.0.113.50.443 > 192.0.2.40.46188: Flags [P.], seq 1:1461, ack 518, win 16384, length 1460
    27 packets captured
    27 packets received by filter
    0 packets dropped by kernel
  8. Save the filtered packets to a .pcap file for later analysis.
    $ sudo tcpdump --interface=eth0 -n host 203.0.113.50 and port 443 -w /root/packet-dump.pcap
    tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
    29 packets captured
    29 packets received by filter
    0 packets dropped by kernel

    This command writes the capture to a file named packet-dump.pcap instead of printing packets to the terminal.

  9. Verify the saved packet capture file type to confirm it was created correctly.
    $ sudo file /root/packet-dump.pcap
    /root/packet-dump.pcap: pcap capture file, microsecond ts (little-endian) - version 2.4 (Ethernet, capture length 262144)
  10. Read the saved capture file with tcpdump to replay and inspect the packets.
    $ tcpdump -r /root/packet-dump.pcap
    reading from file /root/packet-dump.pcap, link-type EN10MB (Ethernet), snapshot length 262144
    06:05:18.077845 IP host.example.net.46202 > api.example.net.https: Flags [S], seq 3378191711, win 64240, options [mss 1460,sackOK,TS val 1980456719 ecr 0,nop,wscale 7], length 0
    06:05:18.082501 IP api.example.net.https > host.example.net.46202: Flags [S.], seq 18510802, ack 3378191712, win 32768, options [mss 1460,wscale 1,nop], length 0
    06:05:18.082552 IP host.example.net.46202 > api.example.net.https: Flags [.], ack 1, win 502, length 0
    06:05:18.085382 IP host.example.net.46202 > api.example.net.https: Flags [P.], seq 1:518, ack 1, win 502, length 517
    06:05:18.085759 IP api.example.net.https > host.example.net.46202: Flags [.], ack 518, win 16384, length 0