CentOS 7 + SELinux + PHP + Apache – cannot write/access log files

Apache logs keep saying that it can’t write to file due to permission where file permissions are properly setup,.

Unable to save log files in custom directory on Startup (Apache)

Encountered an issue trying to start Apache.  It was looking through the virtual hosts and trying to create access/error logs accordinly, but was receiving this error:

Permission denied: AH00091: httpd: could not open error log file /export/home/httplogs/websitename-error_log. AH00015: Unable to open logs

The directory structure has proper ownership and permissions, ex: directory is owned by nfsnobody:nfsnobody, file permission is 0644 and directory permission is 0755. It doesn’t make sense.

SELinux has rules/policies that applies to files/directories on top of the unix file permissions structure as extended attributes. When I run the command below on the default document root, I saw more information on the file/directory permissions.

# ls -Z /export/home/httplogs

Below is the output (some information removed):

drwxrwxrwx. nfsnobody nfsnobody unconfined_u:object_r:usr_t:s0   httplogs

And below is what I got for other normal directories:

lrwxrwxrwx. root root system_u:object_r:httpd_log_t:s0 /etc/httpd/logs

Therefore, we can conclude that we need to specify the proper SELinux permissions on directories in order to serve files on a custom directory and set another SELinux permissions to allow writing to file. Therefore, we can solve the original problem then.

Fixing the original problem

So we want to save our logs at /export/home/httplogs to enable writing to log files

First, set the proper ownership and permissions.

Set Ownership
# chown nfsnobody:nfsnobody -R /export/home/httplogs
 
SELinux to give perms for log dir, resursively
# chcon -t httpd_log_t /export/home/httplogs -R

httpd_log_t – for allowing Apache to write content to that path.

Side Notes:

Allow Read/Write recursively:
# semanage fcontext -a -t httpd_sys_rw_content_t “/var/www/html/sites/domain(/.*)?”

In output of sebool -a, make sure these are set:
# sebool -a
httpd_enable_cgi –> on
httpd_unified –> on
httpd_builtin_scripting –> on

To set a boolean, run setsebool [boolean] [0|1]
To make it permanent, pass the -P argument to setsebool

Also, look at SELinux and Apache Security Study by Dan Walsh here.