I'm building a log analysis server that's running a big MySQL database. Logs are imported in the database and then are processed for statistical analysis and stuff like that. The system is running CentOS5 64bit (almost identical to RHEL 5). I'm keeping the database on a separate RAID array, for obvious reasons. So I mounted that array as /db and then moved the MySQL datadir via /etc/my.cnf:
datadir=/db/mysql tmpdir=/db/tmp/ basedir=/db
I made sure to move /var/lib/mysql to /db/mysql in such a way as to preserve all the attributes, including SELinux. But, of course, MySQL fails to run:
type=AVC msg=audit(1177025497.442:254): avc: denied { search } for pid=7453 comm="mysqld" name="/" dev=sdb1 ino=2 scontext=root:system_r:mysqld_t:s0 tcontext=system_u:object_r:file_t:s0 tclass=dir type=SYSCALL msg=audit(1177025497.442:254): arch=c000003e syscall=87 success=no exit=-13 a0=7fff6ee35150 a1=0 a2=0 a3=3 items=0 ppid=7417 pid=7453 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) comm="mysqld" exe="/usr/libexec/mysqld" subj=root:system_r:mysqld_t:s0 key=(null) type=AVC msg=audit(1177025497.442:255): avc: denied { search } for pid=7453 comm="mysqld" name="/" dev=sdb1 ino=2 scontext=root:system_r:mysqld_t:s0 tcontext=system_u:object_r:file_t:s0 tclass=dir type=SYSCALL msg=audit(1177025497.442:255): arch=c000003e syscall=2 success=no exit=-13 a0=7fff6ee35350 a1=42 a2=1b6 a3=3 items=0 ppid=7417 pid=7453 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) comm="mysqld" exe="/usr/libexec/mysqld" subj=root:system_r:mysqld_t:s0 key=(null) type=AVC msg=audit(1177025497.442:256): avc: denied { search } for pid=7453 comm="mysqld" name="/" dev=sdb1 ino=2 scontext=root:system_r:mysqld_t:s0 tcontext=system_u:object_r:file_t:s0 tclass=dir
Now, I can definitely customize the policy, I guess the first rule would be like this and I'll keep tweaking it until it works:
allow mysqld_t file_t:dir search;
But this seems like a hack. I mean, moving the datadir to a different location is probably something that MySQL admins do all the time when building big servers (or maybe even not that big).
I wish there was a SELinux variable, or a place where I can tell SELinux that the datadir has moved, that XYZ is the new location, and just let me use it (provided that the SELinux attributes are OK within the MySQL datadir per se).
Same thing happens with many servers when moving their default data locations. Examples that I had issues with: Cyrus-IMAPd, Squid. Sure, one can customize the policy the "normal", step-by-step way, but that doesn't seem the right thing.
I'm strictly speaking from the sysadmin's perspective. It just looks like a natural thing to be able to customize SELinux via a simple variable or something, and make it "aware" (sort of) that, hey, I only moved the data dir to a new location, stop panicking about that.
Thanks,
These are the selinux labeling rules for mysql:
# grep mysql /etc/selinux/targeted/contexts/files/file_contexts /etc/mysql(/.*)? system_u:object_r:mysqld_etc_t:s0 /var/log/mysql.* -- system_u:object_r:mysqld_log_t:s0 /var/lib/mysql(/.*)? system_u:object_r:mysqld_db_t:s0 /var/run/mysqld(/.*)? system_u:object_r:mysqld_var_run_t:s0 /usr/sbin/mysqld(-max)? -- system_u:object_r:mysqld_exec_t:s0 /etc/my.cnf -- system_u:object_r:mysqld_etc_t:s0 /usr/libexec/mysqld -- system_u:object_r:mysqld_exec_t:s0 /var/lib/mysql/mysql.sock -s system_u:object_r:mysqld_var_run_t:s0
It seems you're moving /var/lib/mysql to /db/mysql, and the following new labeling rule should set the right labels for the db:
# Add new labeling rule: /usr/sbin/semanage fcontext -a -t mysqld_db_t "/db/mysql(/.*)?" # Restore labels based on labeling rules: restorecon -R /db/mysql
But, I'm quite uncertain on how to map your tmpdir and basedir. What where the original location of these ? Once you find these, it will likely be easy to create similar new labeling rules for these, and your new database location should be OK.
On the other hand.. I would have just mounted the storage array as /var/lib/mysql, run "restorecon -R /var/lib/mysql" and not have needed to change much in either selinux or mysql startup for getting it working.
-jf
(re-sending reply to mailing list, Reply-To is broken for this list)
Jan-Frode Myklebust wrote:
It seems you're moving /var/lib/mysql to /db/mysql
true
I've found that if I mount /db like this, SELinux does not complain anymore:
mount -o defcontext=system_u:object_r:var_t /db
The new problem is, if I put defcontext=... in /etc/fstab, for some reason /db errors out when the system boots up and tries to mount it, so /db ends up not mounted.
But, I'm quite uncertain on how to map your tmpdir and basedir.
tmpdir=/db/tmp/ basedir=/db
What where the original location of these ?
tmpdir=/tmp/ basedir=/var/lib
Jan-Frode Myklebust wrote:
It seems you're moving /var/lib/mysql to /db/mysql, and the following new labeling rule should set the right labels for the db:
# Add new labeling rule: /usr/sbin/semanage fcontext -a -t mysqld_db_t "/db/mysql(/.*)?"
Which files are modified by this command, and will the changes persist after updates will be released (and applied) for the selinux RPMs?
But, I'm quite uncertain on how to map your tmpdir and basedir. What
Yeah, I'd like to keep tmpdir (originally on /tmp) together with the datadir, so I'd like to move it, say, to /db/tmp
I guess I should run semanage for /db/tmp as well?
basedir will probably be /db (originally /var/lib) so I'm not sure what to do. I guess I could actually move /var/lib/mysql to /db/lib/mysql and change basedir from /var/lib to /db/lib - this might make it simpler to adapt existing labeling rules to the customized system?
By the way, I figured out the fstab thing. The correct way to do it is:
# grep /db /etc/fstab LABEL=/db /db ext3 defcontext=system_u:object_r:var_t:s0 1 2
The trailing :s0 appears to be important in this context. But after the system boots up, I can manually do a "mount /db" even if :s0 is not appended and it works.
On 2007-04-21, Florin Andrei florin@andrei.myip.org wrote:
# Add new labeling rule: /usr/sbin/semanage fcontext -a -t mysqld_db_t "/db/mysql(/.*)?"
Which files are modified by this command, and will the changes persist after updates will be released (and applied) for the selinux RPMs?
The new rule is added to /etc/selinux/targeted/contexts/files/file_contexts.local and will persist after upgrades of mysql/selinux.
I guess I should run semanage for /db/tmp as well?
I think you will get away with simply labelling /db/ as mysqld_db_t:
/usr/sbin/semanage fcontext -a -t mysqld_db_t "/db(/.*)?" restorecon -R /db
# grep /db /etc/fstab LABEL=/db /db ext3 defcontext=system_u:object_r:var_t:s0 1 2
That doesn't look right to me.. I think you should label it mysqld_db_t, not var_t. mysqld_db_t should mean only mysql will have access to these files and directories, while var_t is much more open. Lots of apps probably have access to var_t.
But -- you should probably do either mount option, or "semanage fcontext". No need to do both.
-jf
Jan-Frode Myklebust wrote:
On 2007-04-21, Florin Andrei florin@andrei.myip.org wrote:
# grep /db /etc/fstab LABEL=/db /db ext3 defcontext=system_u:object_r:var_t:s0 1 2
That doesn't look right to me.. I think you should label it mysqld_db_t, not var_t. mysqld_db_t should mean only mysql will have access to these files and directories, while var_t is much more open. Lots of apps probably have access to var_t.
Well, I was just trying to replicate the situation in /var I thought - the least amount of changes, the least amount of headaches.
But I'll try both and see what happens.
But -- you should probably do either mount option, or "semanage fcontext". No need to do both.
Got it.
Jan-Frode Myklebust wrote:
On 2007-04-21, Florin Andrei florin@andrei.myip.org wrote:
# grep /db /etc/fstab LABEL=/db /db ext3 defcontext=system_u:object_r:var_t:s0 1 2
That doesn't look right to me.. I think you should label it mysqld_db_t, not var_t. mysqld_db_t should mean only mysql will have access to these files and directories, while var_t is much more open. Lots of apps probably have access to var_t.
# grep /db /etc/fstab LABEL=/db /db ext3 defcontext=system_u:object_r:mysql_db_t:s0 1 2
# tail -n 1 /var/log/messages Apr 22 13:38:34 reports kernel: SELinux: security_context_to_sid(system_u:object_r:mysql_db_t:s0) failed for (dev sdb1, type ext3) errno=-22
On 2007-04-22, Florin Andrei florin@andrei.myip.org wrote:
# grep /db /etc/fstab LABEL=/db /db ext3 defcontext=system_u:object_r:mysql_db_t:s0 1 2
# tail -n 1 /var/log/messages Apr 22 13:38:34 reports kernel: SELinux: security_context_to_sid(system_u:object_r:mysql_db_t:s0) failed for (dev sdb1, type ext3) errno=-22
What about:
LABEL=/db /db ext3 fcontext=system_u:object_r:mysql_db_t:s0 1 2 or LABEL=/db /db ext3 fcontext=system_u:object_r:mysql_db_t 1 2
?
-jf
Jan-Frode Myklebust wrote:
What about:
LABEL=/db /db ext3 fcontext=system_u:object_r:mysql_db_t:s0 1 2 or LABEL=/db /db ext3 fcontext=system_u:object_r:mysql_db_t 1 2
?
You mean "fscontext"?
I can't test it now, as the system is busy swallowing a huge pile of logs, but I think fscontext changed the context of all files underneath the mount point. I don't want that, I just want to change the context at the top and leave the rest of the filesystem unchanged.
selinux@lists.fedoraproject.org