Skip to content
DevOps AI ToolKit
Newsletter

Kali Linux Networking for DevOps · Part 13 of 15

Wireshark for DevOps Engineers

Difficulty: Intermediate ~19 min Part 13/15
Prerequisites: tcpdump packet analysisTCP vs UDP
Series progress13 / 15
Series curriculum (15 lessons)

In the previous lesson we captured packets on the command line with tcpdump. That tool is perfect for getting the packets — it runs on any headless server and writes a compact capture file. But once you have thousands of packets, reading them as scrolling text is exhausting. This is where Wireshark earns its place. Wireshark is a graphical packet analyzer that takes the same capture files and lets you filter, colorize, and reassemble the raw bytes into something a human can reason about.

The most important idea in this lesson is that you rarely capture with Wireshark on the box that has the problem. Production servers have no desktop, and running a heavy GUI on a struggling host is a bad idea. Instead you capture with tcpdump on the server, copy the file down, and analyze it on your workstation. We are not going to tour every menu — we will learn Wireshark the way you actually use it during an incident: open the file, isolate the conversation that matters, and find the evidence.

What You Will Learn

  • How to open a .pcap capture file saved by tcpdump
  • The difference between capture filters and display filters
  • How to read the packet list, and what the source and destination columns tell you
  • The most useful display filters for DevOps troubleshooting
  • How to follow a TCP stream to reconstruct a whole conversation
  • How to inspect DNS, HTTP, and TLS traffic
  • How to read a TLS handshake and confirm it succeeded
  • How to spot TCP retransmissions and connection resets

Before touching the UI, internalize the workflow. Its three steps keep the heavy graphical tool off the server under investigation.

  [ headless server ]        [ your workstation ]
   tcpdump -w file.pcap  -->  scp file down  -->  open in Wireshark
   (capture the packets)      (move the file)     (analyze the packets)

On the server that is misbehaving — no GUI required — you capture to a file:

sudo tcpdump -i eth0 -w capture.pcap port 443

The -w capture.pcap flag writes raw packets to a file instead of printing a text summary, and port 443 is a capture filter that records only HTTPS traffic so the file stays small. We covered these flags in tcpdump Packet Analysis; here we only care that the result is a portable .pcap file. Then copy it down with scp:

scp user@server:/home/user/capture.pcap ./

scp copies the file over SSH, so the packets now live on your workstation and the server is left alone. Finally, open the file in Wireshark — either File → Open, or from a terminal with wireshark capture.pcap. The capture happened at the exact spot the problem lives (the server’s interface), but the analysis happens where you have a comfortable tool and can take your time. This is the way to use Wireshark when the problem is on a server with no GUI.

🛠️ DevOps Perspective — Treat the .pcap as an artifact, like a log bundle. Attach it to the incident ticket. A colleague can open the same file and see the same packets, which makes packet evidence reproducible in a way that “it looked slow” never is.

Capture Filters vs Display Filters

Wireshark has two kinds of filters, and confusing them is the single most common beginner mistake. They look similar but operate at completely different moments.

  Capture filter  -->  decides what gets RECORDED
                       (applied while sniffing; discarded packets
                        are gone forever)

  Display filter   -->  decides what gets SHOWN
                       (applied to an already-loaded file; hidden
                        packets are still there)

A capture filter limits what is written to disk in the first place. tcpdump port 443 is a capture filter — packets that do not match are never recorded, so you can never get them back. You use capture filters to keep the file small on a busy server.

A display filter limits what Wireshark shows you from a file that is already fully loaded. Nothing is deleted — clear the filter and every packet reappears. This is the filter box at the top of the Wireshark window, and it uses a richer syntax than capture filters.

The practical rule: capture broadly enough that you do not lose the evidence, then use display filters to zoom in. You can always filter a packet away in Wireshark, but you cannot filter in a packet that was never saved.

Reading the Packet List

When the file opens, the top pane is the packet list — one row per packet, in time order. The columns you will read most are:

ColumnWhat it tells you
No.Packet number in the capture
TimeSeconds since the capture started
SourceThe IP address the packet came from
DestinationThe IP address the packet is going to
ProtocolWireshark’s best guess: TCP, DNS, TLS, HTTP
InfoA one-line summary of the packet’s contents

The Source and Destination columns are your orientation. Read them together as a direction: Source your client and Destination the server is a packet going out; the reverse is a reply coming back. When you are chasing a stalled request, those two columns tell you which side spoke last, and therefore which side you are waiting on. Wireshark also colorizes rows by default — black or red usually flags something abnormal (bad checksums, retransmissions, resets), Wireshark’s way of saying “look here.”

Useful Display Filters

These go in the display filter bar. Press Enter to apply, and clear the bar to see everything again. Each one isolates a different slice of the traffic.

dns

Shows only DNS traffic — the name-resolution queries and responses. Use this when you suspect a name is resolving to the wrong address or not resolving at all. Everything that is not DNS disappears from view.

tcp

Shows only TCP packets, hiding UDP, DNS, and everything else. Handy to focus on connection-oriented traffic when a UDP-heavy capture is cluttering the list.

tcp.port == 443

Shows only TCP packets on port 443 — that is, HTTPS traffic, in either direction. The filter matches whether 443 is the source or destination port, so you see both the client’s requests and the server’s replies for that service.

ip.addr == 192.168.1.10

Shows every packet to or from 192.168.1.10, regardless of protocol or port. Use this to pin the view to one host — for example, the single backend that is timing out. Note ip.addr == matches both source and destination; if you only want one direction, use ip.src == or ip.dst ==.

tcp.flags.reset == 1

Shows only packets with the TCP RST (reset) flag set. A reset is an abrupt “this connection is over” — and finding who sent it, and when, is one of the fastest ways to explain a connection that died mid-request. We will come back to resets below.

🔎 Troubleshooting Tip — Filters combine with and, or, and not. tcp.port == 443 and ip.addr == 192.168.1.10 narrows to the HTTPS conversation with one specific host. Build filters up incrementally: start broad, then add a clause each time you rule something out.

Following a TCP Stream

A single TCP conversation is scattered across dozens of packets, interleaved with unrelated traffic, and reading it packet by packet is painful. Wireshark’s killer feature solves this: right-click any packet in a conversation and choose Follow → TCP Stream. Wireshark reassembles every packet of that one connection, in order, and shows you the actual bytes exchanged. For an HTTP request you will literally see the request line and headers the client sent, followed by the server’s response, color-coded by direction — the two sides as a transcript.

Why reach for this? It collapses “here are 400 packets” into “here is the request, and here is where the reply stopped.” If a request stalled, the stream view shows the request went out in full but the response never arrived — or arrived halfway and cut off.

🛠️ DevOps Perspective — Wireshark’s TCP stream view reconstructs a conversation so you can see exactly where an HTTP request stalled or a reset was sent. That single view answers the question every incident asks: did the client fail to send, or did the server fail to reply?

Inspecting DNS, HTTP, and TLS

Wireshark understands hundreds of protocols and dissects them — it decodes the raw bytes into named fields you can read in the middle (detail) pane. Three matter most for day-to-day DevOps work. If the distinction between connection-oriented and connectionless traffic is fuzzy, revisit TCP vs UDP first — it explains why TCP has streams to follow and UDP does not.

DNS

Apply the dns filter. Each query row shows the name being looked up; each response row shows the answer. Expand a response in the detail pane to read the returned addresses. If your application is connecting to the wrong IP, the DNS answer here is where you catch it — the resolver may be handing back a stale or unexpected record. Pair this with DNS Troubleshooting when the name layer is your suspect.

HTTP

For plaintext HTTP (port 80), Wireshark shows the request method, path, headers, and status code directly. Follow the TCP stream and you read the full exchange — a 404, a slow 200, or a redirect loop as clearly as reading a log, except this is the wire truth, not what the application thought it sent.

TLS

Modern traffic is almost all encrypted, so on port 443 you will not see request bodies — that is the point of TLS. What you can see, and what is genuinely useful, is the handshake that sets up the encryption, covered next.

Reading a TLS Handshake

Before any encrypted data flows, the client and server negotiate the connection in the open. Filter with tcp.port == 443 and look at the first few packets of a connection. You are looking for this sequence:

  Client                         Server
    |------- ClientHello ---------->|
    |<------ ServerHello -----------|
    |<----- Certificate, etc. ------|
    |------- (key exchange) ------->|
    |======= Application Data =====>|
    |<====== Application Data ======|

The ClientHello is the client proposing which TLS versions and cipher suites it supports. The ServerHello is the server picking from that list and sending its certificate. After a couple more key-exchange messages, both sides switch to encryption.

Here is the practical diagnostic: once you see packets labeled Application Data in the Info column, the handshake completed successfully. Application Data is the encrypted payload — its presence means the two sides agreed on a cipher, exchanged keys, and are now talking securely. You cannot read the contents (that is the encryption working as designed), but you have proof the TLS layer is fine.

If instead you see a ClientHello but no ServerHello, or a reset right after the ClientHello, the failure is in the negotiation itself — a version mismatch, a rejected certificate, or a firewall interfering. That points you straight at the TLS layer of the stack:

Application → TLS → Port → DNS → Gateway → Route → Interface
                ^
          handshake stalls here

For chasing certificate-specific failures, TLS Certificate Troubleshooting picks up where the packet view leaves off.

Spotting Retransmissions and Resets

Two packet-level signals explain a large share of “the network feels broken” reports, and Wireshark flags both automatically.

A retransmission happens when a sender does not receive an acknowledgment in time and sends the same data again. Wireshark labels these TCP Retransmission in the Info column and colors them. A few are normal; a storm of them is the packet-level signature of loss — a saturated link, a flaky NIC, or an overloaded host dropping packets. When a connection is “slow but works,” retransmissions are usually why: each re-send costs a timeout’s worth of delay. Isolate them with:

tcp.analysis.retransmission

A dense cluster around one point in time pins when the loss happened, which you can line up against a deploy, a scaling event, or a traffic spike.

A reset (RST) is an abrupt termination. Unlike a graceful close (the FIN handshake), a RST says “stop immediately, this connection is done.” Apply the reset filter from earlier:

tcp.flags.reset == 1

Now read the Source column — who sent the reset is the whole story. If the server sent the RST, the server (or a load balancer in front of it, or a full connection queue) refused or killed the connection. If an address you do not recognize sent it, a firewall or proxy is tearing connections down. A reset right after a request was sent is the classic signature behind “connection reset by peer.”

🏭 Why This Matters in Production — A user report of “random 502s” and a wall of RST packets from the load balancer’s IP are the same event seen from two altitudes. The packet capture turns a vague symptom into a specific accusation: this device, at this millisecond, killed the connection. That is what closes an incident.

Security Note

🔐 Security Note — Packet captures can contain real secrets. Plaintext HTTP, form posts, session cookies, and Basic-Auth headers all appear in the clear inside a .pcap. Only analyze captures from systems you own or have explicit permission to assess, and store the files securely — treat a .pcap like a credentials file, not a log. Delete captures when the investigation is done, and never paste one into a public issue tracker without scrubbing it first.

Try It Yourself

🧪 Try It — Generate a capture you can analyze end to end.

On a server (or a local VM), capture a short burst of web traffic:

sudo tcpdump -i eth0 -w web.pcap port 80 or port 443

Let it run, make a few requests with curl https://example.com, stop tcpdump with Ctrl+C, then scp the file down and open it in Wireshark. Then:

  1. Type dns in the display filter and find the lookup for the site. What address did it return?
  2. Clear the filter, right-click a packet on port 443, and choose Follow → TCP Stream. Find the ClientHello and confirm you see Application Data afterward.
  3. Apply tcp.flags.reset == 1, then tcp.analysis.retransmission. Did any connection reset, and are there retransmissions? A clean local capture usually has neither.

Common Problems

  • “I opened the file and see nothing / everything.” Check the display filter bar. A leftover filter hides packets; an empty bar shows all. Clear it to reset.
  • “Capture and display filter syntax got mixed up.” They are different languages. port 443 is capture-filter syntax (tcpdump/BPF); tcp.port == 443 is display-filter syntax (Wireshark). Using one where the other belongs errors or matches nothing.
  • “I can’t read the HTTPS request bodies.” That is TLS working correctly — the payload is encrypted. You can still read the handshake and confirm the connection succeeded, but not the plaintext without the session keys.
  • “The capture is empty even though the app was failing.” If you cannot reach the service at all, confirm the basics first with Testing Connectivity — there may be nothing on the wire to capture because the connection never left the host.

Troubleshooting Workflow

When a .pcap lands on your desk, work it in a fixed order rather than scrolling randomly:

1. Observe   — open the file, scan for red/black rows
2. Narrow    — display-filter to the host or port in question
3. Reassemble— Follow TCP Stream on the failing connection
4. Classify  — request never sent? no reply? reset? retransmits?
5. Locate    — map the symptom to a stack layer
                (TLS handshake stalls → TLS; RST from LB → Port)
6. Correct   — fix at that layer, not by guessing
7. Validate  — re-capture and confirm the signature is gone

The discipline is the same one this series teaches everywhere: observe the evidence, form a hypothesis about which layer is broken, and use the capture to confirm or reject it before you change anything. Wireshark does not fix the problem — it tells you, with packet-level certainty, what the problem is.

What You Learned

  • Wireshark is the analysis end of a capture workflow: capture on the server with tcpdump -w, copy down with scp, analyze on your workstation — the way to use Wireshark when the box has no GUI.
  • Capture filters decide what gets recorded (and lost forever if excluded); display filters only decide what is shown from an already-loaded file.
  • The Source and Destination columns give you direction; read pairs of packets to see who spoke last.
  • Core display filters: dns, tcp, tcp.port == 443, ip.addr == 192.168.1.10, and tcp.flags.reset == 1.
  • Follow → TCP Stream reassembles a whole conversation so you can see exactly where a request stalled or a reset was sent.
  • In a TLS handshake, ClientHello → ServerHello, and packets labeled Application Data mean the handshake succeeded.
  • Retransmissions signal packet loss; resets (RST) signal abrupt termination — and the Source of the RST names the culprit.
  • Packet captures may hold credentials and sensitive payloads: only analyze captures you are authorized to, and store them securely.

You can now turn a raw capture into a diagnosis. The next question is how to control which packets are allowed through in the first place. Continue to Part 14 — Linux Firewall Troubleshooting, where we move from observing traffic to filtering it with the Linux firewall.

Affiliate Disclosure: Some links on this page are affiliate links. If you purchase through one of these links, DevOps AI Toolkit may earn a commission at no additional cost to you. See our affiliate disclosure.

← Back to Kali Linux Networking for DevOps Back to Kali Linux

Related on DevOps AI Toolkit