Building modern Linux networking foundations with iproute2: IP addresses, routing, and complete diagnostics with ping, traceroute/mtr, dig, curl, and ss for checking open ports, along with common pitfalls in the field.

After episode 16 where we covered the Boot Process, Kernel, and Kernel Modules — understanding how the machine turns on, the kernel loads, and modules are managed — you now know what happens inside the machine. But a real-world server never lives alone: it must talk to databases, receive traffic from the internet, and answer DNS queries. Without networking, all those services are just isolated code.
Networking often feels like magic until you have the right vocabulary and tools. When a customer complains "the website is slow", "the connection keeps dropping", or "I can't connect to the database", you don't have a GUI to check — all you have is a terminal and a set of commands. The ability to read those commands' output quickly and accurately is the difference between a panicked admin and one calmly tracing the problem step by step.
In this episode 17, we'll build the Linux networking foundation: understanding network interfaces and IP addresses with the modern iproute2 suite, checking connectivity with ping and traceroute, investigating name resolution with dig, and confirming services are really listening with ss. By the end of the episode, you'll have a diagnostic procedure you can apply directly on any server.
The legendary ifconfig command is obsolete and no longer installed by default on modern distros. Its replacement is iproute2 — a set of tools that's more consistent and more informative. Get used to ip from now on.
ip addrThe output will show each interface — for example lo (loopback), eth0 (ethernet), or ens3/enp0s3 (predictable names in the systemd style). For a brief summary, use ip -brief addr:
ip -brief addrlo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 192.168.1.10/24Reading eth0 UP 192.168.1.10/24 means the interface is active, with the IPv4 address 192.168.1.10 and prefix /24 (netmask 255.255.255.0). The CIDR format (/24) is the modern way to write a netmask — 32 address bits, 24 of which are the network portion.
Interfaces tell the machine where it is; the routing table tells the machine where to send packets. Think of a travel map: if the destination is in the same city, send it directly; if it's out of town, send it via the highway leading to the outer gate (gateway).
ip routedefault via 192.168.1.1 dev eth0
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.10default line is the default gateway — the last route used when no specific route matches. Usually your router/modem's IP.192.168.1.0/24 line is a connected route — the local network reachable directly without a gateway.The commands you'll use most to add a static route:
sudo ip route add 10.0.0.0/8 via 192.168.1.1 dev eth0sudo ip route del 10.0.0.0/8Note
Changes with ip addr add or ip route add are temporary and disappear at reboot. For permanent configuration, use the distro's network management tool: netplan (modern Ubuntu), NetworkManager (nmcli), or systemd-networkd. Their priority order will be dissected deeper in episode 21.
ping: Is That Machine Alive and Reachable?ping is the most basic test: send ICMP echo request packets and wait for echo replies. It's not just a "is it alive" test, but also a test of latency and packet loss.
ping -c 4 8.8.8.8PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=117 time=3.42 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=117 time=3.44 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=117 time=3.48 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=117 time=3.41 ms
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 3.412/3.438/3.480/0.028 msNotice the ttl and time columns — both are powerful diagnostic signals. ttl=117 means the packet crossed about 7 routers (initial TTL is 128 for Windows/BSD, 64 for Linux — 128 − 117 = 11 hops, 64 − 117 = negative, meaning the source isn't Linux). This is a quick way to guess the target host's OS.
Warning
IPv4 vs IPv6 is a classic trap. ping google.com could mean ping IPv6 (::1, ping6) if DNS resolution returns an IPv6 address first. When IPv6 misbehaves, you'll see Destination unreachable: No route even though IPv4 is healthy. Use ping -4 to force IPv4 and ping -6 for IPv6, or ping the IP address directly.
traceroute and mtr: Tracing the Packet PathWhen ping fails or is slow, you need to know at which point the packet stops. traceroute sends packets with incremental TTL (1, 2, 3, ...) — each router traversed "returns" a TTL-expired message, so you see a list of hops:
traceroute -n 8.8.8.8 1 192.168.1.1 1.234 ms 1.198 ms 1.156 ms
2 10.0.0.1 4.001 ms 4.114 ms 3.987 ms
3 * * * (timeout — this router blocks ICMP)
4 72.14.215.85 21.233 ms 20.988 ms 21.001 msAn asterisk (*) at a hop doesn't mean the network is broken — many routers block ICMP. As long as the next hop responds, packets are still flowing.
mtr is a combination of ping + traceroute that continuously updates statistics in real time. It's an admin's favorite tool for latency debugging:
mtr -n -c 20 8.8.8.8The Loss% and Avg columns on the same row will immediately show the most problematic hop. If loss only appears at a specific hop, it's usually a transit router that doesn't respond to ICMP, not a dead path.
dig, nslookup, and hostHumans aren't comfortable memorizing 142.250.4.100; we memorize google.com. The translator between names and IPs is called a DNS resolver. Three tools that are all useful for checking it:
dig example.com;; ANSWER SECTION:
example.com. 1865 IN A 93.184.216.34The 1865 column is the TTL in seconds — how long the resolver may cache this result. The most useful part of dig output is often not the answer, but where it answered: SERVER: 127.0.0.53 means you're using the local systemd-resolved, while SERVER: 8.8.8.8 means the resolver went straight to public DNS.
nslookup example.comhost example.com| Tool | Strength | When to Use |
|---|---|---|
dig | Detailed output, can query any record type (A, AAAA, MX, TXT, NS) | Advanced DNS debugging |
nslookup | Familiar, simple | Quick name resolution check |
host | Most concise | Quick confirmation of a single record |
Example of querying other records with dig:
dig example.com MX +shortdig example.com NS +shortcurl and wget: Talking to HTTP ServicesThis isn't just a "download tool". curl is a versatile weapon for testing APIs, inspecting response headers, and simulating browser requests. It's mandatory preparation before you debug APIs in the upcoming DevOps episodes.
curl -I https://example.comHTTP/2 200
server: nginx
content-type: text/html; charset=UTF-8
content-length: 1256curl -v https://example.comcurl -O https://example.com/file.tar.gzwget https://example.com/file.tar.gzImportant
The "curl vs browser" trap: if a website opens in the browser but curl fails, don't immediately blame the network. The host could be blocking requests without a browser User-Agent, requiring a cookie/session, or using TLS not supported by an old curl client. Check the status code (403, 503) and use curl -v to see the TLS details. Also: curl -I only sends HEAD — many servers respond with a different code for HEAD vs GET. To mimic a browser, use curl -L (follow redirects) and set -A "Mozilla/5.0 ...".
ss: Checking Listening PortsAfter a service is running, the most important question is: is it really listening on the expected port, and on which interface? The answer is in ss (socket statistics) — the modern replacement for netstat.
sudo ss -tulpn| Flag | Meaning |
|---|---|
-t | TCP sockets only |
-u | UDP sockets only |
-l | Only sockets that are listening |
-p | Show the process owning the socket |
-n | Show numbers (IP/port), not service names |
Example output:
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* sshd
tcp LISTEN 0 511 127.0.0.1:5432 0.0.0.0:* postgresImportant reading above: sshd listens on 0.0.0.0:22 (all interfaces — vulnerable if the firewall is open), while postgres only on 127.0.0.1:5432 (localhost only — safe and correct). This is the pattern you look for when auditing security: database/administrative services should bind to localhost, not all interfaces.
sudo ss -tulpn | grep -E ":(22|80|443)\b"Tip
If ss doesn't show a port you believe is running, check three things in order: (1) the service is actually running (systemctl status), (2) the service is listening on the right port and the right interface, (3) the firewall isn't blocking — the full topic is in episode 19. Always read the Local Address column first before blaming the firewall.
When networking misbehaves, don't panic and don't randomly change configs. Follow this sequential flow — it's what senior admins use in the field:
ip -brief addr (status UP, IP present).ip route (a default via ... exists).ping -c 3 192.168.1.1 (problem in the local network).ping -c 3 8.8.8.8 (problem in DNS or WAN).dig example.com (if IP ping succeeds but the name fails, the problem is DNS).curl -v https://example.com (problem in the app/firewall).ss -tulpn | grep :443 (checking the server side).This sequence narrows the problem down layer by layer — from physical, network, transport, to application — so you don't waste time changing irrelevant settings.
1. Pinging a hostname vs an IP address. ping google.com tests three things at once (DNS + routing + connectivity). If it fails, you don't know which one broke. Always split it: ping the IP first, then ping the name. This determines whether the problem is in resolution or in the path.
2. Relying on ifconfig/netstat which aren't installed. Modern distros don't include them. ip and ss are the standard now — learn those two and leave the old ones behind.
3. Ignoring the -4/-6 flags. A misconfigured IPv6 network often makes ping hostname fail "weirdly" even though IPv4 is healthy. Be aware that resolution can return AAAA (IPv6) records first.
4. Reading * in traceroute as damage. A timing-out hop isn't proof the network is dead. Keep reading until the last hop before concluding.
5. curl -I vs a real request. HEAD doesn't always represent GET. If you suspect an application problem, use curl -v with the same method as the actual client.
6. Forgetting sudo for ss -p. Without sudo, the Process column is empty, so you can't tell which service opened the port. Run it with sudo when debugging ports.
In this episode 17, you've built a real Linux networking foundation: getting to know interfaces and IP addresses with ip addr and routing with ip route (iproute2), testing connectivity with ping and traceroute/mtr, dismantling DNS with dig/nslookup/host, communicating with HTTP services via curl and wget, and checking listening ports with ss. More importantly, you now have a sequential diagnostic procedure that narrows problems down layer by layer.
Key points to take home:
ip and ss are the modern standard; ifconfig and netstat are legacy./24) is the modern addressing language — understand it before touching configuration.ping tests many things at once — separate the IP test and the name test to isolate the problem.dig gives the most complete information; TTL and SERVER: are the keys to reading it.ss -tulpn shows listening ports along with the process and interface — the first security audit before touching the firewall.In the next episode 18 we'll secure remote access to servers through the topic Remote Access Using SSH & Secure File Transfer. You'll learn to harden sshd_config, exchange keys with ssh-keygen and ssh-copy-id, transfer files with scp and rsync, and create SSH tunnels — the skill that's the backbone of remote server administration. See you there!