Serve a file SELinux will not let you serve
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
- Create a page in the web root normally and confirm it serves:
echo hi > /var/www/html/ok.html, thencurl localhost/ok.html. - Create a page in your home directory and MOVE it into the web root with
mv. Confirmcurlnow returns 403 although the permissions match ok.html. - Diagnose:
ausearch -m avc -ts recentnames the source and target contexts, andausearch -m avc -ts recent | audit2whyexplains it. Compare the two files' contexts withls -Z. - Fix it with
restorecon -vand confirm the page now serves. Explain why the copied file worked and the moved one did not. - Confirm SELinux is the cause the diagnostic way: set
setenforce 0, retry, see it work, thensetenforce 1immediately -- and state why leaving it at 0 is not a fix. - 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-Pand confirm it holds. - Serve content from a non-standard directory and use
semanage fcontextplusrestoreconto 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.