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:
+104
@@ -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.
|
||||
+56
@@ -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.
|
||||
+45
@@ -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).
|
||||
+33
@@ -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.
|
||||
+30
@@ -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.
|
||||
Reference in New Issue
Block a user