Looks like my old faithful LAMP directory structure has come unstuck with SELinux. I prefer everything in the same place. CentOS 6.6 Apache 2.2.15 MySQL 6.5


If I do this then Apache works fine but mysql will not start.

chcon -R -t httpd_sys_content_t /DATA/
chcon -R -t mysqld_db_t  /DATA/mysql
chcon -R -t httpd_sys_content_t /DATA/httpdocs

If I do this then mysql will start but Apache will not start.

chcon -R -t mysqld_db_t /DATA
chcon -R -t mysqld_db_t  /DATA/mysql
chcon -R -t httpd_sys_content_t /DATA/httpdocs

I know this is related to the label I'm attaching to the root /DATA folder and they can not have two?

Yes all my problems go away if I disable SELinux but it is required for this project. The folders are chowned and chmodded fine.

For the mysql case the error is

2015-04-24 14:17:56 3391 [Warning] Can't create test file /DATA/mysql/WIK1.lower-test
2015-04-24 14:17:56 3391 [Warning] Can't create test file /DATA/mysql/WIK1.lower-test
/usr/sbin/mysqld: Can't change dir to '/DATA/mysql/' (Errcode: 13 - Permission denied)
2015-04-24 14:17:56 3391 [ERROR] Aborting

For the Apache case the error is.

Starting httpd: Warning: DocumentRoot [/DATA/httpdocs/] does not exist

I have tried adding this to /etc/selinux/targeted/contexts/files/file_contexts.local

/DATA/mysql(/.*)?       system_u:object_r:mysql_db_t:s0

But it does nothing.

Can anyone help me tame SELinux or is my only option a separate folder for mysql?


Thanks, I tried this (also posting answer cause I could not format text in comment)

    cd ~
    setenforce Permissive
    service mysqld restart
    service httpd restart
    # interact with web app make it do things like file writes, db access, network and so on.
    grep 'mysqld_t\|httpd_sys_content_t' /var/log/audit/audit.log | audit2allow -M postgreylocal 
    semodule -i postgreylocal.pp
    # check it exists...
    semodule -l
    chcon -R -t postgreylocal /DATA
    chcon -R -t postgreylocal /DATA/
setenforce Enforce

mysql still does not go. I think I do not know how to apply the policy postgreylocal? In the log I have - /var/log/audit/audit.log

type=AVC msg=audit(1429892483.654:3036): avc:  denied  { read } for  pid=7089 comm="mysqld" name="DATA" dev=dm-3 ino=13 scontext=unconfined_u:system_r:mysqld_t:s0 tcontext=system_u:object_r:unlabeled_t:s0 tclass=lnk_file
type=SYSCALL msg=audit(1429892483.654:3036): arch=c000003e syscall=80 success=no exit=-13 a0=132b500 a1=10 a2=41000 a3=7fff4d3af8f0 items=1 ppid=6882 pid=7089 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=4294967295 comm="mysqld" exe="/usr/sbin/mysqld" subj=unconfined_u:system_r:mysqld_t:s0 key=(null)
type=CWD msg=audit(1429892483.654:3036):  cwd="/"
type=PATH msg=audit(1429892483.654:3036): item=0 name="/DATA/mysql/" nametype=UNKNOWN

If I chcon with SE Enforcing I get the following....

# chcon -R -t postgreylocal /DATA
chcon: failed to change context of `/DATA' to `system_u:object_r:postgreylocal:s0': Invalid argument
  • 1
    Your preference for everything in the same place is what needs to change. Put everything back in its default locations. – Michael Hampton Apr 24 '15 at 15:25

You can not attach two different security labels to the same directories. So, you had to select a single label and let the other process to read/write the files with that label.

Problem is that doing that you are effectively granting the second process read/write access to the files owned by the first process, which is exactly what you don't want to do.

Two solutions exists:

  1. you can mark all as httpd_sys_content_t and let mysql access files with that label. While this is remain somewhat insecure (mysql process can read/write http files), mysqld is usually a trusted process and so it is way better than the other way around (let http do access mysql files).
  2. you con assign to /DATA/ a different, shared label and modify your selinux policy in a way that grant permission to both httpd and mysqld to that shared label. Under /DATA/, leave the two directory types with their own lables (eg: /DATA/mysql with mysqld_db_t and /DATA/httpdocs with httpd_sys_content_t)

In both cases, for an easy policy edit, set selinux to permissive mode, the use the audit2allow utility to parse your /var/log/audit/audit.log file. Here you can find more informations.

  • Please read the page I linked in my answer. It has anything you need to proceed. – shodanshok Apr 24 '15 at 8:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.