Skip to content

Phase 1 · FOUNDATIONS

Networking 101 — IP, DNS, ports, curl

Day 11 of 90 ~55 min 0/20 in phase Builds on Day 10

By the end of today

  • Read an IP address and CIDR block, and name what /24 means
  • Explain how DNS turns a name into an IP address
  • Use curl -I and -v to walk the request path and debug it

How a name becomes a response: IP, DNS and ports

Section 1 of 5 · ~3 min

Type curl https://example.com and a surprising amount happens in the half-second before any text appears. Four things must line up: an address to reach, a name-to-address lookup, a port to knock on, and a request the other end understands. Learn those four and networking stops being magic.

Every machine on a network has an IP address — a number that says where it is. IPv4 writes it as four bytes separated by dots — 93.184.216.34 — each octet 0–255. Addresses come in blocks written in CIDR notation: 10.0.0.0/24 means “the first 24 bits are the network, the last 8 identify hosts,” which is 256 addresses from 10.0.0.0 to 10.0.0.255. A /16 fixes only 16 bits and leaves 65,536 addresses; the smaller the number after the slash, the bigger the block. You will read CIDR every single day — firewall rules, cloud subnets, and 0.0.0.0/0 (which means every address) all speak it.

An address gets you to the machine; a port gets you to the right program on it. One server runs many services, so each listens behind a numbered door: 80 for HTTP, 443 for HTTPS, 22 for SSH, 5432 for Postgres. So example.com:443 means “port 443 on that host.” Ports 0–1023 are the reserved, well-known ones.

But you typed a name, not a number, so first that name has to be resolved. DNS, the Domain Name System, is the internet’s phone book: it turns example.com into an IP. Your machine asks a resolver — often 1.1.1.1, Cloudflare’s public resolver, or one your network hands you — and the resolver walks the hierarchy (root, then .com, then example.com’s authoritative server) and returns the address, cached for a while so the next lookup is instant. The record type matters: an A record maps a name to an IPv4 address, AAAA to IPv6, and CNAME points one name at another.

Real world: Reaching a service is like phoning a large company. DNS is the directory that turns “Acme Corp” into a phone number — the IP. Dialling the main line reaches the building, but you still need an extension to land on the right desk, and that extension is the port. Dial a wrong number and nobody answers; get the extension wrong and you reach the wrong department entirely.

Put it together and you have the request path — the trip from a name to bytes on your screen:

The request path: curl resolves the name to an IP via a DNS resolver, connects to that IP on port 443, and reads back an HTTP response. curl example.com you type a name DNS resolver name → IP connect IP : 443 address + port HTTP 200 response + body
Four steps from a name you type to bytes you read — curl -v shows you each one.

curl is how you walk that path by hand. curl -I sends a HEAD request and prints only the response headers — the status line, content type, and any redirects — without downloading the body, which is perfect for “is it up, and what does it say?”. curl -v (verbose) narrates the whole trip: the IP it resolved and connected to, the TLS handshake, the request headers it sent, and the response headers that came back. When something is broken, -v shows which of the four steps failed — a DNS error, a refused connection, or a bad HTTP status — and that is the entire skill: knowing which link in the chain snapped.

Hands-On Lab

Section 2 of 5 · ~2 min

Budget about 25 minutes. Open your WSL2 Ubuntu 24.04 terminal (if you have not set up WSL2 yet, do Day 0 first — macOS and Linux users can follow along in their built-in terminal). You need a working internet connection; type each command and read every line of output.

# 1. What IP addresses does this machine hold? -brief keeps it to one line per interface.
ip -brief address
# Output (your addresses differ; note the /8 and /20 — that is CIDR on your own box):
# lo               UNKNOWN        127.0.0.1/8 ::1/128
# eth0             UP             172.28.113.45/20 fe80::215:5dff:fe10:2a3c/64
# 2. Where does traffic leave for the wider internet? The default route names the gateway.
ip route
# Output (WSL2 uses a NAT gateway; the CIDR line describes your local subnet):
# default via 172.28.112.1 dev eth0 proto kernel
# 172.28.112.0/20 dev eth0 proto kernel scope link src 172.28.113.45
# 3. Which resolver will turn names into IPs for you? WSL2 generates this file automatically.
cat /etc/resolv.conf
# Output (the nameserver address depends on your WSL networking mode):
# # This file was automatically generated by WSL. ...
# nameserver 172.28.112.1
# 4. Resolve a name to an IP with no extra tools — getent uses the system resolver.
getent hosts example.com
# Output (the address you get will differ — DNS answers change and rotate):
# 23.215.0.136    example.com
# 5. Ask only "is it up, and what does it say?" — -I fetches headers, not the body.
curl -I https://example.com
# Output (date and etag vary; the 200 status line is what you are checking):
# HTTP/2 200
# content-type: text/html
# date: Fri, 10 Jul 2026 09:14:07 GMT
# 6. Ports and redirects: plain HTTP (port 80) to a site that forces HTTPS shows a 301.
curl -I http://github.com
# Output (the Location header points you at the HTTPS URL on port 443):
# HTTP/1.1 301 Moved Permanently
# Content-Length: 0
# Location: https://github.com/
# 7. Narrate the whole trip. -v prints to stderr; -o /dev/null drops the HTML body.
curl -sSv https://example.com -o /dev/null
# Output (trimmed — the connected IP will differ; read it top to bottom as the request path):
# *   Trying 23.215.0.136:443...
# * Connected to example.com (23.215.0.136) port 443
# * using HTTP/2
# > GET / HTTP/2
# > Host: example.com
# > user-agent: curl/8.5.0
# >
# < HTTP/2 200
# < content-type: text/html
# 8. Prove the address+port you actually connected to, with curl's -w write-out template.
curl -s -o /dev/null -w '%{http_code} %{remote_ip}:%{remote_port}\n' https://example.com
# Output (status code, then the IP and port curl reached — again, the IP varies):
# 200 23.215.0.136:443

Read the path back out loud from the last two commands: a name became an IP (step 4), curl connected to that IP on port 443 (step 7), sent an HTTP request, and got a 200 back (step 8) — that is every arrow in the diagram, run by hand.

Common Errors & Fixes

Section 3 of 5 · ~3 min

These three catch almost everyone in their first week with curl and ip on Ubuntu 24.04. Read the error text slowly — learning to parse which step failed is the actual skill.

Common error: Fat-fingering the hostname — running curl -I https://exmaple.com — prints:

curl: (6) Could not resolve host: exmaple.com

Why: curl never got as far as connecting. It handed the name to the resolver, the resolver found no record for exmaple.com, and it came back empty. Error (6) is curl’s specific code for a DNS failure — the first link in the request path.

Fix: Check the spelling, then confirm resolution independently with getent hosts example.com. If a name you know is correct still fails, the problem is your resolver or /etc/resolv.conf, not the site.

How you’d spot it in prod: “Could not resolve host” in a deploy log or app error usually means a typo in a config value, an internal DNS name that only resolves inside a VPC, or a resolver that is down. Verify the name resolves from the box that is actually failing, not from your laptop.

Common error: Hitting a closed port — running curl -I http://localhost:8080 when nothing listens there — prints:

curl: (7) Failed to connect to localhost port 8080 after 0 ms: Connection refused

Why: The host is right there — localhost needs no DNS — but nothing is bound to port 8080, so the kernel answers the TCP handshake with an immediate RST and curl reports “Connection refused”. That is a fast, definite rejection: the machine is reachable and actively said “no one is home on that door.” It is the opposite of a firewall silently dropping packets, which leaves you hanging until a timeout. Error (7) is the connect step failing, one link further along than a DNS error.

Fix: Use the port the service actually serves — 443 for HTTPS, 80 for plain HTTP. If you own the box, check what is listening with ss -tln (tomorrow’s tool). A refusal means “reached the host, wrong or closed door”; a hang/timeout more often means a firewall silently dropping packets.

How you’d spot it in prod: “Connection refused” between two services almost always means the target process is not running or is bound to 127.0.0.1 instead of 0.0.0.0, or a security group blocks the port. Confirm the service is up and listening on the expected port before blaming the network.

Common error: Reaching for the old habit — running ifconfig to see your IP on Ubuntu 24.04 — prints:

Command 'ifconfig' not found, but can be installed with:
sudo apt install net-tools

Why: ifconfig (and netstat) ship in the legacy net-tools package, which Ubuntu no longer installs by default. The modern, always-present replacement is the ip command from iproute2.

Fix: Use ip address (or ip -brief address) to see interfaces and IPs, and ip route for the routing table. Do not install net-tools out of habit — every current tutorial and runbook assumes ip.

How you’d spot it in prod: A script that calls ifconfig will fail on a fresh Ubuntu 24.04 host or a slim container image with “command not found”. The fix is to port the script to ip, not to add net-tools to the image.

Networking Interview Questions

Section 4 of 5 · ~1 min

Cover the answers below and say your own version out loud first — trace the request path from name to response before you reveal each answer. Recalling before revealing is what makes these stick when an interviewer asks them cold. The four questions and answers render right after this note.

Go Deeper

Section 5 of 5 · ~1 min

Optional extras if you have ~30 more minutes today:

  • 5 min — Run man curl and skim the -I, -v, -w and -L flags; they are the four you will reach for most often.
  • 10 min — Read the Subnets and CIDR section of the Networking for DevOps guide for the bit-by-bit view of why /24 is 256 addresses and /16 is 65,536.
  • 10 min — Play with prefix lengths in the CIDR checker and subnet calculator to watch the host count change as the slash moves.
  • 5 min — Convert one IP between decimal, binary and hex in the IP address converter to see the four-bytes idea directly.
Walk me through what happens when you run curl https://example.com. Both

First the name is resolved: my machine asks a DNS resolver, which returns an IP address for example.com. curl opens a TCP connection to that IP on port 443, the HTTPS port. Over that connection it does a TLS handshake so the traffic is encrypted, then sends an HTTP request — a GET for the path plus a Host header. The server replies with a status line like HTTP/2 200, response headers, and the body. curl prints the body and the process exits. If I add -v, curl narrates each of those steps, so when something breaks I can see whether it was DNS, the connection, TLS, or the HTTP status that failed.

What is CIDR notation, and what does /24 mean? Both

CIDR — Classless Inter-Domain Routing — writes an IP range as an address plus a prefix length, like 10.0.0.0/24. The number after the slash is how many leading bits are fixed as the network part; the rest identify hosts. A /24 fixes 24 bits and leaves 8, so it covers 256 addresses, 10.0.0.0 to 10.0.0.255. A /16 fixes 16 bits — 65,536 addresses — and a /32 is a single host. The smaller the prefix number, the bigger the block. You read CIDR constantly in firewall rules, cloud subnets, and route tables, where 0.0.0.0/0 is shorthand for every address.

What is the difference between an IP address and a port? Both

An IP address identifies a machine on the network — it says which host to reach. A port identifies which program on that host you want, because one server usually runs many services at once. The IP gets your packet to the right building; the port gets it to the right desk inside. Ports are 16-bit numbers, 0 to 65535, and the well-known ones are worth memorising: 80 for HTTP, 443 for HTTPS, 22 for SSH, 5432 for Postgres. So 93.184.216.34:443 means port 443 on that host. If the host is up but nothing is listening on the port, you get connection refused rather than a timeout.

A teammate says 'the site is down.' How do you start debugging? Service

I narrow down which link in the chain broke instead of guessing. First, does the name resolve — a quick lookup, or curl -v to see the resolved IP; a 'could not resolve host' points at DNS. If it resolves, can I connect to the port — curl -v shows the connect succeeding or 'connection refused', which usually means the service is not listening or a firewall blocks it. If the connection is fine, what HTTP status comes back — a 200, a 500 from the app, or a 502 from a proxy tell very different stories. Working DNS then connection then TLS then HTTP, in order, turns 'it is down' into one specific failing step.

Mark Day 11 complete

Tomorrow you turn detective — ss, dig and ping become one repeatable flow for finding exactly where a connection breaks.

Stuck on today’s lab? Ask in Mission 90 Q&A