$linuxjunkies
>

Use Wireshark on Linux

Install Wireshark on Linux, configure non-root capture, use capture and display filters, decrypt TLS with SSLKEYLOGFILE, and follow TCP streams end-to-end.

IntermediateUbuntuDebianFedoraArch9 min readUpdated June 7, 2026

Before you start

  • A Linux desktop or server with a network interface to capture on
  • sudo / root access for installation and group management
  • Basic familiarity with TCP/IP concepts (IP addresses, ports, protocols)

Wireshark is the de facto standard for packet analysis on Linux. Whether you're debugging a flaky API, investigating unexpected network traffic, or learning how TCP actually works, it gives you a live, filterable view of every byte on the wire. This guide covers installation across the major distros, setting up non-root capture, using capture and display filters effectively, making sense of TLS traffic, and following TCP/UDP streams end-to-end.

Install Wireshark

Debian / Ubuntu

The package is in the main repository. During installation, a dialog asks whether non-superusers should be able to capture packets — answer Yes. If you miss it, re-run the config step shown below.

sudo apt update && sudo apt install wireshark
# Re-run the postinst dialog if you skipped it
sudo dpkg-reconfigure wireshark-common

Fedora / RHEL 9+ / Rocky 9+

sudo dnf install wireshark

Arch Linux

sudo pacman -S wireshark-qt

Allow Non-Root Packet Capture

Running Wireshark as root is a bad habit — the GUI parses untrusted data and a vulnerability there becomes a root exploit. The correct approach is to add your user to the wireshark group, which grants access to dumpcap, the privileged capture helper.

sudo usermod -aG wireshark $USER

Log out and back in (or start a new login shell with newgrp wireshark) for the group membership to take effect. Verify with:

groups | grep wireshark

On Fedora/RHEL the group may already be created by the package; double-check with getent group wireshark.

Launch and Select an Interface

Start Wireshark from your application launcher or terminal:

wireshark &

The welcome screen lists all available interfaces with a live sparkline of traffic. Double-click any interface to start capturing immediately, or single-click and hit the blue shark-fin button. Common choices:

  • eth0 / enp3s0 — wired Ethernet
  • wlan0 / wlp2s0 — Wi-Fi (monitor mode requires extra setup)
  • loloopback, useful for debugging local services
  • any — all interfaces at once (saved as Linux cooked capture, some dissectors limited)

Capture Filters

Capture filters run in the kernel via BPF before packets reach Wireshark. They reduce overhead and keep capture files manageable. Set them in the capture options dialog (Ctrl+K) or with the -f flag when using the CLI tool tshark.

Capture filter syntax is libpcap / tcpdump syntax — not the same as display filters.

# Only traffic to/from a specific host
host 192.168.1.50

# Only TCP port 443
tcp port 443

# Capture DNS (UDP 53) and HTTP (TCP 80)
port 53 or tcp port 80

# Exclude your SSH session so you don't flood the capture
not tcp port 22

# Traffic between two hosts
host 10.0.0.1 and host 10.0.0.2

Apply a capture filter before you start capturing — you cannot change it mid-capture without restarting. For exploratory work, skip the capture filter and rely on display filters instead.

Display Filters

Display filters are applied to an existing capture (live or saved) and use Wireshark's own richer syntax. The filter bar turns green for valid syntax, red for invalid.

Common display filter patterns

# Show only HTTP/2 traffic
http2

# All DNS queries (not responses)
dns.flags.response == 0

# TCP resets — good for spotting connection problems
tcp.flags.reset == 1

# Packets larger than 1400 bytes
frame.len > 1400

# Traffic to or from a specific IP
ip.addr == 203.0.113.10

# Filter by source IP only
ip.src == 10.0.0.5

# TLS Client Hello messages
tls.handshake.type == 1

# HTTP requests containing a specific path
http.request.uri contains "/api/login"

# Combine with logical operators
tcp.port == 8080 && ip.src == 192.168.0.0/24

Right-click any field in the packet detail pane and choose Apply as Filter → Selected to build filters interactively without memorising syntax. The filter expression toolbar at the top also autocompletes field names as you type.

Reading TLS Traffic

Wireshark cannot decrypt TLS on its own — it needs the session keys. Modern TLS 1.3 with ephemeral key exchange means server private keys are useless for decryption; you need the per-session pre-master secrets.

Most modern applications (Firefox, Chrome, curl, OpenSSL-based tools) can write session keys to a file when the environment variable SSLKEYLOGFILE is set.

# Set for your shell session
export SSLKEYLOGFILE="$HOME/tls-keys.log"

# Launch the browser or application in the same shell
firefox &
# or
curl https://example.com

Then tell Wireshark where that file is:

  1. Go to Edit → Preferences → Protocols → TLS
  2. Set (Pre)-Master-Secret log filename to your key log path (e.g. /home/you/tls-keys.log)
  3. Click OK. Wireshark immediately re-dissects captured TLS traffic and shows the decrypted application data.

Once configured, display filter http or http2 will surface decrypted HTTP requests and responses that were previously invisible inside TLS records.

Security note: the key log file grants anyone who reads it the ability to decrypt your TLS sessions. Delete it when you're done and never set SSLKEYLOGFILE in a persistent shell profile on a production or shared machine.

Follow Stream

The packet list shows individual frames. Follow Stream reassembles the full conversation at the application layer — far easier to read for HTTP, SMTP, or custom protocols.

  1. Click any packet that's part of the conversation you want.
  2. Right-click → Follow → TCP Stream (or UDP Stream, TLS Stream, HTTP Stream depending on the protocol).
  3. A dialog opens showing the reassembled data. Client-to-server traffic is shown in one colour, server-to-client in another.
  4. Use the Show data as dropdown to switch between ASCII, hex dump, raw bytes, or YAML.
  5. The filter bar is automatically set to isolate that stream — click X in the dialog and then clear the filter to return to the full capture.

For TLS streams, use Follow → TLS Stream (not TCP Stream) after loading your key log file to see the decrypted payload rather than encrypted bytes.

Saving and Exporting

# Save current capture from the CLI with tshark
tshark -i eth0 -w /tmp/capture.pcapng

# Read a saved file
wireshark /tmp/capture.pcapng &

# Export only packets matching a display filter to a new file
tshark -r /tmp/capture.pcapng -Y 'tcp.port == 443' -w /tmp/tls-only.pcapng

Use the .pcapng format — it supports multiple interfaces, comments, and name resolution blocks. The older .pcap format is still widely compatible but lacks these features.

Verification

To confirm everything is working without relying on live traffic, generate some DNS queries in a terminal while capturing on any interface with the display filter dns:

dig +short linux.org A

You should see a DNS query and response pair appear in Wireshark within a second. Expanding the DNS layer in the packet detail pane confirms the dissector is working correctly. If you see nothing, verify the capture interface matches the one your system routes traffic through (ip route get 1.1.1.1 shows the outgoing interface).

Troubleshooting

  • "Permission denied" on interfaces: Your user isn't in the wireshark group yet, or you haven't fully logged out and back in. Confirm with groups; use newgrp wireshark as a quick fix in the current terminal.
  • No packets on Wi-Fi: By default, Wi-Fi in managed mode only captures unicast traffic to/from your machine. Monitor mode is needed for all-station capture, which requires the adapter supports it and usually means disabling NetworkManager on that interface first.
  • TLS traffic not decrypting: Ensure the application was started after setting SSLKEYLOGFILE and that the path in Wireshark preferences matches exactly. Check the file exists and is non-empty after some HTTPS activity: wc -l ~/tls-keys.log.
  • Display filter turns red: Field names are case-sensitive and protocol-specific. Use the autocomplete in the filter bar or View → Internals → Supported Protocols to find the right field name.
  • High CPU / dropped packets on busy links: Add a capture filter to reduce volume, or increase the capture buffer size in Capture → Options → Interfaces → Buffer size. For sustained high-rate capture, tshark with ring buffer options (-b filesize:100000 -b files:5) is more efficient than the GUI.
tested on:Ubuntu 24.04Fedora 40Arch rollingDebian 12

Frequently asked questions

Can I use Wireshark on a headless server?
Yes — use tshark, the terminal-based companion. It shares all the same capture and display filter syntax and can write .pcapng files you can open in the GUI on another machine.
Why can't I decrypt TLS even after setting SSLKEYLOGFILE?
The application must be launched after the environment variable is set. Also verify the key log file is non-empty (wc -l ~/tls-keys.log) and that the path in Wireshark's TLS preferences matches exactly, including the home directory expansion.
Is it safe to capture on a production server?
Use it carefully and briefly. Prefer tshark with a tight capture filter, enable ring-buffer rotation to avoid filling the disk, and delete capture files that contain credentials or sensitive data immediately after analysis.
What is the difference between a capture filter and a display filter?
Capture filters use libpcap/BPF syntax and drop non-matching packets before they are recorded, reducing overhead. Display filters use Wireshark's own syntax and hide/show packets after they are already captured, so you can change them freely.
How do I capture Wi-Fi traffic from other devices on the network?
You need a Wi-Fi adapter that supports monitor mode. Put it into monitor mode with 'iw dev wlan0 set type monitor', then select it in Wireshark. Be aware this disables normal network access on that adapter and may require stopping NetworkManager first.

Related guides