DEV Community

Roger Oliveira
Roger Oliveira

Posted on Originally published at Medium

Linux From Zero Networking, DNS, Ports and Sockets for Platform Engineers

In the first two posts of this series we covered the terminal, files, permissions, processes and systemd. By now you can look at a Linux box and understand what's running and who's allowed to touch what. What's missing is the piece that shows up in almost every real incident: networking.

My thesis for this series stays the same: Platform Engineering starts before Kubernetes. Before you debug a CrashLoopBackOff or an Ingress that won't resolve, you need to know how to investigate networking on the bare operating system. Without that, troubleshooting is just guessing.

How Linux sees a network interface

Every conversation starts with an interface. On modern systems, the reference tool is ip, not the old ifconfig:

ip a
Enter fullscreen mode Exit fullscreen mode

This shows interfaces (lo, eth0, ens160, container/bridge interfaces like docker0 or cni0), assigned IPs, and state (UP/DOWN). To understand where traffic actually goes, the routing table is next:

ip route
Enter fullscreen mode Exit fullscreen mode

The default route (default via ...) decides where a packet goes when no more specific route matches. On platforms with multiple interfaces (production, management, storage), one of the most common operational mistakes is assuming traffic leaves through one interface when the routing table actually sends it through another.

DNS: the most underrated cause of "it's down"

A huge share of incidents that look like "the app is down" are actually name resolution failures. The basic flow on Linux goes through:

  • the local resolver, historically configured in /etc/resolv.conf (on many modern distros, now managed by systemd-resolved or NetworkManager);
  • the lookup order defined in /etc/nsswitch.conf (local /etc/hosts before or after DNS, depending on configuration);
  • the DNS server actually queried, which in corporate environments is usually an internal DNS with forwarders to the internet.

Three commands solve 90% of DNS investigations:

dig example.com
dig example.com +trace
resolvectl status
Enter fullscreen mode Exit fullscreen mode

dig +trace is the most underused one: it shows the full resolution path, from the root servers down to the final answer, and usually exposes exactly where the chain broke — a dead forwarder, an expired cache TTL, a record that no longer exists.

A pattern worth memorizing: "I can't ping the name, but I can ping the IP" is almost always DNS, never networking. Plenty of engineers waste time looking at firewalls and routes when the whole problem is name resolution.

Ports, sockets, and what "LISTEN" actually means

A socket is the meeting point between a process and the network — a (IP address, port, protocol) tuple the kernel uses to hand packets to the right process. To see this live:

ss -tulpn
Enter fullscreen mode Exit fullscreen mode
  • -t and -u show TCP and UDP sockets;
  • -l shows only the ones listening — accepting new connections;
  • -p shows the owning process;
  • -n skips name resolution, keeping the output fast and literal.

The gap between a service "listening" and a service "actually accepting connections" is where a lot of platform bugs live: a process can be LISTENing on the right port and still refuse a connection because it's bound only to 127.0.0.1 (loopback) while the client comes from a different interface, or because a firewall rule drops the packet before it even reaches the process.

For TCP connection states (SYN_SENT, ESTABLISHED, TIME_WAIT, CLOSE_WAIT), ss -tan gives the full picture — and an abnormal pile-up of CLOSE_WAIT, for example, usually points to an application not closing connections properly, not to a networking issue at all.

A troubleshooting checklist I actually use

When a service "won't connect," the order that wastes the least time is:

  1. Is the port actually listening? (ss -tulpn on the service's host)
  2. On which interface? (0.0.0.0 vs 127.0.0.1 binding explains half of "works locally, not remotely")
  3. Does the name resolve to the right IP? (dig, compared against what you expect)
  4. Does a route to the destination exist? (ip route get <destination-ip>)
  5. Is a firewall/security-group rule dropping the packet somewhere in between?
  6. Does the TCP handshake actually complete? (ss -tan on the client side during the connection attempt)

That sequence — port → bind → DNS → route → firewall → handshake — is an evidence-based investigation, not a guess. It's the same principle behind this whole series: you don't guess where the problem is, you eliminate one layer at a time until only one explanation is left.

Why this matters beyond plain Linux

This entire toolkit reappears, almost untranslated, inside Kubernetes: ClusterIP and Service objects are, underneath, iptables/ipvs rules doing the exact same job of routing a packet to the right socket; CoreDNS is the same name-resolution problem, just running inside the cluster; an Ingress that won't respond usually boils down to the same six steps above, with one more layer of abstraction on top.

Engineers who understand networking and sockets at the OS level debug Kubernetes with evidence. Engineers who don't just memorize kubectl commands and hope for the best.

This is the third post in the Linux From Zero series. Previous posts cover terminal/files/permissions and processes/systemd — hands-on labs live in the kubernetes-do-zero-ptbr repository. Next up: SSH and remote administration.

Top comments (0)