Serve a file SELinux will not let you serve

short · 30 min · Objective 3.3

Task

Reproduce the most common SELinux denial -- a web server refused a file whose permissions are perfect -- diagnose it from the audit log, and fix it the right way. Then see the mv-versus-cp trap that causes it, and a boolean that reverts because you forgot one flag.

Steps

  1. Create a page in the web root normally and confirm it serves: echo hi > /var/www/html/ok.html, then curl localhost/ok.html.
  2. Create a page in your home directory and MOVE it into the web root with mv. Confirm curl now returns 403 although the permissions match ok.html.
  3. Diagnose: ausearch -m avc -ts recent names the source and target contexts, and ausearch -m avc -ts recent | audit2why explains it. Compare the two files' contexts with ls -Z.
  4. Fix it with restorecon -v and confirm the page now serves. Explain why the copied file worked and the moved one did not.
  5. Confirm SELinux is the cause the diagnostic way: set setenforce 0, retry, see it work, then setenforce 1 immediately -- and state why leaving it at 0 is not a fix.
  6. Trigger a boolean case: configure httpd as a reverse proxy so it needs outbound network, watch it fail, and fix it with setsebool httpd_can_network_connect on. Reboot and confirm it reverted because you omitted -P; then set it with -P and confirm it holds.
  7. Serve content from a non-standard directory and use semanage fcontext plus restorecon to label it permanently.

Verify

curl -s -o /dev/null -w '%{http_code}\n' localhost/moved.html    # 200 after restorecon
ls -Z /var/www/html/moved.html | grep -q httpd_sys_content_t && echo "labelled correctly"
getsebool httpd_can_network_connect | grep -q ' on$' && echo "boolean on"
semanage boolean -l | grep httpd_can_network_connect | grep -q 'on.*on' && echo "and persistent"

Step 5 is the diagnostic and step 4 is the fix -- keep them separate in your head. setenforce 0 tells you SELinux is responsible; it does not resolve anything, and a machine left there has quietly lost the protection.

Notes

The mv-versus-cp behaviour is the trap worth carrying: a moved file keeps its old context, a copied file inherits the destination's. "The file looks identical but is not served" is almost always a page that was moved rather than copied into place.