I'm trying to understand why Apache is still able to serve a PHP file after I set the permissions 000 and give the file root ownership.
If I create a PHP file owned by the webserver with permissions 644, its served correctly. If I then alter the permissions to 000 and change the ownership to root, the file is still served, but I don't think it should be!
If I then restart Apache the file is not served. I get a 500 and the error log grumbles about not being able to open a file, which is exactly the behaviour I'd expect.
After the restart, when the file is not being served, if I change the ownership back to the webserver and permissions back to 644, the file is served again, without requiring a restart of apache.
This behaviour is only true for PHP files. HTML files behave as I'd expect, as soon as you remove the permissions, the files is not served.
It was suggested to me that Apache might be maintaining a file handle on the PHP file and that it was not seeing the permission changes until it restarted. I've tried using lsof on the file, but didn't see any open file descriptors.
I also tried and experiment where I started with webserver ownership and 644 permissions and checked the file could be served. Then I renamed the file, change the permissions to 000 and ownership to root and then moved the file back. After this, the file was still served up by Apache.
Can anyone shed any light on what's going on here?
Most likely what's happening is you have opcache running. PHP compiles itself at runtime. To save overhead, PHP 5.5 or later has Opcache, which saves that compile step. So Apache is probably caching the file. Apache would then store the cache file with its own permissions. Apache might also be caching it in memory as well. When you restart Apache it has to go back to the base PHP file, which it no longer has permissions to.