四月 20th, 2012
MySQL can’t change data dir & SELinux
这两天在迁移mysql data dir的时候,发现新的data dir /data/mysql 在权限设置都正确的情况下,还是会报 Can’t change dir to ‘/data/mysql’ (Errcode: 13) 。ErrCode 13也确实就是反映权限问题。网上查询了半天,查出有可能是SELinux的设置。于是,把SELinux关掉再重启mysql,starting mysql [OK]。
问题解决了,但是解决方式简单粗暴 =。= ,直接关掉SELinux。从安全方面考虑,这种方式不提倡。
so,研究研究SELinux吧。原以为SELinux会很难懂,我很怕这种权限问题,一看就觉得头大。读完Vincent Danen的这三篇关于SELinux的文章和SELinux的Wiki,之后,其实觉得SELinux也没我想象中那么complicated。
首先,SELinux是什么。简单说,SELinux帮助控制applicates可以访问哪些资源,这可以帮助我们阻止非法的访问请求。就像mysql,默认的SELinux只会把/var/lib/mysql作为MySQL可以访问的数据资源,而我们更改为/data/mysql下,就需要做额外的SELinux配置。
了解了SELinux是什么,找台机器试验一下。先看看系统环境,系统版本为centos 6.0。
[root@lxnaevcj ~]# head -n 1 /etc/issue
CentOS Linux release 6.0 (Final)
获取当前SELinux情况。
[root@lxnaevcj ~]# getenforce
Enforcing
SELinux有三种状态,Enforcing(1),Permissive(0) 和 Disabled。Enforcing表明系统处于SELinux保护中,任何不合法的请求将被deny和report;Permissfive不阻止非法请求只进行report,Disabled则无任何操作。在Enforcing和Permisive这两种状态中切换只需要setenforce 0 或者setenfore 1,切换到disabled或者从disabled切到其他状态则需要更改/etc/sysconfig/selinux中的配置并重启机器。
SELinux中主要有4个概念,Users,Roles,Types 和Contexts。SELinux Users以_u结尾,Roles以_r结尾,Types为_t,Context(也被成为label) 则是一个进程或者一个文件的属性,用于表明进程访问这个文件的合法性。一个用户进程通常拥有f user_u:user_r:user_t的 context而用户的home目录则是user_u:object_r:user_home_t的context。
查看/var/lib/mysql的context,用 ls -Z命令。
可以看到mysql文件夹的权限为
drwxr-xr-x. mysql mysql system_u:object_r:mysqld_db_t:s0 mysql
也就是用户为system_u,角色为object_r,type为mysqld_db_t,s0是MLS range。
再看看/data/mysql的权限
drwxr-xr-x. mysql mysql system_u:object_r:default_t:s0 mysql
Type不一样,因此chcon -R -t mysqld_db_t /data/mysql 更改type为 mysqld_db_t
好,启动mysq。/etc/init.d/mysql start
=====================我是意外的分割线====================
重启MySQL竟然失败了,报的错还是和以前一样,Can’t change dir to ‘/data/mysql/’ (Errcode: 13)。这不能忍了。。SELinux的设置难道还是不对么!SELinux你是个大骗纸么!(ivy在卖萌了)
逼ivy开大啊,看log,troubleshotting SELinux,第五节。
下载了sealert,并且将audit log转为可读模式,然后仔细研究log发现一句话。
SELinux is preventing /usr/libexec/mysqld from search access on the directory /data.
If you want to allow mysqld to have getattr access on the data directory
Then you need to change the label on /data
Do
# semanage fcontext -a -t FILE_TYPE ‘/data’
where FILE_TYPE is one of the following:。。。。。
Then execute:
restorecon -v ‘/data’
果断尝试一下,semanage fcontext -a -t mysqld_db_t ‘/data’ ;restorecon -v ‘/data’
终于,MySQL启动成功。
原来还涉及到/data这个文件目录的权限,默认的/var/文件夹type为var_t,/var/lib的type为var_lib_t,这两种type应该mysql也能访问。
最后展示下所有相关文件的SELinux权限和用户。
system_u:object_r:mysqld_db_t:s0 /data
system_u:object_r:mysqld_db_t:s0 /data/mysql
/data/mysql里所有文件 unconfined_u:object_r:mysqld_db_t:s0




