learninfra · Linux · Networking · Kubernetes · System Design · AI Infrastructure · Exam blueprints · Drills

SELinux & AppArmor

A page with mode 644 still returns 403, and root is still told no. Learn the second lock on every door: read the denial, fix the label or the profile, and never switch the lock off.

An interactive Linux lesson: 25 steps, about 35 minutes, on a live simulation in your browser.

This lesson runs on a different machine from the rest of the track. web01 is a Rocky Linux 9 host, the free rebuild of Red Hat Enterprise Linux, and on that family SELinux is switched on out of the box. getenforce answers Enforcing: the kernel refuses whatever the security policy does not allow, and writes each refusal to a log.

Install nginx with dnf, the Red Hat package manager. Unlike apt on Ubuntu, installing starts nothing: on RHEL a package's service arrives disabled and stopped, so systemctl enable --now nginx starts it and keeps it on at boot. Then ask it for the default page. You get 200. Nothing about SELinux is visible yet.

What you will learn

  1. Two locks on every door

    • A web server on a RHEL-like host: On a RHEL-family host SELinux is on by default, and it watches every system service, quietly, until one of them steps outside its policy.
    • Copy one page, move the other
    • ls -l says yes: Access needs two yeses: the rwx bits first, then the security policy. A 644 file can still be refused by the second lock.
    • Break it: when DAC says no first: No denial in the audit log means SELinux never said no. Check the rwx bits before you blame the policy.
  2. Labels, not paths

    • Every process and file has a label: SELinux decides by type: may this domain do this to that type? The type is stored on the inode and travels with mv.
    • Root in the web server's shoes: MAC does not care about uid 0. A compromised service is held to its domain's rules even when it runs as root.
  3. Reading a denial

    • Find the denial: An AVC reads as a sentence: domain scontext was denied { permission } on an object of type tcontext, class tclass.
    • Ask why: audit2why says what would allow the access. You still decide whether the access, or the label, is what is wrong.
    • Pick the fix: When the denied type looks wrong for where the file lives, fix the label with restorecon. Never widen the policy to fit a mislabelled file.
  4. A new home for the site

    • Break it: serve the site from /web: The policy holds a table from path patterns to types. A path no rule matches gets default_t, and confined services cannot read it.
    • Write the rule: semanage fcontext changes what the label should be. restorecon changes what it is. You need both.
    • Drill: apply the rule
  5. Ports and booleans

    • Break it: move nginx to port 8081: Ports carry types like files do. A confined service may bind only ports whose type its domain allows.
    • Drill: label the port
    • nginx as a reverse proxy
    • Flip the boolean: A boolean is a policy-approved switch for a common need. Without -P it lasts until the next boot.
  6. What survives a reboot

    • The Sunday kernel update: setsebool without -P is a test. Anything you want after the next boot needs -P, or semanage, which always persists.
    • Break it: the setenforce 0 fix: Permissive mode is a diagnostic: it tells you SELinux was the cause. It is never the fix.
    • Drill: fix it for good
    • The config file is for the next boot: setenforce changes now; /etc/selinux/config changes the next boot. Check both with sestatus.
  7. Ubuntu's version: AppArmor

    • Ubuntu: a profile is a list of paths: AppArmor confines a program by its path, with rules about paths. A newly loaded profile applies from the program's next start.
    • The same 403, found by path: AppArmor denials are in the kernel log with the path in name=. The fix is a rule in the profile, then apparmor_parser -r.
    • Let AppArmor write the profile: Complain mode is AppArmor's permissive: learn with it, then enforce. Never leave a profile in complain mode as the fix.
  8. Recap & playground

    • Cheat sheet
    • Playground: web01 is yours