9

Our company has a webserver with CentOS 7 and our customers manage their websites through FTP (vsftpd). SELinux is in enforcing mode.

The issue is that data created/uploadad through VSFTPD is not inheriting the appropriate SELinux context. Let me explain.

For example, for WordPress sites the server has, out of the box, already a couple of rules that can be seen using semanage fcontext -l |grep '/var/www', which are:

/var/www/html(/.*)?/uploads(/.*)?                  all files          system_u:object_r:httpd_sys_rw_content_t:s0
/var/www/html(/.*)?/wp-content(/.*)?               all files          system_u:object_r:httpd_sys_rw_content_t:s0

So, when I copy a WordPress site let's say from another server into a directory in /var/www/html/ by SSH, the folders wp-content/ and wp-content/uploads/ have the proper httpd_sys_rw_content_t security context. HOWEVER, when those folders are created through FTP, the context they get is httpd_sys_content_t (no rw). This means that the sites our customers upload to the server can't write into those directories even if they give write permissions to the apache user/group, so the WordPress admin doesn't work. So, when they upload a site they have to request support from us to fix this, which is a waste of time for all involved.

Let's say the customer uploaded their site into httpdocs, if through SSH I do mv httpdocs/ httpdocs.2/ && cp -pr httpdocs.2/ httpdocs/ && rm httpdocs.2/ -fr the issue is solved, so there's nothing wrong with the data.

I can also do restorecon -Rv httpdocs/ to have the issue fixed.

So, the question is: How can I have the directories created/uploaded through VSFTPD inherit the proper SELinux contexts just like they are inherited when the directories are created/uploaded through SSH?

2
  • For security, it's a bad idea to support FTP at all. Consider getting rid of it and instructing customers on how to configure their file transfer clients to use SFTP instead...which will also get rid of this problem. Apr 1, 2016 at 22:21
  • Thanks Michael. I agree with you but in our case we don't use "ftp.domain.com" for our customers and also we don't expose the server's public IP address (server is behind NginX proxy), so FTP security is not an issue for us. Only those who we send the FTP address to can even find the server's IP address to connect through FTP. Apr 1, 2016 at 22:37

1 Answer 1

7

There is a difference between default labelling that occurs at runtime and the regular expression based post-labelling policy that applies on the server.

What you are noting here:

/var/www/html(/.*)?/uploads(/.*)?                  all files          system_u:object_r:httpd_sys_rw_content_t:s0
/var/www/html(/.*)?/wp-content(/.*)?               all files         system_u:object_r:httpd_sys_rw_content_t:s0

Is the post labelling policy.

What you discuss in your problem actually relates to the runtime policy.

When a entry is created in a directory using SELinux the rules governing what label the file or directory ends up being are not dictated by the regular expressions you quote but other rules as follows (I believe this is the correct order but might have missed something).

  1. There is a explicit named type_transition rule.
  2. There is a explicit non-named type_transition rule.
  3. Inherit the same context as the parent directory.
  4. Apply the default_context.

So, when I copy a WordPress site let's say from another server into a directory in /var/www/html/ by SSH, the folders wp-content/ and wp-content/uploads/ have the proper httpd_sys_rw_content_t security context.

So, yes it does do this, but not for the reason you think it does. Certainly not because of the post labelling policy.

This occurs because a specific named type_transition rule exists which provides this behaviour.

$ sesearch -C -T -s unconfined_t -t httpd_sys_content_t -c dir

Found 4 named file transition filename_trans:
type_transition unconfined_t httpd_sys_content_t : dir httpd_sys_rw_content_t "wp-content"; 
type_transition unconfined_t httpd_sys_content_t : dir httpd_sys_rw_content_t "smarty"; 
type_transition unconfined_t httpd_sys_content_t : dir httpd_sys_rw_content_t "uploads"; 
type_transition unconfined_t httpd_sys_content_t : dir httpd_sys_rw_content_t "upgrade"; 

This is basically saying.

  • If you are unconfined_t and
  • If you are performing an action in the target type httpd_sys_content_t and
  • If the class of the new entry is a directory and
  • If the name of the new entry is "uploads" then
  • The new type is httpd_sys_rw_content_t

The reason this works for SSHD is because after you have logged in you are being given the source context of unconfined_t for which this rule applies.

This does not work for the FTP service because the source context of this service is most likely ftpd_t which has no matching rule.

As such, you'd need to modify the policy to alter the behaviour of SELinux to also honour the named file rulings you see in the other entries for FTP too.

In Fedora 23 at least, there exists a interface to permit this, a policy module like this would do it.

policy_module(local_ftpd, 7.2.0)

require {
  type ftpd_t;
}

apache_filetrans_named_content(ftpd_t)

You can load this by ensuring that the selinux-policy-devel package is installed and running make -f /usr/share/selinux/devel/Makefile load.

1
  • 1
    Hi Matthew, that did the trick!! Thanks for your help as I was going crazy with this. I was not sure what do with the policy module you wrote as I had never customized SELinux, so I googled a bit and the following is what I did: I created the file local_ftpd.te with your policy module, then I did make -f /usr/share/selinux/devel/Makefile local_ftpd.pp and then semodule -i local_ftpd.pp. Is this OK? Now the files created through FTP inherit the desired contexts. Thanks again! Apr 3, 2016 at 15:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .