Networking & web 32 entries 25 run in the sandbox

Linux networking and DNS cheat sheet

Interfaces, routes, listening sockets, reachability and resolution. Each entry has a worked example and the flags worth knowing, and where one is easy to get wrong, the gotcha.

Interfaces & routes

ip -br addr

One line per interface with its state and addresses.

lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             10.0.1.23/24 fe80::8ff:1ff:fe2a:3b4c/64
-br
Brief, table-like output.
-4 / -6
Only IPv4 or IPv6.
addr show dev eth0
One interface in full detail.

ip route

Show the routing table: the default gateway and which interface each network uses.

default via 10.0.1.1 dev eth0 proto dhcp src 10.0.1.23 metric 100
10.0.1.0/24 dev eth0 proto kernel scope link src 10.0.1.23
get ADDR
Which route, interface and source address a packet to ADDR would use.
-6
The IPv6 table.

ip route get <addr>

Ask the kernel exactly how it would reach an address. Resolves 'which interface is this going out of?'

ip route get 10.20.0.15
10.20.0.15 via 10.0.1.1 dev eth0 src 10.0.1.23 uid 1000
from SRC
Simulate a packet from a specific source address.

ip route add <network> via <gateway>

Send traffic for one network through another gateway. It works at once and is gone after a reboot.

sudo ip route add 10.20.0.0/16 via 10.0.0.254 && ip route get 10.20.3.4
del NETWORK
Remove the route again.
replace NETWORK via GW
Add it, or change it if it exists.
metric N
Among routes to the same network, the lowest metric wins.
ip addr add ADDR/24 dev eth0
The same idea for an extra address: now, until reboot.

Gotcha The gateway must be on a network the host is directly connected to, or you get "Nexthop has invalid gateway".

netplan apply

Ubuntu keeps the addresses and routes that survive a reboot as YAML in /etc/netplan. apply reads the files and sets the host up to match.

sudo netplan get
/etc/netplan/60-static.yaml
Your own file, mode 600; later names are merged over earlier ones.
addresses: [10.0.0.50/24]
Static addresses under ethernets, then the interface name. The /prefix is required.
routes: [{to: 10.20.0.0/16, via: 10.0.0.1}]
Static routes; to: default replaces the old gateway4.
sudo netplan try
Apply, and roll back after 120 seconds unless you confirm.

Gotcha apply removes whatever was added with ip addr add or ip route add. YAML is indented with spaces, never tabs.

Sockets & ports

ss -tlnp

List listening TCP sockets with the owning process. The fastest answer to 'is anything on port 8080?'

State  Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0      511          0.0.0.0:80        0.0.0.0:*     users:(("nginx",pid=812,fd=6))
LISTEN 0      4096       127.0.0.1:8080      0.0.0.0:*     users:(("server",pid=1432,fd=9))
-t / -u
TCP or UDP sockets.
-l
Listening sockets only.
-n
Numeric addresses and ports; no DNS lookups.
-p
Show the process (needs root for other users' sockets).

Gotcha 127.0.0.1:8080 accepts only local connections. If a proxy or container on another address cannot connect, check the bind address.

ss -s

Socket summary: total TCP connections by state. A jump in TIME-WAIT or orphans shows connection churn.

-s
Summary statistics.

ss -tn dst <addr>

Filter connections by peer or port, for example every open connection to the database.

ss -tn dst 10.0.2.40:5432
dst ADDR[:PORT]
Match the remote end.
sport = :443
Match the local port.
state established
Filter by TCP state.

netstat -tulpn

The legacy equivalent of ss, still found on older hosts and in many runbooks.

-t -u
TCP and UDP.
-l
Listening.
-p -n
Process names, numeric output.

lsof -iTCP:<port> -sTCP:LISTEN

Find the process that owns a listening port when you get 'address already in use'.

sudo lsof -iTCP:8080 -sTCP:LISTEN
-iTCP:PORT
TCP sockets on PORT.
-sTCP:LISTEN
Only listening sockets.
-P -n
Do not convert ports or addresses to names.

Reachability

ping -c <N> <host>

Check basic reachability and round-trip latency with ICMP echo.

ping -c 4 10.0.2.40
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 0.412/0.497/0.611/0.071 ms
-c N
Stop after N packets.
-W SEC
Timeout per reply.
-s SIZE
Payload size, useful for MTU tests with -M do.

Gotcha Many clouds and firewalls drop ICMP. A failed ping does not prove the host is down; test the actual TCP port.

nc -zv <host> <port>

Test whether a TCP port accepts connections without speaking the protocol.

nc -zv -w 3 db.internal 5432
Connection to db.internal (10.0.2.40) 5432 port [tcp/postgresql] succeeded!
-z
Scan only; send no data.
-v
Report success or failure.
-w SEC
Connection timeout.

Gotcha 'Connection refused' means the host answered but nothing listens there. A timeout usually means a firewall dropped the packet.

bash -c '</dev/tcp/<host>/<port>'

Port check with nothing but bash, for minimal containers that lack nc and curl.

timeout 3 bash -c '</dev/tcp/db.internal/5432' && echo open || echo closed
/dev/tcp/H/P
A bash-only pseudo path that opens a TCP connection.
timeout 3
Give up after three seconds.

tracepath <host>

Show the routers on the way to a host, hop by hop, to see how far packets get when ping fails. It is part of the base system and needs no root.

tracepath -n example.com
-n
Addresses only: no reverse lookups, so it is faster.
-m N
Give up after N hops (default 30).
traceroute -T -p 443
Probe with TCP to a port the firewalls let through (needs the traceroute package and root).

Gotcha A hop in the middle that gives no reply only means that router does not answer. It matters when every hop from some point on is silent: that is where the packets stop.

mtr -rwc 20 <host>

Combine ping and traceroute to show where along the path loss or latency appears.

mtr -rwc 20 api.example.com
-r -w
Report mode with wide host names.
-c N
Send N probes per hop.
-T -P 443
Probe with TCP to port 443 instead of ICMP.

Gotcha Loss at one middle hop that does not continue to later hops is just a router rate-limiting replies.

tcpdump -i <iface> -nn <filter>

Capture packets to prove what is actually on the wire.

sudo tcpdump -i any -nn -c 20 port 53
-i any
Capture on every interface.
-nn
Do not resolve hosts or ports.
-c N
Stop after N packets.
-w FILE.pcap
Save for Wireshark.
host / port / tcp
BPF filters; combine with and/or.

DNS

dig <name>

Query DNS and see the full answer, including TTL, record type and the server that answered.

dig api.example.com
;; ANSWER SECTION:
api.example.com.   300   IN   A   203.0.113.10

;; SERVER: 127.0.0.53#53(127.0.0.53)
status: NOERROR
The name exists. NXDOMAIN means it does not; SERVFAIL means the resolver failed.
TTL (300)
Seconds this answer may be cached.
SERVER
Which resolver you actually asked.

dig +short <name>

Print just the answer values, ideal for scripts and quick checks.

dig +short api.example.com
203.0.113.10
+short
Answers only.
+noall +answer
Only the answer section, keeping TTLs visible.

dig @<server> <name>

Ask a specific resolver. Comparing the local resolver with a public one separates cache problems from DNS problems.

dig @8.8.8.8 api.example.com +short
@SERVER
Resolver to query instead of resolv.conf.
+tcp
Query over TCP.

dig <name> <TYPE>

Query a particular record type.

dig example.com MX +short
A / AAAA
IPv4 / IPv6 addresses.
CNAME
Alias to another name.
MX / TXT
Mail servers; verification and SPF/DKIM records.
NS / SOA
Authoritative servers and zone serial.

dig +trace <name>

Resolve from the root servers down, bypassing caches, to see which delegation step breaks.

dig +trace api.example.com
+trace
Iterate from the root like a recursive resolver.

dig -x <ip>

Reverse lookup: which name is attached to an IP address (PTR record).

dig -x 203.0.113.10 +short
-x ADDR
Build and query the in-addr.arpa name.

nslookup <name> [server]

The older lookup tool available almost everywhere, including Windows and many base images.

nslookup api.example.com
SERVER
Optional second argument: the resolver to use.
-type=MX
Record type.

getent hosts <name>

Resolve a name exactly the way applications do: /etc/hosts, then DNS, in nsswitch.conf order.

getent hosts api.internal
10.0.2.15       api.internal
hosts
Uses gethostbyname rules.
ahosts
Uses getaddrinfo and shows every address family.

Gotcha dig ignores /etc/hosts. When dig and the application disagree, getent tells you what the application sees.

cat /etc/hosts

Static name overrides consulted before DNS on most systems.

127.0.0.1   localhost
10.0.2.15   api.internal
IP name [alias]
One mapping per line.

Gotcha A forgotten test entry in /etc/hosts silently beats real DNS. It is a classic 'works on my machine' cause.

cat /etc/resolv.conf

Which resolvers the host uses, the search domains, and options such as ndots.

nameserver 127.0.0.53
search corp.example.com
options edns0
nameserver
Up to three resolvers, tried in order.
search
Suffixes appended to short names.
ndots:N
Names with fewer than N dots try the search list first.

Gotcha On systemd-resolved hosts 127.0.0.53 is a local stub; the real upstreams are in resolvectl status.

resolvectl status

Show per-link DNS servers for systemd-resolved, and flush its cache.

query NAME
Resolve through systemd-resolved with timing.
flush-caches
Drop cached answers after fixing a record.
statistics
Cache hit and miss counters.

Firewalls

ufw status verbose

Ubuntu's firewall front end: show and change rules.

sudo ufw allow 443/tcp
status numbered
Rules with indexes for deletion.
allow PORT/PROTO
Open a port.
allow from CIDR to any port N
Open a port for one network only.
delete N
Remove a rule by number.

Gotcha Before ufw enable on a remote host, allow SSH first, or you lock yourself out.

iptables -L -n -v --line-numbers

List iptables rules with packet counters, so you can see which rule is matching traffic.

sudo iptables -L INPUT -n -v --line-numbers
-L CHAIN
List one chain.
-n
Numeric output.
-v
Packet and byte counters per rule.
-S
Print rules as the commands that would recreate them.

Gotcha Rules match top to bottom and the first match wins. An early DROP makes a later ACCEPT dead code.

nft list ruleset

Show the complete nftables configuration, the successor to iptables on current distributions.

sudo nft list ruleset
list table inet filter
One table.
-a
Show rule handles for deletion.

firewall-cmd --list-all

firewalld on RHEL-family hosts: show the active zone, services and ports.

sudo firewall-cmd --add-service=https --permanent && sudo firewall-cmd --reload
--list-all
Everything allowed in the default zone.
--add-port=8080/tcp
Open a port.
--permanent
Persist the change; takes effect after --reload.

Your pager is ready.

Free, instant, and it works on your phone. No signup: start as a guest and save your progress later.