Must-know cold
ip -br a · ip r · ping -c 4 HOST
ss -tlnp · curl -I URL · curl -v --max-time 5 URL
- Resolve:
getent ahosts NAME · dig +short NAME · resolvectl query NAME
- Capture:
sudo tcpdump -ni any -c 20 port 22
- Ladder: DNS → route/ping → port listen → TLS/HTTP → app
Failure vocabulary
Definition: DNS fail vs timeout vs connection refused vs HTTP/TLS errors.
| Symptom | Typical meaning |
|---|
| Could not resolve host | DNS / nss failure |
| Network unreachable | Routing / interface down |
| Connection timed out | Filtered, drop, or silent blackhole |
| Connection refused | Host answered with RST: nothing listening on that IP:port, or firewall REJECT |
| HTTP 5xx | Transport (and TLS, if HTTPS) already OK; application/server error |
| SSL certificate problem | Trust, name mismatch, expiry, or incomplete chain |
Commands
ip
Definition: Show/configure interfaces, addresses, and routes (modern ifconfig replacement).
| Option / object | Argument | Meaning | Example |
|---|
ip a / ip addr | — | Addresses on interfaces | ip a |
ip -br a | — | Brief interface + addr | ip -br a |
ip -br link | — | Brief link state | ip -br link |
ip r / ip route | — | Routing table | ip r |
ip route get | ADDR | Path taken to ADDR | ip route get 1.1.1.1 |
ip neigh | — | ARP/neighbor table | ip neigh |
ip link set | IF up / down | Admin link (needs root) | sudo ip link set eth0 up |
-4 / -6 | — | IPv4 / IPv6 only | ip -4 a |
-s | — | Statistics | ip -s link |
Flag combos
| Combo | Meaning | Example |
|---|
ip -br a; ip r | Addr + default route | First look |
ip route get 8.8.8.8 | Which IF/gateway | Multi-homed |
ping
Definition: ICMP echo probe for basic reachability and latency.
| Option | Argument | Meaning | Example |
|---|
| (none) | HOST | ICMP echo (runs until Ctrl-C) | ping 8.8.8.8 |
-c | N HOST | Send N probes then stop | ping -c 4 host |
-W | SEC HOST | Per-probe timeout (Linux) | ping -c 2 -W 2 host |
-i | SEC HOST | Interval between pings | ping -i 0.5 host |
-s | BYTES HOST | ICMP payload size (not total frame) | ping -s 1472 host |
-4 / -6 | HOST | Force family | ping -4 host |
-n | HOST | No DNS reverse lookup | ping -n host |
Flag combos
| Combo | Meaning | Example |
|---|
ping -c 4 -W 2 HOST | Finite safe test | Scripts |
| Note | ICMP may be blocked while TCP works | Don’t stop at ping fail |
ss
Definition: Socket statistics: listening ports and connection states (ss replaces netstat).
| Option | Argument | Meaning | Example |
|---|
| (none) | — | Non-listening sockets (mostly established TCP) — not a summary | Prefer flags |
-s | — | Summary counters | ss -s |
-t | — | TCP | ss -t |
-u | — | UDP | ss -u |
-l | — | Listening only | ss -lt |
-n | — | Numeric; no resolve | ss -tn |
-p | — | Process (often needs root) | ss -tlnp |
-a | — | All (listen + established) | ss -tan |
-4 / -6 | — | Address family | ss -tln4 |
sport = | :PORT | Filter source port | ss -tlnp 'sport = :80' |
dport = | :PORT | Filter dest port | ss -tan 'dport = :443' |
-r | — | Resolve hosts | ss -tr |
Flag combos
| Combo | Meaning | Example |
|---|
ss -tlnp | Listening TCP + process | Default |
ss -ulnp | Listening UDP + process | DNS etc. |
ss -tanp | grep :8080 | State for port | ESTAB/TIME-WAIT |
ss -tlnp | grep 127.0.0.1 | Localhost-only binds | “Works locally only” |
curl
Definition: Transfer data from URLs; inspect HTTP(S) status, headers, and bodies.
| Option | Argument | Meaning | Example |
|---|
| (none) | URL | GET body to stdout | curl URL |
-I / --head | URL | Send HTTP HEAD (not a GET; some apps 405 / differ) | curl -I https://x |
-v | URL | Verbose (DNS, TLS, headers) | curl -v URL |
-s | URL | Silent (no progress) | curl -s URL |
-S | URL | Show errors even with -s | curl -sS URL |
-o | FILE URL | Write body to FILE | curl -o f URL |
-O | URL | Save as remote filename | curl -O URL |
-L | URL | Follow redirects | curl -L URL |
-k | URL | Insecure TLS (skip verify) | curl -k https://... |
-m / --max-time | SEC URL | Whole operation timeout | curl -m 5 URL |
--connect-timeout | SEC URL | Connect phase timeout | curl --connect-timeout 3 URL |
-u | USER:PASS URL | Basic auth | curl -u u:p URL |
-H | HEADER URL | Add header | curl -H 'Auth: t' URL |
-X | METHOD URL | HTTP method | curl -X POST URL |
-d | DATA URL | Request body; implies POST unless -X / -I / --head | curl -d 'a=1' URL |
-x / --proxy | PROXY URL | Use proxy | curl -x http://proxy:8080 URL |
-w | FORMAT | Write-out metrics | curl -w '%{http_code}\n' -o /dev/null -s URL |
-f | URL | Exit ≠0 on HTTP 4xx/5xx (not on 3xx) | curl -f URL |
Flag combos
| Combo | Meaning | Example |
|---|
curl -sS -I -m 5 URL | Quick health | |
curl -v --max-time 10 URL | Full debug | |
curl -sS URL | python3 -m json.tool | Pretty JSON | |
curl -sS -o /dev/null -w '%{http_code}\n' URL | Status only | |
DNS & name resolution
Definition: What apps resolve (getaddrinfo / NSS) is not always what dig asks a nameserver. Split-horizon and systemd-resolved stubs make this the first SSH/curl “could not resolve host” check.
| File | Role |
|---|
/etc/nsswitch.conf | hosts: order (files dns resolve myhostname …) |
/etc/hosts | Static names (often first in NSS) |
/etc/resolv.conf | Stub resolver list. With systemd-resolved this is often 127.0.0.53, not the upstream |
getent
Definition: Query Name Service Switch databases (getent(1)). ahosts calls getaddrinfo(3) — the path curl, ssh, and glibc apps use.
| Command | Argument | Meaning | Example |
|---|
getent ahosts | NAME | getaddrinfo / AF_UNSPEC (A + AAAA as the app sees it) | getent ahosts api.local |
getent ahostsv4 / ahostsv6 | NAME | IPv4-only / IPv6-only getaddrinfo | getent ahostsv4 host |
getent hosts | NAME | gethostbyname2 — may hide AAAA | getent hosts api.local |
getent services | NAME | /etc/services port names | getent services ssh |
Exit 2 = key not found (getent(1)). Prefer ahosts for “will ssh/curl resolve this?”
dig
Definition: BIND 9 DNS lookup (dig(1)). Talks to nameservers listed in /etc/resolv.conf unless @server is given. Default type is A. Package: bind9-dnsutils / bind-utils. No args → NS query for . (root).
| Form | Meaning | Example |
|---|
dig NAME | A record via default resolvers | dig example.com |
dig NAME AAAA | IPv6 address | dig example.com AAAA |
dig +short NAME | Answer RDATA only | dig +short example.com |
dig @SERVER NAME | Query that server, not resolv.conf | dig @8.8.8.8 example.com |
dig -x ADDR | Reverse PTR (in-addr.arpa / ip6.arpa) | dig -x 192.0.2.1 |
dig +trace NAME | Iterative from the root (sets +dnssec) | Slow; good for delegation |
dig +norecurse NAME @AUTH | RD bit off — what an authoritative server has | |
dig NAME MX / NS / TXT / CNAME | Other types | dig example.com MX |
dig -p PORT | Non-53 (DoT is +tls, default port 853) | Test a hidden master |
dig does not walk NSS/hosts. A name in /etc/hosts can still fail in dig and succeed in getent ahosts.
host
Definition: Shorter BIND lookup (host(1)). Same package family as dig. Default is A+AAAA+MX style output.
| Form | Meaning | Example |
|---|
host NAME | Address lookup | host example.com |
host -t TYPE NAME | One RR type | host -t AAAA example.com |
host -a NAME | ANY (verbose) | |
host ADDR | Reverse lookup | host 192.0.2.1 |
resolvectl
Definition: systemd-resolved client (resolvectl(1)). Use when /etc/resolv.conf points at 127.0.0.53. Default query returns A and AAAA.
| Command | Meaning | Example |
|---|
resolvectl query NAME | Resolve (cache / LLMNR / mDNS / DNS) | resolvectl query api.local |
resolvectl status | Global + per-link DNS servers, DNSSEC, DoT | First look on Ubuntu |
resolvectl dns | Show (or set, with a link) DNS servers | |
resolvectl flush-caches | Drop the local RR cache | After a zone change |
-t TYPE query NAME | Raw RR (A, AAAA, MX, …); FQDN, no search list | resolvectl -t MX query example.com |
-4 / -6 | Only that family | |
resolvectl is not installed’s answer if you are on a chroot/nscd box without resolved — then getent + dig @upstream.
Flag combos
| Combo | Meaning |
|---|
getent ahosts HOST; ping -c1 HOST | App path, then L3 |
dig +short HOST; dig +short HOST AAAA | v4 and v6 from DNS only |
resolvectl status; resolvectl query HOST | Stub-resolver RCA |
traceroute
Definition: Show network path hops toward a destination. Optional package.
| Command | Argument | Meaning | Example |
|---|
traceroute | HOST | Path hops (Linux default is often UDP, not ICMP) | traceroute host |
traceroute -I | HOST | ICMP echo probes | traceroute -I host |
traceroute -n | HOST | No reverse DNS | traceroute -n host |
tracepath | HOST | Often no root needed | tracepath host |
mtr | HOST | Live loss/latency (if installed) | mtr -r -c 10 host |
Flag combos
| Combo | Meaning | Example |
|---|
traceroute -n HOST | Faster path view | |
Packet capture & analysis
Definition: Look at packets on the wire. tcpdump uses pcap-filter(7) (capture filter). tshark adds Wireshark display filters (-Y). SSH/TLS payloads are encrypted — you still see IP/TCP flags, ports, and retransmits. Capture needs root or CAP_NET_RAW / CAP_NET_ADMIN.
tcpdump
Definition: Dump packets matching a Boolean expression (tcpdump(1), libpcap). Default snaplen is 262144 bytes (-s 0 means that default). Interrupt with Ctrl-C.
| Option | Argument | Meaning | Example |
|---|
-i | IF / any | Interface. Linux any = all regular IF, not promiscuous | sudo tcpdump -i any |
-n | — | Do not convert addresses or ports to names (tcpdump(1) -n) | Always for RCA |
-c | N | Exit after N packets | sudo tcpdump -c 20 -ni any |
-w | FILE | Write pcap (raw), not text. Later -r | sudo tcpdump -w ssh.pcap port 22 |
-r | FILE | Read a savefile (no extra privilege) | tcpdump -nr ssh.pcap |
-v / -vv | — | More IP/TCP fields; with -w, a 1 Hz count on stderr | |
-e | — | Link-layer header (MACs) | ARP / wrong VLAN |
-l | — | Line-buffered stdout (pipes) | … | grep … |
-p | — | Don’t request promiscuous | |
-s | SNAPLEN | Bytes per packet; 0 = default 262144 | Don’t need -s0 on modern tcpdump |
-X | — | Payload hex+ASCII (useless for SSH/TLS crypto) | HTTP/DNS plaintext |
-D | — | List capture interfaces | |
Expression (quote it; see pcap-filter(7)). Put -- before the expression if it could look like an option:
| Filter | Meaning |
|---|
host 10.0.0.5 | To or from that address |
port 22 | TCP or UDP 22 |
tcp port 22 | SSH TCP only |
src host 10.0.0.5 and port 53 | DNS from that host |
icmp / arp | Those protocols |
tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 | SYN or FIN |
SSH RCA: SYN with no SYN-ACK → filter/drop (timeout). SYN then RST → refused. Handshake then app data you cannot read → crypto is working; debug ssh -vv instead.
Flag combos
| Combo | Meaning |
|---|
sudo tcpdump -ni any -c 30 port 22 | SSH TCP on all IF, numeric, stop at 30 |
sudo tcpdump -ni any -c 20 port 53 | DNS (UDP/TCP 53) |
sudo tcpdump -w /tmp/n.pcap -ni eth0 host 10.0.0.5 | Save for Wireshark |
tcpdump -nr /tmp/n.pcap 'tcp port 22' | Read back, no root |
tshark
Definition: Wireshark CLI (tshark(1)). Optional package. Capture filter -f is pcap-filter (same as tcpdump). Display filter -Y is Wireshark syntax (ssh, dns, tcp.port == 22). Default write format is pcapng.
| Option | Meaning | Example |
|---|
-i IF / -D | Capture IF / list IF | sudo tshark -i any |
-f 'FILTER' | Capture filter (pcap) | sudo tshark -f 'port 22' |
-Y 'FILTER' | Display filter (after dissect) | tshark -r f.pcap -Y ssh |
-w FILE | Raw packets (not text). Text = redirect stdout, not -w | sudo tshark -w n.pcapng |
-r FILE | Read capture | tshark -r n.pcapng |
-V | Full protocol tree | Heavy |
-T fields -e F | One column per field | tshark -T fields -e ip.src -e tcp.dstport |
-q -z conv,tcp | TCP conversations after the file | Stats, not a packet list |
Without -r/-i, tshark picks the first non-loopback IF — set -i explicitly.
proxy
Definition: Environment variables that force HTTP(S) clients through a proxy.
| Variable | Argument | Meaning | Example |
|---|
http_proxy / https_proxy | URL | Proxy for HTTP(S) clients (not ping/ssh). Uppercase variants too | export https_proxy=http://proxy:8080 |
no_proxy / NO_PROXY | LIST | Bypass list (matching rules vary by client) | export no_proxy=localhost,127.0.0.1,.corp |
Common recipes
| Goal | Command |
|---|
| My IPs | ip -br a |
| Default route | ip r |
| Reach host | ping -c 4 HOST |
| Listening ports | ss -tlnp |
| Who owns :8080 | sudo ss -tlnp | grep :8080 |
| HTTP headers | curl -I -m 5 URL |
| Verbose HTTP | curl -v --max-time 10 URL |
| Resolve (app path) | getent ahosts NAME |
| Resolve (DNS only) | dig +short NAME · dig +short NAME AAAA |
| Who is the stub? | resolvectl status (if resolv.conf is 127.0.0.53) |
| Capture SSH | sudo tcpdump -ni any -c 30 port 22 |
| Capture DNS | sudo tcpdump -ni any -c 20 port 53 |
| Save pcap | sudo tcpdump -w /tmp/n.pcap -ni eth0 host HOST |
| JSON API | curl -sS URL | python3 -m json.tool |
Pitfalls
- Ping fail ≠ service down (ICMP blocked). Linux
traceroute is often UDP; hops that “* * *” may still pass TCP.
127.0.0.1 / ::1 bind → remote clients fail; ss the listen address (0.0.0.0 vs 127.0.0.1 vs [::]).
curl without -m / --connect-timeout can hang forever.
curl -I is HEAD, not GET — a 200 on HEAD does not prove GET works.
- Corporate HTTP(S) clients need
https_proxy / no_proxy. They do not apply to ping or ssh.
ss -p hides other users’ processes without root.
- DNS:
/etc/hosts is consulted per nsswitch. On systemd-resolved, /etc/resolv.conf is often 127.0.0.53 (stub), not the real upstream — use resolvectl status / query.
getent hosts ≠ getaddrinfo. Prefer getent ahosts for “what ssh/curl will see.” dig bypasses NSS entirely.
dig with no args queries NS for . — not a bug, just BIND’s default.
tcpdump -n skips both host and port name lookup (current tcpdump(1)). Quote filters; & | () are shell metacharacters.
- Linux
-i any is not promiscuous and is not every libpcap device. Live capture needs root / CAP_NET_RAW. -w is raw pcap, not text.
- SSH/TLS capture shows TCP (SYN/RST/timeout), not passwords or shell. Use
ssh -vv for auth.
tshark -f is pcap-filter; tshark -Y is Wireshark display filter. -w is still raw packets.
- Off-subnet traffic follows the longest matching route, not always the default gateway.
Addressing
Two devices talk on-link only if they share the same network prefix under the subnet mask (and can ARP/NDP). Otherwise the packet follows the longest matching route — often the default gateway, not always.
| Piece | Question |
|---|
| IP address | Who am I? |
| Subnet mask / CIDR | What is local to me? |
| Default gateway | Where do I send everything else? |
Common CIDR sizes
| CIDR | Mask | Total | Usable | Typical use |
|---|
/32 | 255.255.255.255 | 1 | 1 | Single host route |
/31 | 255.255.255.254 | 2 | 2 | P2P (RFC 3021; both usable) |
/30 | 255.255.255.252 | 4 | 2 | Classic point-to-point |
/29 | 255.255.255.248 | 8 | 6 | Tiny segment |
/24 | 255.255.255.0 | 256 | 254 | Standard LAN |
/16 | 255.255.0.0 | 65,536 | 65,534 | Large campus |
/8 | 255.0.0.0 | 16,777,216 | ~16.7M | Huge (rare) |
For ordinary LAN prefixes, network (host bits 0) and broadcast (host bits 1) are reserved — a /24 has 254 usable hosts, not 256. Exceptions: /32 (1 address) and /31 (RFC 3021 point-to-point, both usable).
Worked /26: 192.168.1.10/26 → 64 addresses, network 192.168.1.0, broadcast 192.168.1.63, usable 192.168.1.1–192.168.1.62.
Private vs public
| Range | Notes |
|---|
10.0.0.0/8 | Large private |
172.16.0.0/12 | Medium private (172.16–172.31) |
192.168.0.0/16 | Small / home private |
127.0.0.0/8 | Loopback (127.0.0.1 is one address in this range) |
169.254.0.0/16 | IPv4 link-local (APIPA). Common after DHCP fail; also used on purpose |
Isolate a reachability fail
ping -c 4 192.168.1.1 # gateway — local segment
ping -c 4 8.8.8.8 # public IP — routing, no DNS
ping -c 4 google.com # hostname — DNS after routing
Socket & transport (L4)
| Verb | Tool / syscall | What it does |
|---|
| Socket | socket() | Allocates a kernel socket FD (IPv4/IPv6/UNIX, TCP/UDP). |
| Bind (socket) | bind() | Associates a socket with a local IP:port. Not the same as ip addr add (that assigns an address on an interface). |
| Listen | listen() | Passive TCP queue for incoming SYNs. |
| Connect | connect() | TCP 3-way handshake (or UDP default peer). |
| Accept | accept() | Takes one established connection from the listen queue. |
| Send / receive | send(), recv() | Copies payload between user buffers and kernel sk_buff. |
| Close | close(), shutdown() | FIN/RST tear-down; frees the socket. |
Link & interface (L1/L2)
| Verb | Tool | What it does |
|---|
| Up / down | ip link set DEV up/down | Administrative NIC state. |
| Bridge | ip link add type bridge | Software L2 switch (MAC learning). |
| Bond | ip link add type bond | Aggregate NICs (LACP / failover). |
| Veth pair | ip link add type veth | Virtual wire between namespaces. |
| Promisc | ip link set DEV promisc on | Pass all frames to the kernel. |
Routing (L3)
| Verb | Tool | What it does |
|---|
| Assign | ip addr add, DHCP | Address + prefix on an interface (L3). Separate from bind(). |
| Route | ip route add | FIB entry: dest → nexthop. |
| Forward | sysctl net.ipv4.ip_forward=1 | Transit packets NIC-to-NIC. |
| Resolve | getent, dig, ARP/NDP | Name→IP or IP→MAC. |
Filter & inspect
| Verb | Tool | What it does |
|---|
| Filter | nftables, iptables | Match headers at Netfilter hooks. |
| Drop / reject | DROP, REJECT | Silent discard vs ICMP/RST. |
| NAT | nft / iptables -t nat | Rewrite addresses/ports (SNAT/DNAT). |
| Shape | tc | Rate limits / qdiscs. |
| Capture | tcpdump, tshark, Wireshark | Frames via libpcap (pcap-filter). |
| Probe | ping, traceroute, nc | Path, latency, port status. |
| Inspect | ss, ip -s link | Socket states and drop counters. |