sn sysnerdunderstand it from the kernel up
← curriculum map
Networking
Core · ~50 min · 5 labs
map / Concepts / Networking
Concepts Core ~50 min requires: Operating Systems

Networking

Every network operation is layers wrapped around layers. Debugging is just unwrapping them in order — so we learn to see each layer directly.

Q1See L2 and L3 on one interfacewarm-up

An interface has a hardware address (L2, the MAC) and an IP address (L3). Packets are addressed by IP but delivered on the wire by MAC.

Task

List your interfaces and identify the MAC and the IP on one of them.

Verify it yourself
verify
$ ip addr show

link/ether is the L2 MAC; inet is the L3 IP. Two addresses, two layers, one interface.

Reveal solution
solution
$ ip addr show
$ ip -br addr   # compact view
Q2Capture the 3-way handshakecore

A TCP connection opens with SYN → SYN-ACK → ACK. You can watch it happen on the wire.

Task

Sniff TCP on port 443 in one terminal, then make an HTTPS request in another.

Verify it yourself
verify
$ sudo tcpdump -i any -n 'tcp port 443' -c 6

Run curl -s https://example.com >/dev/null in a second shell. You'll see flags [S], [S.], [.] — the handshake.

Reveal solution
solution
$ sudo apt install -y tcpdump   # if needed
# terminal 1:
$ sudo tcpdump -i any -n 'tcp port 443' -c 6
# terminal 2:
$ curl -s https://example.com >/dev/null
Q3Read socket statescore

A socket moves through states — LISTEN, ESTABLISHED, TIME_WAIT. ss is the modern way to see them (forget netstat).

Task

Start a listener, then find it and its state.

Verify it yourself
verify
$ ss -tlnp | grep 8000

You see the socket in LISTEN on :8000. Connect to it and check ss -tan to watch ESTABLISHED appear.

Reveal solution
solution
$ python3 -m http.server 8000 &
$ ss -tlnp | grep 8000
Sponsored

Reach engineers who read the man page

Native, contextual, no tracking — this is how the curriculum stays free.

Q4Trace DNS resolutioncore

A name becomes an IP through a resolver chain (/etc/nsswitch.conf/etc/hosts → DNS). Two tools show two views.

Task

Resolve a name with the DNS-only path and with the full system path.

Verify it yourself
verify
$ getent hosts example.com

dig +short example.com asks DNS directly; getent follows the system resolver order — sometimes they differ, and that difference is a classic bug.

Reveal solution
solution
$ dig +short example.com
$ getent hosts example.com
Q5Break-and-fix — refused vs timed outdebug

Two failures that look similar but mean opposite things: connection refused (something said "no one's here") vs timeout (something ate the packet — usually a firewall).

Task

Trigger a refused connection, then explain how you'd tell it apart from a timeout.

Verify it yourself
verify
$ curl -sS --max-time 3 http://localhost:9999 ; echo "exit=$?"

You get Connection refused immediately — nothing is listening. A firewall drop would instead hang until the timeout. Refused = fast + reset; timeout = slow + silent.

Reveal solution
solution
# refused (fast): nothing listening
$ curl -sS --max-time 3 http://localhost:9999
# start something and it connects:
$ python3 -m http.server 9999 & sleep 1
$ curl -sS --max-time 3 http://localhost:9999 | head
What you just built

Layers, the handshake, socket states, and resolution are the map you'll use to debug everything from a hung curl to a broken Kubernetes Service. In the Linux module you'll build the machinery that implements all of it.