Linux (RHEL)¶
Tool · prereq 03 (Containers/Podman) · ~1.5–2 days (4 submodules: LVM/storage, networking/firewall, systemd/journald, SELinux/users)
Every container from module 03 (Containers) has to run somewhere — a real Linux host with its own package manager,
service manager, and security model to operate correctly, not just launch containers on. RHEL is the
enterprise default here: dnf/RPM package management with a rewindable transaction history, systemd
owning every long-running service's boot-time lifecycle, and SELinux enforcing by default instead of
an optional layer you can safely ignore. This module is about operating that host properly — including
resisting the temptation to setenforce 0 and disable the one thing protecting it.
TL;DR — in 30 seconds:
dnf historyturns every package change into an undoable transaction —dnf history undo <id>reverts one, no need to remember what was installed before.- A systemd unit needs both
enable(wire it into the boot target, for next boot) and--now(start it right now) — running only one leaves the other half undone. - An SELinux denial is fixed by giving the file the right context or flipping the right boolean —
never by
setenforce 0, which turns off the whole protection instead of fixing the one path.
Learning objectives¶
By the end, the junior can:
- Manage packages with
dnfand usednf historyto inspect/undo. - Write, enable, and inspect a systemd service.
- Read an SELinux denial and fix it (context or boolean), not just disable SELinux.
Pair, Do and Prove run in Claude Code, with the onboarding-tutor skill. Click a button to copy the exact prompt, then paste it into Claude Code in this repo.
1. Learn · acquire the concept¶
Read: the rhel course — focus §5 (dnf/RPM), §7 (systemd), §8 (SELinux — the big one), §9 (firewalld). Skip for now: §14 (CIS/STIG/OpenSCAP), §15 (image mode) — later, on real fleets. Glossary (beat 5): the module’s Anki deck
Check yourself — you installed a package with dnf and want to undo just that one transaction. What do you run, and why is that safer than manually removing the package?
dnf history undo <id> — because it reverses the exact set of changes that transaction made (including
any dependencies it pulled in), instead of a manual dnf remove that only removes the one package you
name and can leave orphaned dependencies behind.
Check yourself — a systemd unit runs fine when you systemctl start it by hand, but doesn't come back after a reboot. What's missing?
systemctl enable — start only starts it right now; enable is the separate step that wires the
unit into its target so it starts automatically at boot. Running one without the other leaves the unit
either running-but-not-persistent, or persistent-but-not-running (which --now fixes in one command).
2. Pair · passive → active¶
Drive the onboarding-tutor skill:
- "Explain what SELinux is actually doing when it denies something."
- "3-line mental model of a systemd unit's lifecycle."
- "Quiz me on
dnf historybefore I install anything."
Common gotchas
- Running
setenforce 0to make an SELinux denial go away. Fix: that disables enforcement system-wide until reboot — find the actual denial withausearch/sealertand fix the context or boolean instead; "disabled and it worked" is a fail condition on the gate for this module. - Manually
rpm -e-ing a package instead of usingdnf remove. Fix:dnftracks the transaction (and its dependency graph) in history; a rawrpmremoval doesn't, sodnf history undocan't help you recover from it. - Editing a package-managed unit file directly under
/usr/lib/systemd/system/. Fix: the next package update overwrites it — usesystemctl edit <unit>to write a drop-in override instead, which survives updates. - Assuming a
journalctlpermission error means a Unix file-permission problem. Fix: check for an SELinux denial first (ausearch -m avc -ts recent) — a process can have correct Unix perms and still be denied by policy.
Done when: you can explain why "just setenforce 0" is the wrong fix, unprompted.
3. Do · produce an artifact¶
Exercise — operate a RHEL(-like) host:
Use a RHEL/UBI container or a VM (e.g.
podman runa UBI image, or a Rocky/Alma VM).
- Install a package with
dnf; then show its entry indnf history. - Write a simple systemd unit for a long-running command:
daemon-reload, thenenable --now, and checksystemctl status+journalctl. - Trigger an SELinux denial (e.g. serve a file from a non-standard path) and fix it the right way — set the correct context (
restorecon/semanage fcontext) or the right boolean. Confirm withausearch/sealert.
Done when: the service runs, and the SELinux denial is resolved without disabling SELinux.
4. Prove · understanding gate¶
Mandatory. Pass bar in the Socratic gate.
- Walkthrough: Explain your systemd unit fields and what
enablevsstartdid. - Alternative: SELinux context vs boolean — which did you use and why? When is each right?
- Failure & debug: A service won't start and
journalctlshows a permission error on a file that has correct Unix perms. Where do you look next, and why? - Provenance: Which commands did the agent give you? How did you verify the SELinux fix actually worked (not just that the error stopped)?
Pass bar: you can defend the SELinux fix and read a systemd unit plus its journal. "Disabled SELinux and it worked" = fail.
5. Retain · fight forgetting¶
Study the module deck SE Onboarding::09 RHEL — its 15 theme subdecks let you drill one area at a time. It syncs to your Anki automatically on pull (anki-sync).
Done when: you can recall, from the deck, dnf/history, the systemd unit lifecycle, SELinux context vs boolean, and firewalld.
Key takeaways¶
dnf historyturns every package change into an undoable transaction —dnf history undo <id>reverses the whole transaction (including any dependencies it pulled in), which is why it's safer than a manualrpm -eor a plaindnf removeof just the one package.- A systemd unit needs both halves:
enablewires it into the boot target for next boot,start(or--now) runs it right now — doing only one leaves it either running-but-not-persistent or persistent-but-not-running. - Never edit a package-managed unit file directly under
/usr/lib/systemd/system/— the next package update overwrites it; usesystemctl edit <unit>to write a drop-in override that survives updates. - An SELinux denial is fixed by giving the file the right context or flipping the right boolean —
never by
setenforce 0, which disables enforcement system-wide instead of fixing the one path. ausearch/sealertare how you find the actual denial behind an SELinux problem — read the denial before guessing at a context or boolean fix.- A
journalctlpermission error can appear even when Unix file permissions are correct — check for an SELinux denial first, since a process can pass Unix perms and still be blocked by policy.
Go deeper — curated resources¶
Hand-picked external material to take this topic further — the best books, courses, talks, and writing. Cost is tagged Free, Free online (full text/course free on the web), or Paid.
- Book · The Linux Command Line — William Shotts. The best free introduction to the shell — 500+ pages, from first command to scripting, as a free PDF. Free online.
- Interactive · Linux Journey — Cindy Quach / LabEx. Bite-size Linux from zero with in-browser labs — no setup, no signup. Free.
- Book · How Linux Works, 3rd ed. — Brian Ward (No Starch Press). What's really happening under the shell: processes, the kernel, filesystems, boot, networking. Paid.
- Blog · wizardzines — Julia Evans. Brilliant illustrated deep-dives on the command line, systemd, networking and more — many posts and zines free, others paid. Free.
- Docs · Red Hat Enterprise Linux documentation — Red Hat. The distro reference — package management, systemd, SELinux, firewalld, storage. Free.
Gate log (mentor fills on pass)¶
- Date passed: / Passed by: / checked by: / Weak spots: