feat(root02): author Linux Administration & Networking

Adds all 6 ROOT 02 modules (Linux system administration, storage & filesystems, the
Networking Mental Model, Linux network inspection, DNS & HTTP, Linux troubleshooting) — 37
activities, each with a real lesson, demonstration/guided exercise, knowledge check, hands-on
Lab, and reflection. The Networking Mental Model module (M3) gets deliberately extra depth per
its "critical module" designation, with no lab by design — conceptual mastery via knowledge
check and guided exercise, matching root-05-m00's own precedent.

Adds 6 new hands-on Linux/networking scenarios plus 2 MCQs: linux-service-inspection (inspects
the platform's own real nginx without touching it — a genuinely safe, real service-inspection
target that avoids ever risking the Lab's own connectivity), linux-service-lifecycle (start/
verify/stop a fully controllable service), linux-storage-inspection, linux-network-inspection
(ip/ss/getent/curl, each framed as answering one specific diagnostic question),
linux-dns-http-diagnosis (a genuine DNS-resolves-but-wrong-port failure, diagnosed and fixed),
and linux-troubleshooting-framework (a real missing-config-file failure, resolved via the
RootNode Observe/Evidence/Hypothesis/Test/Repair/Validate/Prevent framework). All tested
end-to-end via the real scenario-validation API, including negative tests confirming they fail
when unsolved.

Wires rootnode-linux-networking-assessment (2 required + 4 random-draw scenarios) using the
existing Phase 3B assessment engine.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
2026-08-26 17:07:46 -05:00
co-authored by Claude Sonnet 5
parent b6516a74db
commit e007bcf000
39 changed files with 1752 additions and 0 deletions
@@ -0,0 +1,104 @@
# Networking Mental Model
## Why this module gets extra attention
Nearly everything you'll do for the rest of ROOT_ — container networking, Kubernetes Services,
Ingress, NetworkPolicy, DNS, cloud infrastructure — is a variation on the SAME small set of
ideas this module introduces. Get this model solid now, and every later networking topic becomes
"the same thing again, one layer up." Skip it, and every later module will feel like memorizing
unrelated facts. The goal here is operational REASONING, not subnet arithmetic — you will not be
asked to calculate a subnet mask by hand.
## The chain, layer by layer
Think of reaching another machine as passing through a fixed sequence of layers, each of which
can independently succeed or fail:
```
Host
↓
Network interface (this machine's connection to a network)
↓
IP address (this machine's address on that network)
↓
Subnet (which other addresses are "local" to reach directly)
↓
Default gateway (where to send anything NOT local)
↓
Routing (the actual path traffic takes)
↓
DNS (translating a name into an IP address)
↓
Port (which specific service on that IP)
↓
TCP / UDP (how the connection itself behaves)
↓
Application protocol (HTTP, etc. — the actual conversation)
```
## Each layer, briefly
- **Network interface** — your machine's actual network connection (`eth0`, etc.). No interface,
no networking, full stop.
- **IP address** — this machine's address on a given network. IPv4 addresses look like
`172.17.0.2`. `127.0.0.1` (aka `localhost`) is special: it always means "this same machine,"
never anywhere else. `0.0.0.0` is different again — when a SERVICE binds to it, it means
"listen on every interface this machine has," not a real destination address.
- **Subnet** — a range of addresses considered "local" to each other, expressed as CIDR
(`172.17.0.0/16` means every address starting `172.17.`). You don't need to calculate subnet
math by hand — you need to recognize that two addresses in the same subnet can talk directly,
while addresses outside it need a gateway.
- **Default gateway** — the address your machine sends traffic to when the destination ISN'T in
its own subnet — effectively "ask this router to figure out the rest."
- **Routing** — the actual decision-making about which path traffic takes; `ip route` shows your
machine's routing table (Module 4 makes this hands-on).
- **DNS** — translates a human-readable name (`example.com`) into an IP address, since IP
addresses aren't what humans want to remember or type.
- **Port** — a single IP address can host MANY services simultaneously; the port number is what
distinguishes "which one." Port 80 conventionally means HTTP, 443 HTTPS, 22 SSH — conventions,
not hard rules.
- **TCP vs. UDP** — TCP is connection-oriented and guarantees delivery/order (most web traffic,
SSH); UDP is connectionless and faster but delivers no guarantees (DNS queries themselves,
video streaming). Client/server: one side (the server) listens on a fixed port waiting for
connections; the other (the client) initiates them.
## The reasoning skill: "where is the failure?"
Given this chain, a real diagnostic question decomposes into a sequence of yes/no checks, each
isolating ONE layer:
- Does the host have an IP address at all?
- Is the destination local (same subnet) or remote?
- Is there a valid route to it?
- Can the name resolve to an IP?
- Can the destination PORT actually be reached?
- Is a service actually listening there?
- Does the application itself respond correctly?
Module 4 makes each of these a real command. Module 5 walks the complete request path end to
end. Module 6 formalizes this into RootNode's troubleshooting framework, applied to networking
specifically.
## Instructor Notes
**Lesson goal:** This module gets outsized weight for a reason — it's the single highest-
leverage conceptual investment in ROOT 02. Do not rush it to "cover the topics"; depth here pays
off across ROOT 04, ROOT 05-10, and beyond.
**Approximate timing:** 25 minutes read; 15-20 minutes live with discussion — longer than a
typical lesson, deliberately.
**Common misconception to watch for:** treating `0.0.0.0` as a real destination address rather
than a "listen on every interface" bind convention — this genuinely confuses students later when
they see it in a container's own listening-port output.
**Discussion question:** Walk through a real failure narrative live: "You `curl` a URL and get
'Connection refused.' Which layers does that rule OUT, and which remain suspects?" (Answer:
rules out DNS entirely — you got FAR enough to attempt a TCP connection — and rules out "nothing
is listening at all" being the ENTIRE problem elsewhere; "refused" specifically means something
actively rejected the connection, most often nothing listening on that exact port.)
**Optional extension:** contrast "Connection refused" vs. "Connection timed out" vs. "Could not
resolve host" as three DIFFERENT failure signatures pointing at different layers — worth a full
discussion pass if time allows, since Module 5 depends on students already sensing this
distinction.
@@ -0,0 +1,56 @@
# Demonstration: Three Failures That Sound Similar But Aren't
## OBSERVE
All three of these LOOK like "it didn't work" — but each one rules out and rules in completely
different layers.
```
$ curl http://this-name-does-not-resolve.invalid/
curl: (6) Could not resolve host: this-name-does-not-resolve.invalid
```
## HYPOTHESIS
Which layer does THIS failure point at — DNS, routing, the port, or the application itself?
## INSPECT
"Could not resolve host" happens BEFORE any network connection is even attempted — it's purely a
DNS failure. No IP was ever found to connect to.
## CHANGE
Now a different failure, against a name that DOES resolve:
```
$ curl http://localhost:9999/
curl: (7) Failed to connect to localhost port 9999: Connection refused
```
DNS/name resolution already succeeded here (`localhost` always resolves). "Connection refused"
means a TCP packet reached the destination and was ACTIVELY rejected — almost always because
nothing is listening on that port.
## VERIFY
A third signature, distinct from both:
```
$ curl http://10.255.255.1:80/
curl: (28) Failed to connect to 10.255.255.1 port 80: Connection timed out
```
No response at all, not even a rejection — usually means the destination is unreachable
(no route, or blocked silently), not that something is running but declining you.
## Instructor Notes
**Demo goal:** Get students to viscerally distinguish these three error MESSAGES as three
different diagnostic starting points, not interchangeable "it's broken" signals.
**Approximate timing:** 10 minutes live.
**Common mistake to watch for:** treating every connection failure as "the network is down" —
each of these three messages should immediately narrow which layer to investigate next, per
Module 5's troubleshooting exercise.
@@ -0,0 +1,45 @@
# Knowledge Check: Networking Mental Model
---
**1. What's the actual difference between an IP address and a port?**
*Answer:* An IP address identifies a specific machine on a network; a port identifies WHICH
service on that machine, since one IP can host many services simultaneously.
---
**2. `curl` reports "Could not resolve host." Which layer failed?**
*Answer:* DNS — the name never got translated into an IP address, so no connection attempt was
even made.
---
**3. `curl` reports "Connection refused" instead. What does that specifically tell you?**
*Answer:* The name resolved fine and the destination was reachable, but nothing is listening on
the port you tried — the connection attempt was actively rejected, not silently ignored.
---
**4. What is a default gateway for?**
*Answer:* It's where your machine sends traffic whose destination ISN'T in its own local subnet
— effectively "ask this router to figure out how to get there."
---
**5. True or false: `0.0.0.0` is a real destination address you could `curl`.**
*Answer:* False (in the way most students initially assume) — when a SERVICE binds to
`0.0.0.0`, it means "listen on every interface," a bind convention, not a real host you'd
connect to as a destination.
## Instructor Notes
**Facilitation:** Questions 2-3 are worth spending real time on together — the point isn't
memorizing the exact error text, it's the underlying "which layer does this rule out" reasoning.
**Approximate timing:** 8 minutes (slightly longer than a typical knowledge check, given this
module's weight).
@@ -0,0 +1,33 @@
# Guided Exercise: Diagnose From the Symptom Alone
This is a paper exercise — reason through each case using only the mental model, before any
hands-on Lab work.
## Your task
For each symptom, name which layer(s) it rules OUT, and which remain genuine suspects:
1. `ping 8.8.8.8` succeeds, but `curl https://example.com` fails with "Could not resolve host."
2. `dig example.com` returns a correct-looking IP address, but `curl https://example.com` times
out with no response at all.
3. `curl http://internal-service:8080/` returns "Connection refused," but
`curl http://internal-service:9090/` (a different port, same host) succeeds.
## A worked shape to check yourself against
1. Rules out: basic connectivity/routing to the internet (ping succeeded). Remaining suspect:
DNS specifically — something is preventing name resolution even though raw IP connectivity
works.
2. Rules out: DNS (resolution clearly succeeded). Remaining suspects: routing/reachability to
that specific IP, or a firewall silently dropping the connection — "no response at all" is the
timeout signature, not the "actively rejected" signature.
3. Rules out: DNS AND general reachability to that host (port 9090 worked). Remaining suspect:
narrowed all the way down to "nothing is listening on port 8080 specifically" — the most
precisely isolated diagnosis of the three.
## Instructor Notes
**Facilitation:** Item 3 is the strongest example of "isolate one variable" reasoning (same
host, different port) — worth highlighting explicitly as the gold-standard diagnostic pattern.
**Approximate timing:** 10-12 minutes live discussion; 8 minutes self-paced.
@@ -0,0 +1,30 @@
# Reflection: One Model, Reused Everywhere From Here On
## Reflection questions
1. Before this module, how would you have described "the network is broken" to a colleague?
How would you describe it now, more precisely?
2. This module deliberately avoided subnet math. Do you feel that cost you anything real, given
the module's actual goal (reasoning about WHERE a failure is, not calculating addresses)?
## Real Ops takeaway
**Every networking topic for the rest of ROOT_ is this same chain, viewed from a different
altitude.** A container's published port is still "port," a Kubernetes Service is still "how do
I reach the right destination via a stable address," Ingress is still "routing decisions," and
NetworkPolicy is still "which subnets/ports are allowed to reach which." You are not about to
learn a new mental model in ROOT 04 or ROOT 05 — you're about to see this SAME one applied one
layer up, repeatedly. That's why this module got extra weight: the investment compounds.
This module is complete. Continue to Module 4, where these ideas become real commands.
## Instructor Notes
**Discussion questions for a live classroom:** question 1 is worth collecting several answers
before and after — the change in precision is itself the evidence this module worked.
**Approximate timing:** 8-10 minutes live discussion; 5 minutes self-paced writing.
**Milestone note:** this is the "critical module" this course was built around — consider
confirming as a group that everyone can walk the full chain (host→interface→IP→subnet→gateway→
routing→DNS→port→TCP/UDP→application) from memory before moving on.