Skip to content

Networking Tools Cheatsheet#

"Ping ran, came back; curl worked; but the app returns 503." The network has 7 layers, and there's a separate tool for testing each one.

🌐 DNS#

# Single-line A record
dig +short <DOMAIN>

# Detailed
dig <DOMAIN>
dig <DOMAIN> AAAA              # IPv6
dig <DOMAIN> MX                # mail
dig <DOMAIN> TXT               # SPF, DKIM, ownership
dig <DOMAIN> NS                # name servers
dig <DOMAIN> CNAME

# Specify resolver
dig <DOMAIN> @8.8.8.8           # Google
dig <DOMAIN> @1.1.1.1           # Cloudflare
dig <DOMAIN> @<INTERNAL_DNS>    # internal DNS

# Full path (recursive trace)
dig +trace <DOMAIN>

# Reverse DNS
dig -x <IP>
host <IP>

# DNSSEC check
dig +dnssec <DOMAIN>

# From /etc/hosts or from DNS?
getent hosts <DOMAIN>

📡 Ping & Latency#

# Simple
ping -c 5 <HOST>
ping -i 0.2 <HOST>             # 200ms interval
ping -s 1500 <HOST>             # MTU test (-M do for Don't Fragment)
ping -M do -s 1472 <HOST>       # 1472 + 28 IP/ICMP header = 1500

# Continuous, with statistics
ping -c 100 -q <HOST>          # 100 packets, summary only

# IPv6
ping6 <HOST>
ping -6 <HOST>

# Modern alternative (port-based, for networks that block ICMP)
nc -zv <HOST> 443
mtr <HOST>                     # live traceroute
mtr --report --report-cycles 50 <HOST>

🛤️ Traceroute#

# Traditional UDP
traceroute <HOST>
traceroute -n <HOST>            # don't resolve DNS

# ICMP
traceroute -I <HOST>

# TCP (to bypass firewalls)
traceroute -T -p 443 <HOST>
tcptraceroute <HOST> 443

# Modern: mtr
mtr <HOST>                     # live, packet loss + latency
mtr --report-wide --report-cycles 100 <HOST>

🔌 Port Scan / Test#

# Is a port open? (fastest)
nc -zv <HOST> 443
nc -zv <HOST> 80-443           # range

# UDP
nc -zuv <HOST> 53

# nmap (extra detail, for fingerprinting)
nmap <HOST>                    # default top 1000 ports
nmap -p 80,443 <HOST>
nmap -p- <HOST>                # all 65535
nmap -sV <HOST>                # service version
nmap -O <HOST>                 # OS detection (root)
nmap -sU <HOST>                # UDP

# Fast network discovery
nmap -sn 192.168.1.0/24        # ping sweep, list hosts

# Local listening ports
ss -tunlp
ss -t -a state listening
netstat -tlnp                  # old, ss is preferred
lsof -i -P -n | grep LISTEN

📦 Packet Capture#

# tcpdump basics
sudo tcpdump -i any -n port 80
sudo tcpdump -i eth0 host <IP>
sudo tcpdump -i eth0 'tcp port 443 and host <IP>'

# Save output to a file (opens in Wireshark)
sudo tcpdump -i any -w capture.pcap port 5432
sudo tcpdump -r capture.pcap -nn      # read from file

# Hex/ASCII dump
sudo tcpdump -i any -X port 80
sudo tcpdump -i any -A port 80         # ASCII (for text protocols like HTTP)

# tshark (Wireshark CLI)
sudo tshark -i any -f "port 80" -T fields -e ip.src -e ip.dst -e http.host

# Kubernetes pod capture
kubectl run --rm -it netshoot --image=nicolaka/netshoot -- tcpdump -i any
# or: kubectl debug -it <POD> --image=nicolaka/netshoot --target=<CONTAINER>

🌍 HTTP/HTTPS Testing#

# curl basics
curl https://<DOMAIN>
curl -i https://<DOMAIN>           # response + body
curl -I https://<DOMAIN>           # headers only
curl -L https://<DOMAIN>           # follow redirects
curl -v https://<DOMAIN>           # verbose (includes TLS handshake)

# Send headers
curl -H "Authorization: Bearer <TOKEN>" -H "Content-Type: application/json" \
  -X POST -d '{"key":"value"}' https://api.<DOMAIN>/path

# Method
curl -X POST | PUT | DELETE | PATCH

# Form data
curl -F "file=@local.jpg" https://api.<DOMAIN>/upload
curl -d "param1=value1&param2=value2" https://api.<DOMAIN>/form

# Timing breakdown (duration of each stage)
curl -w '\n
time_namelookup:    %{time_namelookup}\n
time_connect:       %{time_connect}\n
time_appconnect:    %{time_appconnect}\n
time_pretransfer:   %{time_pretransfer}\n
time_starttransfer: %{time_starttransfer}\n
time_total:         %{time_total}\n
http_code:          %{http_code}\n' \
  -o /dev/null -s https://<DOMAIN>

# Specific resolver (DNS bypass)
curl --resolve <DOMAIN>:443:<IP> https://<DOMAIN>

# TLS version test
curl --tlsv1.2 --tls-max 1.2 https://<DOMAIN>
curl --tlsv1.3 https://<DOMAIN>

# Client cert
curl --cert client.crt --key client.key https://<DOMAIN>

# Accept self-signed cert (DEV only)
curl -k https://<DOMAIN>

🔐 TLS / Certificate#

# Inspect certificate
echo | openssl s_client -connect <DOMAIN>:443 -servername <DOMAIN> 2>/dev/null \
  | openssl x509 -noout -text | head -30

# Expiry only
echo | openssl s_client -connect <DOMAIN>:443 -servername <DOMAIN> 2>/dev/null \
  | openssl x509 -noout -dates

# Certificate chain
echo | openssl s_client -showcerts -connect <DOMAIN>:443 -servername <DOMAIN>

# SAN (Subject Alternative Names)
echo | openssl s_client -connect <DOMAIN>:443 -servername <DOMAIN> 2>/dev/null \
  | openssl x509 -noout -text | grep -A1 'Subject Alternative Name'

# Cipher suite test
openssl s_client -connect <DOMAIN>:443 -tls1_2 -cipher 'ECDHE-RSA-AES256-GCM-SHA384'

# TLS scan with nmap
nmap --script ssl-enum-ciphers -p 443 <DOMAIN>

# testssl.sh (most comprehensive)
docker run --rm -ti drwetter/testssl.sh https://<DOMAIN>

🚇 SSH Tunnel#

# Local forward (local port → resource on remote)
# Local 5432 → remote 10.0.0.5:5432 (via jump host)
ssh -L 5432:10.0.0.5:5432 user@<JUMP_HOST>

# Remote forward (remote port → local)
# Remote 8080 → local 8080
ssh -R 8080:localhost:8080 user@<REMOTE>

# Dynamic / SOCKS proxy
ssh -D 1080 user@<HOST>
# Browser/curl SOCKS5 proxy: localhost:1080

# Multiple jumps (via jump host to a second host)
ssh -J jump1@host1,jump2@host2 user@target
ssh -o ProxyJump=jump@<JUMP_HOST> user@<TARGET>

# Background tunnel
ssh -fN -L 5432:db:5432 user@<JUMP>
# -f: background, -N: no command

# Persistent (via config)
# ~/.ssh/config
Host db-tunnel
  HostName <JUMP_HOST>
  User myuser
  LocalForward 5432 db-internal:5432

🔥 Firewall (iptables / ufw / nftables)#

# UFW (Ubuntu, simple)
sudo ufw status verbose
sudo ufw allow 80/tcp
sudo ufw allow from 10.0.0.0/8 to any port 22
sudo ufw enable

# iptables
sudo iptables -L -n -v
sudo iptables -L -n -v -t nat       # NAT table
sudo iptables-save > rules.bak
sudo iptables-restore < rules.bak

# nftables (modern replacement)
sudo nft list ruleset

📈 Bandwidth Test#

# iperf3 (most accurate)
# On the server side:
iperf3 -s

# On the client side:
iperf3 -c <SERVER_IP>
iperf3 -c <SERVER_IP> -t 30 -P 4    # 30 sec, 4 parallel streams
iperf3 -c <SERVER_IP> -u -b 100M    # UDP, 100 Mbit target

# speedtest (Internet)
speedtest-cli
fast.com (CLI: npm i -g fast-cli)

🛠️ K8s Network Debug#

# Ping/curl from pod to service
kubectl run -it --rm netshoot --image=nicolaka/netshoot -- bash
# inside:
#   ping <SVC>.<NS>
#   nslookup <SVC>.<NS>
#   curl http://<SVC>.<NS>:8080/health

# DNS query
kubectl run -it --rm dns-test --image=busybox -- nslookup kubernetes.default

# NetworkPolicy test
kubectl run --rm -it --labels="app=client" --image=curlimages/curl curl-test -- \
  curl -m 5 http://<SVC>.<NS>

# Service endpoint check (does selector match?)
kubectl get svc <SVC>
kubectl get endpoints <SVC>
kubectl get endpointslices -l kubernetes.io/service-name=<SVC>

# Pod-to-pod connectivity
kubectl exec -it <POD-A> -- ping <POD-B-IP>

🆘 Emergency scenarios#

Issue Ordered checks
Connection refused Is the server running? Is the port correct? Firewall? nc -zv
Connection timeout Is there a network path? Trace path with mtr; is firewall dropping it?
No route to host Routing table: ip route, traceroute
DNS not working dig, /etc/resolv.conf, systemd-resolve --status
TLS error Test cert/cipher with openssl s_client, check expiry
HTTP 502/504 Is upstream running? Reverse proxy log; backend timeout
Slow response Stage-by-stage timing with curl -w; CDN cache miss?
Random 503 Load balancer healthcheck inconsistent; pod restart loop