Linux Networking Reference
Linux Networking Reference
The commands that actually diagnose network problems: ip, ss, nmap, tcpdump, curl, dig, and iptables — with real-world one-liners for debugging in production.
ip — modern replacement for ifconfig and route
# Interface management (ip link)
ip link show # list all interfaces
ip link show eth0 # specific interface
ip link set eth0 up # bring interface up
ip link set eth0 down
ip link set eth0 mtu 9000 # jumbo frames
# IP address management (ip addr / ip address)
ip addr show # all IPs on all interfaces
ip addr show eth0 # specific interface
ip addr add 192.168.1.10/24 dev eth0 # add IP
ip addr del 192.168.1.10/24 dev eth0 # remove IP
ip addr flush dev eth0 # remove all IPs from interface
# Routing table (ip route)
ip route show # full routing table
ip route get 8.8.8.8 # which route would be used? (debug!)
ip route add default via 192.168.1.1 # add default gateway
ip route add 10.0.0.0/8 via 10.1.1.1 dev eth1 # static route
ip route del 10.0.0.0/8 # remove route
ip route flush cache # flush route cache
# Neighbour table (ARP)
ip neigh show # ARP cache
ip neigh add 192.168.1.1 lladdr aa:bb:cc:dd:ee:ff dev eth0 # static ARP
ip neigh flush dev eth0 # flush ARP for interface
# Namespaces (for container debugging)
ip netns list
ip netns exec myns ip addr show # run command in namespace
nsenter -t -n ip addr show # enter pod/container network namespace
ss — socket statistics (modern netstat)
# Basic usage
ss -tlnp # TCP (-t), listening (-l), numeric (-n), with process (-p)
ss -ulnp # UDP listening
ss -tlnp # the one you run every time something won't start
# Flags
# -t TCP sockets
# -u UDP sockets
# -l listening sockets only
# -a all sockets (listening + established)
# -n numeric ports (no DNS lookup — faster)
# -p show process name and PID
# -e extended info (timer, UID)
# -s summary statistics
# -4 IPv4 only
# -6 IPv6 only
# Useful combinations
ss -tlnp # what's listening on TCP?
ss -s # summary: TCP states, UDP, RAW
ss state established # only established connections
ss -tn state established # established TCP, numeric
ss -tn dst 10.0.1.5 # connections TO specific host
ss -tn src :443 # connections FROM port 443
ss -tn '( dport = :80 or dport = :443 )' # filter by dest port
# Show socket for specific process
ss -tlnp | grep nginx
ss -tlnp | grep ':8080'
ss -tlnp | grep "pid=1234"
# Watch connections in real time
watch -n1 'ss -tn state established | wc -l'
# Count connections per state
ss -s
# Compare to netstat
# netstat -tlnp → ss -tlnp
# netstat -an → ss -an
# netstat -rn → ip route show
tcpdump — capture and inspect traffic
# Basic capture
tcpdump -i eth0 # capture on interface
tcpdump -i any # all interfaces
tcpdump -i eth0 -n # no DNS resolution (faster)
tcpdump -i eth0 -v # verbose (TTL, TOS, length)
tcpdump -i eth0 -vv # very verbose
tcpdump -i eth0 -nn # no DNS + no port name resolution
# Filters (BPF — Berkeley Packet Filter syntax)
tcpdump host 192.168.1.10 # traffic to/from host
tcpdump src host 192.168.1.10 # only FROM host
tcpdump dst host 192.168.1.10 # only TO host
tcpdump port 443 # by port
tcpdump tcp port 8080 # TCP only on port
tcpdump not port 22 # exclude SSH noise
tcpdump host 10.0.1.5 and port 5432 # combine with and/or/not
tcpdump 'tcp[tcpflags] & tcp-syn != 0' # only SYN packets (new connections)
# Save to file (for Wireshark analysis)
tcpdump -i eth0 -w /tmp/capture.pcap
tcpdump -i eth0 -w /tmp/capture.pcap -C 100 # rotate at 100MB
tcpdump -r /tmp/capture.pcap # read from file
# Capture HTTP requests (GET/POST visible in clear)
tcpdump -i eth0 -A -s0 port 80 | grep -E 'GET|POST|Host:'
# Count packets per host (quick traffic analysis)
tcpdump -i eth0 -nn -c 1000 | awk '{print $3}' | \
cut -d. -f1-4 | sort | uniq -c | sort -rn | head -10
# Debug container networking
# 1. Find the veth pair: ip link show | grep veth
# 2. Capture on veth: tcpdump -i veth1234abcd
# Or enter namespace: nsenter -t -n tcpdump -i eth0
nmap — port scanning and network discovery
# Host discovery
nmap -sn 192.168.1.0/24 # ping sweep (no port scan)
nmap -sn 192.168.1.0/24 --open # only show responding hosts
# Port scanning
nmap 192.168.1.10 # scan 1000 common ports
nmap -p 80,443,8080,8443 10.0.1.5 # specific ports
nmap -p 1-65535 10.0.1.5 # all ports (slow)
nmap -p- 10.0.1.5 # all ports (same as above, shorter)
nmap -F 10.0.1.5 # fast — top 100 ports
# Scan types
nmap -sT 10.0.1.5 # TCP connect scan (full handshake, no root needed)
nmap -sS 10.0.1.5 # SYN scan (stealth, root required, faster)
nmap -sU 10.0.1.5 # UDP scan (slow — UDP has no handshake)
# Service and version detection
nmap -sV 10.0.1.5 # detect service versions
nmap -sV --version-intensity 5 10.0.1.5 # more aggressive version detection
nmap -O 10.0.1.5 # OS detection (root required)
nmap -A 10.0.1.5 # -sV + -O + script scan + traceroute (aggressive, noisy)
# Timing templates
nmap -T0 10.0.1.5 # paranoid (IDS evasion)
nmap -T3 10.0.1.5 # normal (default)
nmap -T4 10.0.1.5 # aggressive (fast networks)
nmap -T5 10.0.1.5 # insane (may miss things)
# Output formats
nmap -oN scan.txt # normal text
nmap -oX scan.xml # XML (for tools)
nmap -oG scan.gnmap # grepable
nmap -oA scan # all three formats with base name
# Quick internal network audit
nmap -sn 10.0.0.0/24 -oG - | grep "Up" | awk '{print $2}' | \
xargs nmap -sV -p 22,80,443,3306,5432,6379,8080,9200 --open
Don’t scan networks you don’t own. Even internal scanning can trigger IDS alerts or cause problems on sensitive production systems.
dig — DNS diagnostics
# Basic queries
dig example.com # A record (default)
dig example.com A # explicit A record
dig example.com AAAA # IPv6
dig example.com MX # mail exchangers
dig example.com NS # nameservers
dig example.com TXT # TXT records (SPF, DKIM, etc.)
dig example.com CNAME # canonical name
dig example.com SOA # start of authority
# Use specific DNS server
dig @8.8.8.8 example.com # query Google DNS
dig @1.1.1.1 example.com # query Cloudflare
dig @10.96.0.10 my-service.prod.svc.cluster.local # K8s CoreDNS
# Reverse lookup (PTR)
dig -x 93.184.216.34 # IP → hostname
dig PTR 34.216.184.93.in-addr.arpa.
# Short output (just the answer)
dig example.com +short
dig example.com A +short # just the IP(s)
# Full trace — see entire delegation chain
dig example.com +trace
# Check DNSSEC
dig example.com +dnssec
# Disable recursion (query authoritative only)
dig example.com +norec
# Useful diagnostics
dig example.com +noall +answer # clean answer section only
dig example.com +stats # include query time and server
# Common debug scenarios
# Mail not delivering?
dig example.com MX +short
# CDN not propagating?
dig @8.8.8.8 example.com A +short # vs
dig @1.1.1.1 example.com A +short
# Kubernetes DNS not resolving?
kubectl exec -it my-pod -- dig my-service.production.svc.cluster.local
iptables / nftables — firewall rules
# iptables — list rules
iptables -L # list all chains (filter table)
iptables -L -n # numeric (no DNS lookup)
iptables -L -n -v # with packet/byte counters
iptables -L -n -v --line-numbers # with line numbers (for delete)
iptables -t nat -L -n -v # NAT table (PREROUTING, POSTROUTING)
iptables -t mangle -L -n # mangle table
# Common operations
# Block incoming from IP
iptables -I INPUT 1 -s 1.2.3.4 -j DROP
# Allow specific port
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow established connections (essential — don't miss this)
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Block outgoing to IP
iptables -A OUTPUT -d 1.2.3.4 -j DROP
# Delete rule by line number
iptables -D INPUT 3
# Flush all rules (careful — locks you out if SSH is blocked)
iptables -F # flush rules
iptables -X # delete user-defined chains
# Save/restore rules
iptables-save > /etc/iptables/rules.v4
iptables-restore < /etc/iptables/rules.v4
# nftables (modern replacement — used in RHEL 8+, Debian 10+)
nft list ruleset # show all rules
nft list table inet filter
nft add rule inet filter input tcp dport 443 accept
# UFW (user-friendly frontend — Ubuntu)
ufw status verbose
ufw allow 443/tcp
ufw deny from 1.2.3.4
ufw delete allow 80/tcp
ufw enable / disable
curl — HTTP debugging one-liners
# Verbose HTTP request (shows headers, TLS details)
curl -v https://example.com
curl -vvv https://example.com # even more verbose (TLS handshake details)
# Show only headers
curl -I https://example.com # HEAD request
curl -sD - -o /dev/null https://example.com # GET but only print headers
# Timing breakdown
curl -o /dev/null -s -w "%{time_namelookup}s DNS\n%{time_connect}s connect\n%{time_starttransfer}s TTFB\n%{time_total}s total\n" https://example.com
# Test specific IP / bypass DNS
curl --resolve example.com:443:93.184.216.34 https://example.com
# Check TLS certificate
curl -vI https://example.com 2>&1 | grep -E 'subject|issuer|expire|SSL|TLS'
# Follow redirects and show final URL
curl -L -s -o /dev/null -w "%{url_effective}\n" https://example.com
# POST JSON
curl -s -X POST https://api.example.com/endpoint \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"key": "value"}' | jq .
# Download with progress
curl -O --progress-bar https://example.com/file.tar.gz
# Connect via proxy
curl -x http://proxy:3128 https://example.com
# Test from inside a K8s pod
kubectl exec -it my-pod -- curl -v http://other-service.production.svc.cluster.local/health
Diagnosing connectivity problems — step by step
# Step 1: Can we resolve DNS?
dig example.com +short
# No result: DNS problem — check /etc/resolv.conf, firewall port 53
# Step 2: Can we reach the host?
ping -c4 example.com # ICMP (may be blocked by firewalls)
traceroute example.com # path tracing
tracepath example.com # no root needed, MTU discovery
# Step 3: Can we connect to the port?
nc -zv example.com 443 # TCP port check
curl -m 5 -so /dev/null -w "%{http_code}" http://example.com # HTTP check
# Step 4: What route would we take?
ip route get 93.184.216.34 # which interface and gateway
# Step 5: Is the local port actually listening?
ss -tlnp | grep :8080
# Step 6: Is a firewall blocking it?
iptables -L -n | grep DROP
# Check cloud security groups / NACLs if on AWS/GCP/Azure
# Step 7: Capture the actual traffic
tcpdump -i eth0 host example.com -nn
# Container/K8s: which namespace is the pod in?
ip link show | grep veth # find veth pair
cat /proc//net/dev # network interfaces in container namespace
# Common failures and their causes
# ECONNREFUSED — nothing listening on that port
# ETIMEDOUT — firewall dropping packets (no RST)
# ECONNRESET — connection actively rejected mid-stream
# EHOSTUNREACH — no route to host (routing table issue)
# Name resolution failed — DNS not working
🔍 Free tool: HTTP Security Headers Analyzer — after configuring your Linux network stack, check that your web services return the right HTTP security headers.
Founded
2023 in London, UK
Contact
hello@releaserun.com