index

Rails Logfiles and SELinux 2014-12-21

I am running a small web app using rails app on fedora. Fedora uses SELinux which caused me a lot of trouble when I first installed it, I had been using Ubuntu for hosting simple websites for a long while but decided to start fresh on the server and go for a new distro. SELinux caused me lot of trouble and confusion at first but I decided to embrace it and see it as an opportunity to learn good security practices.

The problem

Recently my nginx server would not start, the error logs said that nginx had trouble writing a logfile in my rails app (Permission Denied), yet the permissions looked alright. => SELinux!!!

For webservers that host multiple sites I think it is common practice to keep log files in a folder named logs for that site E.g. /var/www/mysite/logs/access.log. SELinux has preconfigured settings for sites with this type of structure.

But Rails projects have it as practice keep app logs in a folder named log. One easy solution is to make a folder in my Rails project just for nginx called logs and tell nginx to put it's files there. But then I would have two folders logs and log. That is messy!

So what I needed to do was add a SElinux context for logging to folders named log, not just logs.

Just to see if it would work I tried adding a the logging label to the log directory with the following command:

> sudo chcon -R -t httpd_log_t /var/www/myrailsapp/log

It worked! I could start nginx again. But as soon as I or the system for some reason restore the SELinux context with "restorecon" my changes will disappear.

Adding our own context

To make a persistent change we need to add our own context rule.

First I examined how the current contexts in SELinux look like.

> sudo semanage fcontext -l

...
/var/webmin(/.*)?           all files   system_u:object_r:var_log_t:s0 
/var/www(/.*)?              all files   system_u:object_r:httpd_sys_content_t:s0 
/var/www(/.*)?/logs(/.*)?   all files   system_u:object_r:httpd_log_t:s0 # << Interesting!
...

The command will list all of the current context's that SELinux uses. After a bit of searching I found the context which is almost what I want. Using this regex string as an example and the program semanage again. I can now add a new context that looks for the log folder (note: not logs).

> sudo semanage fcontext -a -t httpd_log_t "/var/www(/.*)?/log(/.*)?"

Now SELinux will label both /var/www/sitename/log/ and /var/www/sitename/logs/ as being writable for our webserver.

So running

> sudo restorecon -Rv /var/www/

will label all of the files in www according to our contexts.

And now my nginx server starts!

Resources: