SELinux is great for adding another layer of protection to your systems, but sometimes it can be a bit of a pain to work out why you get a particular effect from specific software and not from others where they look like they should be doing the same thing.
This post is because I have recently hit exactly that strange behaviour, in the following set of circumstances:
- Apache as web-server, serving
public_html
directory contents from user homedirs - Samba to share those homedirs
- Editing (or creating) HTML files with particular editors causes files in the
public_html
dir to get the wrong SELinux context
For example, lets create two files in our public_html
directory:
$ touch ~/public_html/foo.html ~/public_html/bar.html
If we use the -Z
option to ls
then we can see the context of the files:
$ ls -Z public_html/ -rw-r--r--. user group unconfined_u:object_r:httpd_user_content_t:s0 foo.html -rw-r--r--. user group unconfined_u:object_r:httpd_user_content_t:s0 bar.html
The context of httpd_user_content_t
is correct for public_html directories, and is set up by default to allow the web-server processes to read these files. This all works as expected.
Now lets edit foo.html
over samba from TextEdit on OSX and look at the context again:
$ ls -Z public_html/ -rw-r--r--. user group system_u:object_r:user_home_dir_t:s0 foo.html -rw-r--r--. user group unconfined_u:object_r:httpd_user_content_t:s0 bar.html
Now foo.html
has the wrong context (user_home_dir_t
) for the public_html
directory and isn’t readable by the web-server, breaking serving of this personal page. Argh!
The reason for this is visible in the samba logs if we crank up the log level
setting from the default of 1 to 4, when we see entries like this:
[2016/08/19 11:15:07.619877, 3] ../source3/smbd/vfs.c:1322(check_reduced_name) check_reduced_name: .TemporaryItems/folders.502/TemporaryItems/(A Document Being Saved By TextEdit)/osx-blah9.html reduced to /home/user/.TemporaryItems/folders.502/TemporaryItems/(A Document Being Saved By TextEdit)/foo.html
So TextEdit is really saving files to ~/.TemporaryItems/...
and then moving them into place when you say to save them!
This is nice in terms of it saving changes as you make them, but breaks the file context for SELinux!
Options for workarounds include:
- Disable SELinux – No
- Tell the editor in question not to move files into place – This doesn’t appear to be an option with TextEdit on OSX
- Change the context of files after they are moved into place – I can’t currently think of a good way to do this, unfortunately
- Allow the web-server access to files with context
user_home_dir_t
– This is shown below - Something I haven’t thought of yet – Please suggest alternative methods via the comments below 🙂
Creating a policy to grant the web-server access to these incorrectly-labelled files
The following set of commands can be used to display a policy created from the audit log, create a binary (loadable) module of it and then load that module.
This will just display the text version of the policy :
# cat /var/log/audit/audit.log | grep httpd | audit2allow -m httpd-allow-userhomedir
If you’re happy with that (i.e. it doesn’t contain superfluous rules) then run this to create a binary policy and then load it:
# cat /var/log/audit/audit.log | grep httpd | audit2allow -M httpd-allow-userhomedir # semodule -i httpd-allow-userhomedir.pp
..but the first time you run this it will only have allowed the httpd
process to have got so far in serving the files. You’ll need to either temporarily set SELinux to “permissive” mode, or to go around this loop a few times to get the web-server to get far enough that your policy has all the required permissions in it.
I ended up with this policy :
module httpd-allow-userhomedir 1.0; require { type httpd_t; type user_home_dir_t; class file { read getattr open }; } #============= httpd_t ============== allow httpd_t user_home_dir_t:file { read getattr open };
..and then everything worked as expected, hooray! 🙂
Adding this to a Puppet manifest is left as an exercise for the reader 🙂
Hint: Look for selinux::module
Additional notes:
- The boolean
httpd_enable_homedirs
only seems to affect allowing thepublic_html
dir to be served, not the rest of the user’s homedir. - This probably isn’t the most secure way of achieving the desired effect. Please tell me if I’m doing it wrong 🙂