DevOpsIndex

Linux Network Debugging Tools

1. ss — Socket Statistics

Replacement for netstat. Reads directly from kernel via netlink.

# TCP listening sockets with PID and process name
ss -tlnp

# Summary: total sockets per state
ss -s

# All TCP sockets (established + time-wait etc.)
ss -tan

# Filter by state
ss -tan state established
ss -tan state time-wait
ss -tan state listening

# Filter by port
ss -tlnp sport = :80

# Show socket memory usage
ss -tm

# UDP
ss -ulnp

Flag reference:

Flag Meaning
-t TCP
-u UDP
-l Listening only
-n Numeric (no DNS resolve)
-p Show process (PID/name)
-s Summary
-a All states

2. tcpdump — Packet Capture

# Capture on interface eth0, port 80, to file
tcpdump -i eth0 -w capture.pcap port 80

# Read from file
tcpdump -r capture.pcap

# HTTP GET requests only
tcpdump -i eth0 -A 'tcp port 80 and (tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420)'

# DNS queries
tcpdump -i eth0 -n port 53

# Capture between two hosts
tcpdump -i eth0 host 10.0.0.1 and host 10.0.0.2

# Verbose TLS handshake
tcpdump -i eth0 -v port 443

# First 100 packets then stop
tcpdump -i eth0 -c 100 -w out.pcap

# Human-readable ASCII output
tcpdump -i eth0 -A port 8080

Common filter syntax:

host 1.2.3.4          → src or dst
src host 1.2.3.4
dst port 443
net 10.0.0.0/8
tcp and port 80
not port 22            → exclude SSH

3. curl -v — Timing Breakdown

# Full verbose: DNS, TCP, TLS, headers, body
curl -v https://example.com

# Timing breakdown with write-out
curl -o /dev/null -s -w "\
DNS lookup:     %{time_namelookup}s<br>\
TCP connect:    %{time_connect}s<br>\
TLS handshake:  %{time_appconnect}s<br>\
TTFB:           %{time_starttransfer}s<br>\
Total:          %{time_total}s<br>\
HTTP status:    %{http_code}<br>" https://example.com

Timing fields:

Field Measures
time_namelookup DNS resolution
time_connect TCP SYN+ACK (cumulative)
time_appconnect TLS handshake complete (cumulative)
time_pretransfer Ready to send request (cumulative)
time_starttransfer TTFB — first byte received (cumulative)
time_total Full transfer done

All times are cumulative from request start. Subtract previous phase to get per-phase duration.

# Follow redirects, show final URL
curl -Lv https://example.com

# Send custom headers
curl -H "Authorization: Bearer TOKEN" -v https://api.example.com/v1/data

# POST JSON
curl -X POST -H "Content-Type: application/json" -d '{"key":"val"}' https://api/endpoint

4. nc — Netcat

# Check if port is open (TCP)
nc -zv host.example.com 443

# Check UDP port
nc -zuv host.example.com 53

# Simple TCP server (listen)
nc -l 8080

# Connect to server
nc host.example.com 8080

# Port scan range
nc -zv host.example.com 20-25

# Send file
nc -l 9999 > received.txt          # receiver
nc host.example.com 9999 < file.txt # sender

# Timeout after 3s
nc -w 3 -zv host.example.com 443

5. iperf3 — Bandwidth Testing

# Start server
iperf3 -s

# Run client (TCP, default 10s)
iperf3 -c server-ip

# UDP test
iperf3 -c server-ip -u -b 100M   # target 100 Mbps

# Parallel streams
iperf3 -c server-ip -P 4

# Reverse (server sends to client)
iperf3 -c server-ip -R

# Custom duration
iperf3 -c server-ip -t 30

# JSON output
iperf3 -c server-ip -J

6. mtr / traceroute — Hop Latency

# mtr: live updating traceroute + packet loss per hop
mtr google.com

# Non-interactive report mode (100 packets)
mtr --report --report-cycles 100 google.com

# TCP mode (bypasses ICMP filters)
mtr --tcp --port 443 google.com

# Classic traceroute
traceroute google.com

# Use TCP SYN (more firewall-friendly)
traceroute -T -p 443 google.com

# Use ICMP
traceroute -I google.com

Reading mtr output:

  • Loss% — packet loss at that hop (intermediate loss may be ICMP rate-limiting, not congestion)
  • Avg — average RTT to hop
  • High loss only at final hop → real issue; high loss at intermediate hop with no downstream loss → ICMP deprioritized

7. dig — DNS Debugging

# Basic lookup
dig example.com

# Short answer only
dig +short example.com

# Full recursive trace from root
dig +trace example.com

# Specific record type
dig example.com MX
dig example.com NS
dig example.com TXT
dig example.com AAAA

# Query specific nameserver
dig @8.8.8.8 example.com

# Reverse DNS (PTR)
dig -x 1.2.3.4

# Check DNSSEC
dig +dnssec example.com

# Query with timing
dig +stats example.com
sequenceDiagram
    participant C as Client
    participant R as Resolver
    participant Root as Root NS
    participant TLD as .com TLD NS
    participant Auth as Auth NS
    C->>R: dig example.com
    R->>Root: who has .com?
    Root-->>R: TLD NS addr
    R->>TLD: who has example.com?
    TLD-->>R: Auth NS addr
    R->>Auth: A record for example.com?
    Auth-->>R: 93.184.216.34
    R-->>C: 93.184.216.34 (TTL 3600)

8. ip — Route / Address / Neighbour

# Show all interfaces and IP addresses
ip addr show
ip addr show eth0

# Add/remove IP
ip addr add 192.168.1.10/24 dev eth0
ip addr del 192.168.1.10/24 dev eth0

# Routing table
ip route show
ip route get 8.8.8.8          # which route would be used?

# Add static route
ip route add 10.0.0.0/8 via 192.168.1.1 dev eth0

# Default gateway
ip route add default via 192.168.1.1

# ARP/neighbour table
ip neigh show
ip neigh flush dev eth0

# Link state
ip link show
ip link set eth0 up
ip link set eth0 down

9. TCP Tuning

# Current values
sysctl net.core.somaxconn
sysctl net.ipv4.tcp_rmem
sysctl net.ipv4.tcp_wmem

# Apply tuning (runtime)
sysctl -w net.core.somaxconn=65535
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
sysctl -w net.core.netdev_max_backlog=5000
sysctl -w net.ipv4.tcp_max_syn_backlog=8192

Persist in /etc/sysctl.conf or /etc/sysctl.d/99-tuning.conf:

net.core.somaxconn = 65535
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_tw_reuse = 1
Parameter Effect
somaxconn Max completed connections in accept queue
tcp_max_syn_backlog Max half-open (SYN) connections
tcp_rmem min/default/max receive buffer per socket
tcp_wmem min/default/max send buffer per socket
tcp_tw_reuse Reuse TIME_WAIT sockets for new connections
flowchart TD
    Q{Need to debug?}
    Q -->|port open?| SS[ss -tlnp]
    Q -->|DNS issue?| DIG[dig +trace hostname]
    Q -->|latency/loss?| MTR[mtr --report host]
    Q -->|bandwidth?| IPF[iperf3 -c server]
    Q -->|inspect packets?| TCP[tcpdump -i eth0 -w cap.pcap]
    Q -->|TLS/HTTP timing?| CRL[curl -w timing_fmt URL]
    SS --> FIX[Fix or escalate]
    DIG --> FIX
    MTR --> FIX
    IPF --> FIX
    TCP --> FIX
    CRL --> FIX