Skip to content

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 history turns 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 dnf and use dnf history to inspect/undo.
  • Write, enable, and inspect a systemd service.
  • Read an SELinux denial and fix it (context or boolean), not just disable SELinux.

Do it with Claude

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 coursefocus §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 enablestart 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 history before I install anything."

Common gotchas

  • Running setenforce 0 to make an SELinux denial go away. Fix: that disables enforcement system-wide until reboot — find the actual denial with ausearch/sealert and 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 using dnf remove. Fix: dnf tracks the transaction (and its dependency graph) in history; a raw rpm removal doesn't, so dnf history undo can'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 — use systemctl edit <unit> to write a drop-in override instead, which survives updates.
  • Assuming a journalctl permission 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 run a UBI image, or a Rocky/Alma VM).

  1. Install a package with dnf; then show its entry in dnf history.
  2. Write a simple systemd unit for a long-running command: daemon-reload, then enable --now, and check systemctl status + journalctl.
  3. 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 with ausearch/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.

  1. Walkthrough: Explain your systemd unit fields and what enable vs start did.
  2. Alternative: SELinux context vs boolean — which did you use and why? When is each right?
  3. Failure & debug: A service won't start and journalctl shows a permission error on a file that has correct Unix perms. Where do you look next, and why?
  4. 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 history turns 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 manual rpm -e or a plain dnf remove of just the one package.
  • A systemd unit needs both halves: enable wires 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; use systemctl 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/sealert are how you find the actual denial behind an SELinux problem — read the denial before guessing at a context or boolean fix.
  • A journalctl permission 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: