To Follow Along
- Hardware: A computer on your network; a second device makes the tests more useful
- Software: A Linux terminal (the commands use iproute2's
ipandss,digfrom the dnsutils package andnc, as found on Ubuntu 24.04 and Debian 12/13); macOS and Windows equivalents are noted. Access to your router's admin page helps but isn't required. - Time: 30 to 60 minutes
Underneath all the acronyms, a network has one job: get a packet from one machine to another. Addresses say where the packet should go, routes say which way to send it, and DNS turns the names people type into addresses.
None of these ideas is hard on its own. The confusion comes from how they stack: when something breaks low down, the symptom shows up at the top, and you end up debugging a web app when the real problem is a bad cable.
IP Addresses Explained
An IPv4 address such as 192.168.1.100 is four numbers separated by dots. Each number ranges from 0 to 255 because it's 8 bits: the whole address is 32 bits, written as four decimal "octets".
That gives roughly 4.3 billion combinations, which sounded like plenty when IPv4 was standardised in 1981 and is nowhere near enough now. IPv6 fixes this with 128-bit addresses, and many ISPs and mobile networks already use it, but home LANs, labs and most internal networks still revolve around IPv4. This guide stays there.
Private vs Public Addresses
Three ranges are set aside for private networks by RFC 1918, and they're worth knowing by heart:
10.0.0.0to10.255.255.255(10.0.0.0/8)172.16.0.0to172.31.255.255(172.16.0.0/12)192.168.0.0to192.168.255.255(192.168.0.0/16)
None of these are routed on the public internet. Anyone can use them inside their own network, which is why every home router hands out 192.168.x.x or 10.x.x.x addresses. Your ISP typically gives your router one public IPv4 address, and the router performs NAT (Network Address Translation) so every device in the house can share it.
Your phone wants to load a webpage. It sends the request from 192.168.1.50 to the router. The router swaps that private source address for its public one (in the examples here, 203.0.113.15, an address from a range reserved for documentation) and sends the request out. When the response comes back, the router looks up which internal device and port that connection belongs to and forwards it there. The diagram in How a Request Leaves Your Network shows the whole path.
Subnet Masks: What the /24 Means
You'll see notation like 192.168.1.0/24 everywhere. It's CIDR notation (Classless Inter-Domain Routing, defined in RFC 4632), and the number after the slash is the prefix length.
What it means: the /24 says "the first 24 bits of this address identify the network." The remaining 8 bits identify individual devices on that network. With a /24, that lines up neatly with the dots: the first three numbers are the neighborhood, and the last number is the house. The same idea written as a dotted mask is 255.255.255.0: 24 one-bits followed by 8 zero-bits.
192.168.1.0/24 breaks down like this:
- Network: 192.168.1.x
- Available hosts: 192.168.1.1 through 192.168.1.254
- 254 usable addresses total: .0 is the network address and .255 is the broadcast address
The general rule: a prefix of length n leaves 32 โ n host bits, so 232โn addresses, minus 2 for the network and broadcast addresses. Cloud providers reserve a few more; AWS keeps five per subnet, as the 3-tier VPC guide notes.
Common Subnet Sizes
| CIDR | Subnet Mask | Usable Hosts | Use Case |
|---|---|---|---|
| /24 | 255.255.255.0 | 254 | Home networks, homelabs, small offices: the usual default |
| /25 | 255.255.255.128 | 126 | Splitting a /24 in half, for example for two VLANs |
| /16 | 255.255.0.0 | 65,534 | Corporate networks, cloud VPCs |
For a home network or a small lab, a /24 per network is plenty and keeps the arithmetic easy. Elaborate subnetting schemes rarely pay off for a handful of devices. Where more structure helps is separating traffic you don't want mixed (IoT devices, guests, servers), which is what VLANs are for; the OpenWrt guide and Linux Router Setup show how a router serves several subnets.
How Devices Find Each Other
Same Network (Direct Communication)
Two devices on the same subnet talk directly. No router involved. Device A broadcasts an ARP request ("who has 192.168.1.50?"), Device B answers with its MAC address, and from then on they send Ethernet frames straight to each other. Each machine keeps the answers in its neighbour (ARP) cache for a while, which you can see with ip neigh.
Different Networks (Routing)
Different subnet? The packet has to go through a router. Your machine compares the destination IP with its own address and prefix, sees it's not local, and sends the packet to its default gateway instead. The gateway (often 192.168.1.1 on home networks) decides where to forward it next. ip route shows your routing table; the line starting with default via is the gateway.
If your default gateway is wrong or missing, nothing outside your local subnet works, while everything on the subnet still does. That pattern is a strong hint. Likewise, if two machines have addresses in different subnets (say a /24 typo puts one on 192.168.2.x), they won't talk directly even when they're plugged into the same switch.
How a Request Leaves Your Network
Putting addresses, the gateway, NAT and DNS together, this is what happens when a laptop on the example network opens a website:
Two consequences of NAT are worth knowing. First, devices on the internet can't open connections to your laptop, because the router has no NAT entry telling it where unsolicited traffic should go; that's what port forwarding adds. Second, some ISPs put customers behind their own carrier-grade NAT, in which case the router's "public" WAN address isn't public either, and port forwarding can't work. For reaching home from outside in either case, a VPN is the usual answer (see WireGuard Cloud Deployment).
DNS: Turning Names into Addresses
This section is the longest in the guide because DNS problems are so easy to mistake for something else.
getent asks the system resolver, so it shows what applications actually get back. Captured on Ubuntu 26.04.1 under WSL 2.The basic idea: nobody types an IP address into a browser. You type example.com, and something has to translate that name into an IP address before any connection happens. That something is DNS.
The lookup chain goes like this:
- Your browser checks its own cache. Already resolved this domain recently? Use that.
- Cache miss. Ask the OS resolver. On Linux,
/etc/resolv.confsays which DNS server to query; on Ubuntu and other systems running systemd-resolved, it points at the local stub127.0.0.53, andresolvectl statusshows the real upstream servers. - The configured DNS server (your router, a public resolver, or a Pi-hole) either has the answer cached or does a recursive lookup: root servers, then TLD servers, then the authoritative nameserver for that domain.
- Answer comes back. Browser gets the IP. Connection proceeds.
Usually that's fast enough that you never notice it. When it fails, everything stalls. Web pages won't load. APIs time out. Docker containers can't pull images. apt update fails. And the error messages rarely say "DNS failure": you get "could not resolve host" if you're lucky, or "connection timed out", or a silent hang.
Working connectivity doesn't help if DNS is down. ping 8.8.8.8 works. ping example.com doesn't. That gap points at name resolution.
Caching causes the other common surprise. You update a DNS record, but the old answer is cached at several levels: your browser, your OS, your upstream resolver. The record's TTL says how long caches may keep it, so lowering the TTL a while before a planned change makes the switch faster. Flushing your local cache only fixes one layer. Running your own filtering resolver is covered in the Pi-hole Deployment Guide.
Testing DNS
# Look up a domain
nslookup example.com
# Or with dig (more detailed)
dig example.com
# Test a specific DNS server
dig @8.8.8.8 example.com
# Check what your system is actually using
cat /etc/resolv.conf
resolvectl status # on systems with systemd-resolved
# Flush DNS cache on Linux (systemd-resolved)
sudo resolvectl flush-caches
# Flush on macOS
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
A useful habit: if something network-related breaks, run dig early. If dig @8.8.8.8 example.com works but dig example.com doesn't, your local DNS server or config is the issue. If neither works, the problem is outbound connectivity, or the domain itself. In dig's output, the status: field in the header (NOERROR, NXDOMAIN, SERVFAIL) and the SERVER: line near the bottom tell you what was answered and by whom.
One more thing. Containers often resolve names differently from their host. On a user-defined Docker network, containers use Docker's embedded DNS server at 127.0.0.11, which also resolves other containers by name; on the default bridge network they get a copy of the host's resolver settings. Kubernetes uses its own cluster DNS. When a container can't resolve hostnames but the host machine can, check the container's /etc/resolv.conf first.
Ports: Addressing Applications
IP gets you to the machine. Port gets you to the application running on it. Think of the IP as the building address and the port as the apartment number.
127.0.0.53 entries are systemd-resolved's local DNS stub. Captured on Ubuntu 26.04.1 under WSL 2.The ports you'll actually encounter:
22- SSH80- HTTP443- HTTPS53- DNS3306- MySQL5432- PostgreSQL
Notation like 192.168.1.100:8080 means "port 8080 on that machine." Your browser, when connecting to a web server, uses a temporary high-numbered (ephemeral) port on your end and connects to 443 on the server's end. You only see your side's port number in tools like ss or packet captures.
Checking Port Connectivity
# Quick check โ is something listening on this port?
nc -zv 192.168.1.100 80
# Telnet works too (old school but reliable)
telnet 192.168.1.100 80
# PowerShell on Windows
Test-NetConnection -ComputerName 192.168.1.100 -Port 80
How it fails tells you something: "Connection refused" comes back immediately and means the host answered but nothing listens on that port; a long wait followed by a timeout means something (usually a firewall) dropped the packets.
DHCP: Automatic IP Assignment
Plug a device into a network and it doesn't magically have an address. It broadcasts a DHCP request, basically "someone give me an IP." A DHCP server, usually your router, responds with an available address plus the gateway and DNS server to use.
Device: "I need an IP."
DHCP Server: "Take 192.168.1.50. Gateway is 192.168.1.1. DNS is 192.168.1.1. Lease lasts 24 hours." (The lease time is whatever the server is configured with.)
That lease part matters. DHCP addresses aren't permanent. They expire and get renewed. For most client devices (laptops, phones) this is fine. For servers, you want an address that never changes: either a static IP configured on the machine (outside the DHCP pool) or a DHCP reservation on the router that always hands that machine the same address. Otherwise your database server can end up on a new address after a lease runs out, and everything pointing at the old one breaks.
Key Troubleshooting Commands
Check Your Own IP
# Linux (modern)
ip addr
ip route # default gateway is the "default via" line
# Linux (legacy) or macOS
ifconfig
# Windows
ipconfig
On Linux, the ip(8) command replaces the older ifconfig, route and arp tools. In ip addr output, look for state UP on the interface and an inet line with an address and prefix such as 192.168.1.50/24. An address starting with 169.254. means the machine gave up waiting for DHCP and picked a link-local address itself.
Most guides say "ARP resolves IPs to MAC addresses" and move on. In practice, ARP is where same-subnet problems hide: two devices accidentally given the same IP address answer ARP requests in turn, so connections to that address work intermittently; a stale cache entry after you swap hardware sends traffic to a MAC that's no longer there. ip neigh lists the cache (entries marked FAILED or INCOMPLETE got no reply), and sudo ip neigh flush dev eth0 clears it for one interface. If you suspect an address conflict, arping -D -I eth0 192.168.1.50 (from the iputils package) checks whether another machine answers for that address.
Test Basic Connectivity
# Step 1: Can I reach my gateway?
ping 192.168.1.1
# Step 2: Can I reach something on the internet by IP?
ping 8.8.8.8
# Step 3: Can I resolve a hostname?
ping example.com
Run these in order. Step 1 fails? Local network problem: cable, Wi-Fi, VLAN, switch, or wrong address/prefix. Step 2 fails but 1 works? Routing, the router's internet connection, or a firewall. Step 3 fails but 2 works? DNS. (Some networks block ping, so a failed ping on its own isn't proof; confirm with the next steps.)
Trace the Route
# Linux/macOS
traceroute example.com
# Windows
tracert example.com
This lists the routers between you and the destination. When packets die somewhere in the middle (reaching your ISP but not beyond, for example), traceroute shows roughly where. Rows of * * * mean that hop didn't reply, which many routers are configured not to do, so look at where the trace stops making progress rather than at single silent hops.
Check What's Listening
# Linux
ss -tuln
sudo ss -tulnp # also shows which process owns each socket
# macOS
netstat -an | grep LISTEN
# Windows
netstat -an | findstr LISTENING
This answers the question "is my application actually listening on the port I think it is?" Check the address column too: a service bound to 127.0.0.1:8080 only accepts connections from the same machine, while 0.0.0.0:8080 or [::]:8080 accepts them on every interface. ss(8) documents the filters, such as ss -tn state established.
The Layered Model (Quick Version)
The OSI model has seven layers. For everyday troubleshooting, five of them map onto concrete checks; the session and presentation layers rarely come up outside exams:
- Physical (1) - Is the cable plugged in? Is the link light on? Is Wi-Fi associated?
ip linkshows whether the interface sees a carrier. Unglamorous, and a surprisingly common cause of "network outages". - Data Link (2) - MAC addresses, switches, VLANs. The layer where ARP lives.
- Network (3) - IP addresses, routing. Can I ping it?
- Transport (4) - TCP/UDP, port numbers. Is the port open?
- Application (7) - HTTP, DNS, SSH. Is the service actually responding correctly?
Troubleshoot bottom-up. Start at the physical layer and work your way up to the application. Skipping ahead is how you end up reading application logs for a problem that lives two layers below.
Quick TCP vs UDP
TCP: connection-oriented, reliable and ordered, with retransmission when packets are lost. Used for web, SSH, file transfers. UDP: no connection and no delivery guarantees, so less overhead. Used for DNS queries, streaming, games and VPNs such as WireGuard. That's enough unless you're writing socket code. It also explains a common firewall mistake: allowing TCP 53 but not UDP 53 breaks most DNS.
VPNs and Tunneling
A VPN wraps your traffic in an encrypted tunnel. Your packets enter the tunnel on your device, travel across the internet in encrypted form, and emerge on the VPN server's end. From your machine's perspective, you're on the remote network. You get an IP on that network. You can reach internal resources as if you were sitting in the same building.
Practical uses: accessing your homelab from a coffee shop, connecting to a corporate network from home, or routing all your traffic through a trusted exit point on untrusted public Wi-Fi. WireGuard's configuration is much smaller than OpenVPN's, which makes self-hosting a VPN far more approachable; the WireGuard Cloud Deployment guide walks through a server on a VPS. Pick a VPN subnet that doesn't overlap the networks you connect from, or traffic for those addresses won't know which way to go.
Firewalls: Several Layers of Rules
A firewall is an ordered list of rules, such as "allow port 22 from 10.0.0.0/8, drop everything else".
The catch: there are usually multiple firewalls between you and your destination. The host firewall (nftables/iptables, ufw, Windows Defender Firewall). The router's firewall. Cloud security groups and network ACLs (the 3-tier VPC guide shows both). Any one of them can silently drop your packets with zero feedback. When a connection just hangs, with no error and no rejection, a firewall silently discarding the traffic is the most likely explanation; a rule that rejects instead gives you an immediate "connection refused" or "no route to host".
Troubleshooting Flow
Put together, this is an order that works for most "the network is down" reports. Each step only makes sense if the one before it passed:
- Is the link up? -
ip link: the interface should beUPwithLOWER_UP. If not: cable, port, Wi-Fi association, or a disabled interface. - Do I have an IP in the right subnet? -
ip addr: no address, or a169.254.x.xone, points at DHCP; an address in the wrong subnet points at a static-config typo. - Can I hit the gateway? -
ip routeto find it, thenping 192.168.1.1. Failing here with a correct address points at layer 2: switch, VLAN, ARP (ip neigh). - Can I hit the internet by IP? -
ping 8.8.8.8. Failing here points at the router's uplink, its NAT, or a firewall. - Does DNS resolve? -
dig example.com, thendig @8.8.8.8 example.comto separate your resolver from the internet. - Can I reach the target machine? -
ping TARGET_IP(remember some hosts block ping) ortraceroute TARGET_IP. - Is the target port open? -
nc -zv TARGET_IP PORT: refused means nothing listening; timeout means a firewall in the way. - Is the application running and listening? - on the target,
sudo ss -tulnpand the application's logs.
The first four steps are quick, and they tell you whether the problem is on your machine, on your network, or further away. Jumping straight to step 8 means reading application logs while the real issue may be a gateway misconfiguration several layers below.
What's Next
Where to go from here depends on what you're building:
- VLANs: segment your homelab into isolated networks, the natural next step if you're running multiple services. Building your own router with Linux Router Setup or OpenWrt puts all of this page's concepts (gateway, DHCP, NAT, DNS) in one box you control.
- NAT internals: port forwarding, hairpin NAT, the details that matter once you expose services to the internet.
- Cloud networking: the same ideas with different names. Subnets, route tables and gateways reappear in the 3-tier VPC guide.
- IPv6: increasingly common on ISP and mobile networks, and worth learning even if your LAN is IPv4-only today.



