• 欢迎访问Selinux网站,Selinux信息,Selinux教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入Selinux Linux常用命令手册
  • Selinux现已支持滚动公告栏功能,兼容其他浏览器,看到的就是咯,在后台最新消息那里用li标签添加即可。
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏Selinux吧

[翻译]SELinux之于MySQL

Selinux实例 selinuxcn 2年前 (2017-01-01) 2957次浏览 扫描二维码

译序

原文参见这里:SELinux and MySQL 作者是 Jeremy Smyth on Mar 22, 2013
20170101202123

以下是译文

========================================================

SELinux(安全强化,如果你感兴趣)“是 linux 中支持安全访问控制策略机制的一种特性”–维基百科。更简单的说,它能阻止比如程序之类的访问他们不应该访问的文件和网络端口等。所谓“不应该访问”这里指的是“尚未被配置为可以访问”。比如说,MySQL 允许访问它的数据目录/var/lib/mysql,并且可以读取/etc/my.cnf。它可以打开 3306 端口,但是 SELinux 阻止它向/home/Jeremy 或者/sbin 或者其他任何尚未配置成为 MySQL 位置的路径进行写操作。

简而言之,如果你想更改 MySQL 的默认端口为一个非标准端口,或者试图备份或者设置数据文件或日志文件到非常用路径,你就会在 MySQL 错误日志里面收到很多奇怪的禁止访问类型的错误。另外,你同样会在/var/log/audit/audit.log(如果 auditd 正在运行,否则在/var/log/messages 或者/var/log/syslog 里面,这取决于你的系统配置)里收到信息。

会得到什么错误呢?
我这边采用了 MySQL5.6 及 Oracle Linux 6.3 作为样例环境,同时启用了 SELinux。当我把 datadir 这个变量设置为/datadir 时(此目录复制了 MySQL 原数据目录的所有内容,并且设置了正确的权限),就无法启动服务了。看下面的错误。

MySQL 错误日志中:
130321 11:50:51 mysqld_safe Starting mysqld daemon with databases from /datadir

2013-03-21 11:50:52 2119 [Warning] Can’t create test file /datadir/boxy.lower-test
2013-03-21 11:50:52 2119 [Warning] Can’t create test file /datadir/boxy.lower-test

2013-03-21 11:50:52 2119 [ERROR] /usr/sbin/mysqld: Can’t create/write to file
‘/datadir/boxy.pid’ (Errcode: 13 – Permission denied)
2013-03-21 11:50:52 2119 [ERROR] Can’t start server: can’t create PID file:
Permission denied
130321 11:50:52 mysqld_safe mysqld from pid file /datadir/boxy.pid ended

我很确信现在这个目录的权限是正确的,我们再来看看/var/log/audit/audit.log:

type=AVC msg=audit(1363866652.030:24): avc: denied { write } for pid=2119
comm=”mysqld” name=”datadir” dev=dm-0 ino=394
scontext=unconfined_u:system_r:mysqld_t:s0
tcontext=unconfined_u:object_r:default_t:s0 tclass=dir

如果我更改端口为非默认端口 3307 时,启动 MySQL 也会遇到类似的错误。

MySQL 错误日志中:
2013-03-21 12:12:09 3436 [Note] Server hostname (bind-address): ‘*’; port: 3307

2013-03-21 12:12:09 3436 [ERROR] Can’t start server: Bind on TCP/IP port:
Permission denied
2013-03-21 12:12:09 3436 [ERROR] Do you already have another mysqld server
running on port: 3307 ?
2013-03-21 12:12:09 3436 [ERROR] Aborting

audit 日志中:
type=AVC msg=audit(1363867929.432:42): avc: denied { name_bind } for pid=3436
comm=”mysqld” src=3307
scontext=unconfined_u:system_r:mysqld_t:s0
tcontext=system_u:object_r:port_t:s0 tclass=tcp_socket

很明显这里有点问题。Access Vector Cache(如日志中显示的“avc: denied”)是 SELinux 用来为内核缓存权限的地方。所以很明显是 SELinux 阻止了操作。

仅仅关闭它就好!

下面就我会先从锤子开始,然后逐渐打造成手术刀。(译注:这个……我不知道理解的对不对,原文是 I’m going to start with the hammer and work my way down to the scalpel. )

锤子如下:

[root@boxy ~]# setenforce 0
[root@boxy ~]# getenforce
Permissive

setenforce 0 用来关闭 SELinux enforcing,重启则失效。getenforce 显示当前状态。如果想要在重启以后仍然生效,想要改写以下配置文件:

[root@boxy ~]# cat /etc/selinux/config

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing – SELinux security policy is enforced.
# permissive – SELinux prints warnings instead of enforcing.
# disabled – No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of these two values:
# targeted – Targeted processes are protected,
# mls – Multi Level Security protection.
SELINUXTYPE=targeted

将 enforcing 设置为 permissive(或者 disabled)就 ok 了。参数的差别如下:

enforcing 阻止 SELinux 不允许的操作
permissive 并不阻止操作,但是会记录日志(/var/log/audit/audit.log)
disabled 完全关闭 SELinux,甚至你都没法使用 setenforce 了,除非换成其他参数,并重启
例如,如果服务器的 SELinux 设置为 permissive,那么我可以这么做:

[root@boxy ~]# setenforce 1
[root@boxy ~]# getenforce
Enforcing

但是如果设置为 disabled,就会这样:

[root@boxy ~]# setenforce 0
setenforce: SELinux is disabled
[root@boxy ~]# setenforce 1
setenforce: SELinux is disabled

以上就是所谓的锤子。

那么,我们返回到产生错误的这个例子,我可以这么使用锤子。

[root@boxy ~]# setenforce 0
[root@boxy ~]# service mysql start –datadir=/datadir
Starting MySQL. SUCCESS!
[root@boxy ~]# service mysql stop
Shutting down MySQL.. SUCCESS!

如果这样子你就满意了,那么你可以编辑配置文件,然后在下次重启时禁用 SELinux,并且谢谢阅览。下次见~

我还是有点迷惑。我该怎么配置它而不是禁用呢?

很明显,比起禁用,还有很多事情可以做。而且负责任的管理员(比如你?)想要知道比起禁用,如何更好的使用它。下面,我不会讨论太多细节。

无论如何,我们可以看看该怎样给比如端口、文件这些对象分配 SELinux 类型(译注:types),然后可以让 mysql_t 域的成员们(尤其是启动 service mysql start 产生的 mysqld_safe 进程)可以访问这些对象。

以下是手术刀了。首先,我们配置一下 SELinux 来启用 MySQL 的 3307 端口

[root@boxy ~]# semanage port -a -t mysqld_port_t -p tcp 3307

(注:你需要首先安装 policycoreutils-python 包来使用 semanage 工具)

semanage 工具可以变更很多 SELinux 设置。这里,我们为使 3307 端口使用 TCP 作为它的协议(-p tcp)而向端口映射增加了(-a)一种类型(-t mysqld_port_t)。当 MySQL(通过 mysqld_safe 进程)试图访问这个端口时,SELinux 从策略(译注:policy)里面识别这个端口匹配一种类型,并且允许进行这样的访问。

同样我们可以允许 MySQL 使用/datadir 文件夹:

[root@boxy ~]# semanage fcontext -a -t mysqld_db_t “/datadir(/.*)?”
[root@boxy ~]# restorecon -Rv /datadir
restorecon reset /datadir context
unconfined_u:object_r:default_t:s0->unconfined_u:object_r:mysqld_db_t:s0
restorecon reset /datadir/mysql.sock context
system_u:object_r:mysqld_var_run_t:s0->system_u:object_r:mysqld_db_t:s0

在这个例子中,semanage 在文件上下文映射(fcontext)中增加了 mysqld_db_t 的类型,指定了/datadir 路径下的所有文件以及子文件(“/datadir(/.*)?”,正则表达式)。这样的文件映射包含在/etc/selinux/targeted/contexts/files/file_contexts.local 文件中,为了能够给这个文件设置合适的类型,这个文件必须能够被读取。restorecon 工具在系统重启的时候就完成了该操作。如果你想马上更改文件上下文并且不需要重启以后还生效,那么使用 chcon 工具就可以了。

如果你想使用其他端口或者文件夹,也可以使用同样的方式和语句。不同类型的文件对应一些类似的类型;我这里使用上面的 mysqld_db_t 来对应数据库文件夹,但是标准 SELinux 策略针对 MySQL 也包含:

mysqld_etc_t 用来匹配配置文件如 /etc/my.cnf
mysqld_log_t 用来匹配日志文件如 /var/log/mysql*
PID 文件、tmp 文件、/etc/init.d 里面的服务启动文件的类型,还有各种各样你想使用的可执行文件。

如你所见,你可以自如的使用你的手术刀来合理的分配权限。就我个人而言,我已经使用像 mysql_log_t 这样的类型匹配自定义的日志文件路径而得到了混合的效果,不过我会首先使用 mysqld_db_t(就像用来匹配数据文件),然后使用自定义的策略文件来搞定。

结语

这篇文章已经够长了,所以我不会讨论更为深入的 SELinux 话题了,比如说编译你自己的策略文件以及为 SELinux 尚不知道的服务配置新的策略。现在,你已经知道如何为 SELinux 增加一种类型,来让 MySQL 可以访问并非默认的端口或者文件了。你也知道了好几种关闭 SELinux 的方法,不过,你现在应该不会那么做了吧?你已经手持完美的手术刀了,何必还去用什么锤子呢?


Selinux 中国 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:[翻译]SELinux 之于 MySQL https://selinux.cn/%e7%bf%bb%e8%af%91selinux%e4%b9%8b%e4%ba%8emysql/
喜欢 (0)