Introduction
When a connection doesn't work and logs say nothing, you have to look at the packets themselves. That's the role of tcpdump (CLI) and Wireshark (GUI). You identify:
- Which packets come in/go out
- If TCP/TLS handshake succeeds
- What errors appear (RST, retransmissions)
- What latency each step takes
Essential for any network sysadmin.
Prerequisites
- Linux VPS with root access
- 5 minutes of patience to read tcpdump options
- For Wireshark: local workstation Windows/macOS/Linux
Step 1: Installation
tcpdump (on VPS)
sudo apt install -y tcpdump
sudo tcpdump --version
Wireshark (on your workstation)
- Windows / macOS: https://www.wireshark.org/download.html
- Linux:
sudo apt install wireshark(check "Allow non-root capture")
Step 2: Basic capture with tcpdump
sudo tcpdump -i eth0
⚠️ Captures all traffic, unreadable in seconds. Always filter.
Essential filters
# Traffic to/from a host
sudo tcpdump -i eth0 host 1.2.3.4
# Specific port
sudo tcpdump -i eth0 port 443
# Source or destination IP
sudo tcpdump -i eth0 src 1.2.3.4
sudo tcpdump -i eth0 dst 1.2.3.4
# Combinations
sudo tcpdump -i eth0 host 1.2.3.4 and port 443
# Anything except SSH (so your own connection doesn't pollute)
sudo tcpdump -i eth0 not port 22
# Protocol
sudo tcpdump -i eth0 icmp
sudo tcpdump -i eth0 udp
Step 3: Useful options
sudo tcpdump -i eth0 -n -nn -v -tttt port 443
# -n : no DNS resolution (fast)
# -nn : no port → service name resolution
# -v : verbose (TTL, ID, etc.)
# -tttt: readable timestamps
# -c 100 : stop after 100 packets
# -s 0 : capture whole packet (not truncated to 96 bytes)
Save to .pcap for Wireshark
sudo tcpdump -i eth0 -w /tmp/capture.pcap port 443
Download via scp:
scp user@VPS_IP:/tmp/capture.pcap ~/Desktop/
Open in Wireshark for visual analysis.
Step 4: Read a capture
sudo tcpdump -r /tmp/capture.pcap -nn
Typical output:
15:30:00.123456 IP 1.2.3.4.54321 > 5.6.7.8.443: Flags [S], seq 12345, win 65535
15:30:00.143789 IP 5.6.7.8.443 > 1.2.3.4.54321: Flags [S.], seq 67890, ack 12346, win 65535
15:30:00.144000 IP 1.2.3.4.54321 > 5.6.7.8.443: Flags [.], ack 67891, win 65535
That's a normal TCP handshake: SYN, SYN-ACK, ACK.
TCP Flags
S(SYN): connection initiation.(ACK): acknowledgmentS.(SYN-ACK): response to SYNF(FIN): clean closeR(RST): reset, abrupt end (error)P(PUSH): data to push immediately
Step 5: Diagnose a connection problem
Symptom: "Connection refused"
sudo tcpdump -i eth0 -nn host 5.6.7.8 and port 443
If you see:
1.2.3.4.54321 > 5.6.7.8.443: Flags [S]
5.6.7.8.443 > 1.2.3.4.54321: Flags [R]
→ Server resets. Port 443 isn't listening (service down or not started).
Symptom: Timeout
sudo tcpdump -i eth0 -nn host 5.6.7.8 and port 443
If you see:
1.2.3.4.54321 > 5.6.7.8.443: Flags [S]
[SYN retransmissions every ~1s, ~3s, ~7s...]
→ No server response. Possible causes:
- Firewall silently dropping
- Broken routing
- Server down
Symptom: "Connection reset"
[handshake OK]
1.2.3.4.54321 > 5.6.7.8.443: Flags [P.], data
5.6.7.8.443 > 1.2.3.4.54321: Flags [R]
→ Server resets once connection is established. Often: app crash, rate limiter triggered, or WAF blocking.
Step 6: Diagnose DNS
sudo tcpdump -i eth0 -nn port 53
You see DNS queries/responses:
1.2.3.4.45678 > 1.1.1.1.53: A? google.com.
1.1.1.1.53 > 1.2.3.4.45678: A 142.250.74.110
If query goes out but no response: resolver problem. Change:
echo "nameserver 1.1.1.1" | sudo tee /etc/resolv.conf
Step 7: Diagnose SSL/TLS
sudo tcpdump -i eth0 -nn -s 0 -w /tmp/tls.pcap port 443
Open in Wireshark → filter tls.handshake.type == 1 (ClientHello).
You see:
- TLS version requested (1.2, 1.3)
- Supported cipher suites
- SNI (requested domain name)
For SSL errors:
- TLS Alert 50 (decode_error): malformed TLS packet
- TLS Alert 40 (handshake_failure): no common cipher
- TLS Alert 42 (bad_certificate): invalid cert
- TLS Alert 70 (protocol_version): TLS version not supported
Step 8: Diagnose latency
sudo tcpdump -i eth0 -nn -tttt host 5.6.7.8 and port 443
Note the timestamps:
15:30:00.123456 1.2.3.4.54321 > 5.6.7.8.443: [S]
15:30:00.143789 5.6.7.8.443 > 1.2.3.4.54321: [S.] ← 20ms (RTT)
20ms between SYN and SYN-ACK = RTT (round-trip time). Normal in mainland France.
Detect retransmissions
In Wireshark → filter: tcp.analysis.retransmission. Too many retransmissions = unstable link.
Detect duplicate packets
1.2.3.4 > 5.6.7.8: ack 100 win 65535
1.2.3.4 > 5.6.7.8: ack 100 win 65535 ← Dup ACK
Three consecutive Dup ACKs trigger fast retransmit (loss detected).
Step 9: Capture HTTP payload
sudo tcpdump -i eth0 -nn -s 0 -A 'port 80 and host 5.6.7.8'
-A shows ASCII payload. You see HTTP requests in clear:
GET / HTTP/1.1
Host: example.com
User-Agent: curl/7.88.1
⚠️ For HTTPS, payload is encrypted. To decrypt, see step 10.
Step 10: Decrypt HTTPS in Wireshark
If you have the server's private key or client's pre-master secrets, Wireshark can decrypt TLS.
Quick method: export pre-master secrets from your browser.
# On your workstation, before launching Firefox/Chrome
export SSLKEYLOGFILE=/tmp/sslkeys.log
firefox &
Run your test → close browser.
In Wireshark → Edit → Preferences → Protocols → TLS → "(Pre)-Master-Secret log filename" → point to /tmp/sslkeys.log.
HTTPS traffic now appears decrypted in the capture.
Step 11: Advanced Wireshark filters
Wireshark has a different filter language than tcpdump (more powerful):
| Wireshark | Description |
|---|---|
ip.addr == 1.2.3.4 | Traffic to/from 1.2.3.4 |
tcp.port == 443 | Port 443 (src OR dst) |
http | All HTTP traffic |
http.request | Requests only |
http.response.code == 500 | 500 errors |
tls.handshake | TLS handshakes |
dns | DNS |
icmp | ICMP |
tcp.flags.reset == 1 | Packets with RST flag |
tcp.analysis.retransmission | Retransmissions |
tcp.window_size == 0 | Zero window (congestion) |
Combinations: &&, ||, !.
http.request && ip.addr == 1.2.3.4 && !tcp.port == 80
Step 12: tshark (Wireshark CLI)
To process a capture in CLI:
sudo apt install -y tshark
# Read a capture
tshark -r /tmp/capture.pcap
# Filter
tshark -r /tmp/capture.pcap -Y "http.response.code == 500"
# Stats
tshark -r /tmp/capture.pcap -q -z conv,tcp
# Extract URLs
tshark -r /tmp/capture.pcap -Y http.request -T fields -e http.host -e http.request.uri
Step 13: Persistent captures (rotation)
To capture continuously without filling disk:
sudo tcpdump -i eth0 -w /var/log/captures/cap-%Y-%m-%d-%H.pcap \
-G 3600 -W 24 \
not port 22
-G 3600: rotate every hour-W 24: keep 24 files (= 1 day)-wwith strftime%Y-%m-%d-%H: one file per hour
Troubleshooting
"tcpdump: : You don't have permission" {#tcpdump-interface-you-dont-have-permission}
Run with sudo. Or add your user to pcap group / CAP_NET_RAW capabilities.
Too many packets, unreadable
Filter more precisely. Avoid capturing on the interface carrying your SSH (your own SSH traffic floods output). Use not port 22.
"Truncated packet"
Increase snaplen:
sudo tcpdump -i eth0 -s 0 # capture full packet
Capture on loopback
For localhost traffic:
sudo tcpdump -i lo
Wireshark refuses to open pcap
Check file permissions after scp. May need chmod 644.
Useful commands
# List interfaces
sudo tcpdump -D
# Stats at end of capture
sudo tcpdump -i eth0 -c 100 port 443
# packets captured / packets received / dropped
# Capture with size rotation
sudo tcpdump -i eth0 -w /tmp/cap -C 100 -W 10
# -C 100 = 100 MB max per file, -W 10 = 10 files
# Combine tcpdump and tshark via pipe
sudo tcpdump -i eth0 -nn -w - port 443 | tshark -r - -Y "tls.handshake.type == 1"
# Top talkers
sudo tcpdump -i eth0 -nn -c 1000 not port 22 | awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -rn | head
# Latency test with tcpdump
sudo tcpdump -i eth0 -nn -tttt host 5.6.7.8 and port 443
Conclusion
tcpdump + Wireshark are the ultimate tools to:
- Confirm where a problem lies (network, DNS, app, TLS)
- Measure real latency
- Capture suspicious traffic for forensic analysis
Going further:
- mitmproxy: HTTPS MITM to see encrypted traffic
- Suricata / Zeek: IDS based on continuous capture
- ntopng: network analysis via web UI
- iperf3: bandwidth test between two hosts
Resources
- tcpdump documentation: https://www.tcpdump.org/manpages/tcpdump.1.html
- Wireshark: https://www.wireshark.org
- Display Filter Reference: https://wiki.wireshark.org/DisplayFilters
- VeryCloud guide — Kernel tuning:
/docs/article/kernel-tuning - VeryCloud guide — IPv6:
/docs/article/ipv6

















