基于 SELinux/AppArmor 对 MySQL 进程的沙箱限制

好嘞,各位看官,欢迎来到今天的“MySQL历险记——沙箱求生记”特别节目! 🚀

我是你们的老朋友,一位在代码丛林里摸爬滚打多年的程序猿,今天咱们不聊高并发,不谈数据库优化,而是要聊聊一个非常重要,但又经常被大家忽略的安全话题:如何用SELinux/AppArmor给咱们的MySQL进程戴上“紧箍咒”,让它老老实实地在沙箱里待着!

别害怕,这可不是什么玄学魔法,而是一门实实在在的安全技术。想象一下,如果你的MySQL服务器不幸被攻破,黑客们就能像在自家后院一样,随意窃取你的数据,甚至篡改你的业务逻辑。这可不是闹着玩的! 😱

所以,今天咱们的目标就是:用最通俗易懂的语言,带大家了解SELinux/AppArmor,并学会如何用它们为MySQL打造一个坚不可摧的沙箱。

第一幕:沙箱的呼唤——为什么要给MySQL“上锁”?

各位,咱们先来聊聊“沙箱”这个概念。想象一下,你家的小朋友在沙滩上玩耍,你肯定会划出一个区域,告诉他:“只能在这里玩,不能跑到马路上去!”

这个划定的区域,就是沙箱。它的作用就是限制小朋友的活动范围,防止他跑到危险的地方去。

同样的道理,MySQL进程也需要一个沙箱。这个沙箱的作用是:

  • 限制MySQL进程的权限:让它只能访问特定的文件、目录和网络资源,不能随意乱来。
  • 隔离MySQL进程:即使MySQL进程被攻破,黑客也只能在沙箱内部活动,无法轻易地渗透到其他系统组件。
  • 增强安全性:即使MySQL软件本身存在漏洞,沙箱也能提供额外的保护层,降低被攻击的风险。

总之,给MySQL“上锁”,是为了让它在可控的环境下运行,防止出现意外情况。

第二幕:两位“锁匠”登场——SELinux和AppArmor

现在,我们来认识一下两位“锁匠”:SELinux和AppArmor。它们都是Linux内核的安全模块,负责实现强制访问控制(Mandatory Access Control,MAC)。

简单来说,MAC就是一种更严格的权限管理机制。传统的Linux权限模型(自主访问控制,DAC)是基于用户和组的,而MAC则是基于安全上下文的。

你可以把DAC想象成一把普通的锁,只要你有钥匙(用户权限),就能打开门(访问文件)。而MAC则像一把更高级的锁,不仅需要钥匙,还需要经过额外的身份验证(安全策略)。

SELinux和AppArmor的区别在于:

特性 SELinux AppArmor
策略类型 基于类型的强制访问控制(Type Enforcement) 基于路径的强制访问控制(Path-Based Access Control)
策略粒度 更细,可以控制进程对文件、目录、网络资源等各种对象的访问权限 相对较粗,主要基于文件路径进行控制
策略复杂性 相对较高,配置和管理比较复杂 相对较低,配置和管理比较简单
适用场景 对安全性要求非常高的场景,需要精细的权限控制 对安全性要求较高,但又希望配置和管理简单的场景
默认状态 在某些Linux发行版(如Red Hat、CentOS)中默认启用 在某些Linux发行版(如Ubuntu、SUSE)中默认启用

总的来说,SELinux更强大,但也更复杂。AppArmor更简单,但也相对较弱。选择哪个“锁匠”,取决于你的具体需求和技术水平。

第三幕:SELinux——打造“金刚罩”

接下来,我们先来学习如何用SELinux给MySQL打造一个“金刚罩”。

  1. 检查SELinux状态

首先,我们需要检查SELinux是否已启用:

sestatus

如果输出类似以下内容,说明SELinux已启用:

SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux policy loaded:          targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy memory:       313M

如果Current modedisabledpermissive,则需要启用SELinux。

  1. 安装SELinux策略包

为了方便管理SELinux策略,我们可以安装一些策略包:

yum install policycoreutils policycoreutils-python selinux-policy selinux-policy-targeted libselinux-utils
  1. 查找MySQL的SELinux类型

我们需要找到MySQL进程的SELinux类型,才能为其创建自定义策略。可以使用ps命令和Z选项来查看:

ps -Z $(pidof mysqld)

输出类似以下内容:

system_u:system_r:mysqld_t:s0 1234 ?   00:00:00 mysqld

其中,mysqld_t就是MySQL进程的SELinux类型。

  1. 创建自定义SELinux策略

接下来,我们需要创建一个自定义的SELinux策略,来限制MySQL进程的权限。

首先,创建一个策略文件(例如mysql.te):

module mysql 1.0;

require {
    type mysqld_t;
    type mysqld_db_t;
    type var_lib_t;
    type etc_t;
    class file { read write create getattr open };
    class dir { read search open getattr add_name write remove_name };
    class unix_stream_socket connectto;
    class tcp_socket name_bind;
}

# 允许MySQL进程读写数据库文件
allow mysqld_t mysqld_db_t:file { read write create getattr open };
allow mysqld_t var_lib_t:dir { read search open getattr add_name write remove_name };

# 允许MySQL进程读取配置文件
allow mysqld_t etc_t:file { read getattr open };

# 允许MySQL进程监听TCP端口
allow mysqld_t port_t:tcp_socket name_bind;

# 允许MySQL进程连接到Unix套接字
allow mysqld_t mysqld_t:unix_stream_socket connectto;

这个策略文件的含义是:

  • 允许mysqld_t类型的进程读写mysqld_db_t类型的文件(数据库文件)。
  • 允许mysqld_t类型的进程读取etc_t类型的文件(配置文件)。
  • 允许mysqld_t类型的进程监听TCP端口。
  • 允许mysqld_t类型的进程连接到Unix套接字。

然后,使用checkmodulesemodule_package命令将策略文件编译成二进制模块:

checkmodule -M -m -o mysql.mod mysql.te
semodule_package -m mysql.mod -o mysql.pp

最后,使用semodule命令安装策略模块:

semodule -i mysql.pp
  1. 设置文件和目录的安全上下文

我们需要为MySQL的数据库文件、配置文件等设置正确的安全上下文。可以使用chcon命令来修改:

chcon -t mysqld_db_t /var/lib/mysql -R
chcon -t etc_t /etc/my.cnf
  1. 测试SELinux策略

重启MySQL服务,并观察日志文件,看看是否有任何SELinux拒绝访问的错误。

systemctl restart mysqld
ausearch -m avc -ts recent

如果有错误,需要修改SELinux策略,直到MySQL能够正常运行。

第四幕:AppArmor——打造“铁布衫”

接下来,我们来学习如何用AppArmor给MySQL打造一个“铁布衫”。

  1. 检查AppArmor状态

首先,我们需要检查AppArmor是否已启用:

apparmor_status

如果输出类似以下内容,说明AppArmor已启用:

apparmor module is loaded.
apparmor profiles are loaded.
  1. 创建AppArmor配置文件

我们需要为MySQL创建一个AppArmor配置文件,来限制MySQL进程的权限。

创建一个配置文件(例如/etc/apparmor.d/usr.sbin.mysqld):

#include <tunables/global>

/usr/sbin/mysqld {
  #include <abstractions/base>
  #include <abstractions/mysql>

  capability dac_override,
  capability sys_resource,
  capability net_bind_service,
  capability setgid,
  capability setuid,
  capability chown,

  /etc/mysql/my.cnf r,
  /etc/mysql/conf.d/ r,
  /var/log/mysql/ r,
  /var/log/mysql/* w,
  /var/lib/mysql/ r,
  /var/lib/mysql/** rw,
  /tmp/mysql.sock w,
  /run/mysqld/mysqld.pid w,

  network inet tcp,
  network unix stream,

}

这个配置文件的含义是:

  • 允许MySQL进程读取/etc/mysql/my.cnf配置文件。
  • 允许MySQL进程读取/etc/mysql/conf.d/目录下的所有文件。
  • 允许MySQL进程读取/var/log/mysql/目录下的所有文件。
  • 允许MySQL进程写入/var/log/mysql/*文件(日志文件)。
  • 允许MySQL进程读取/var/lib/mysql/目录下的所有文件。
  • 允许MySQL进程读写/var/lib/mysql/**文件(数据库文件)。
  • 允许MySQL进程写入/tmp/mysql.sock文件(Unix套接字)。
  • 允许MySQL进程写入/run/mysqld/mysqld.pid文件(PID文件)。
  • 允许MySQL进程使用TCP网络协议。
  • 允许MySQL进程使用Unix流套接字。
  • 允许MySQL进程拥有某些capability (例如: dac_override, net_bind_service)
  1. 加载AppArmor配置文件

使用apparmor_parser命令加载配置文件:

apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld
  1. 设置AppArmor模式

AppArmor有两种模式:enforcecomplain

  • enforce模式:强制执行AppArmor策略,拒绝任何违反策略的操作。
  • complain模式:不强制执行AppArmor策略,但会记录任何违反策略的操作。

建议先使用complain模式进行测试,然后再切换到enforce模式。

aa-complain /usr/sbin/mysqld
  1. 测试AppArmor策略

重启MySQL服务,并观察日志文件,看看是否有任何AppArmor拒绝访问的错误。

systemctl restart mysqld
dmesg | grep apparmor

如果有错误,需要修改AppArmor配置文件,直到MySQL能够正常运行。

  1. 切换到enforce模式

当MySQL能够正常运行后,可以切换到enforce模式:

aa-enforce /usr/sbin/mysqld

第五幕:锦上添花——一些实用技巧

  • 使用audit2allow工具audit2allow是一个非常有用的工具,可以根据SELinux/AppArmor的日志,自动生成策略规则。
  • 定期审查策略:定期审查SELinux/AppArmor策略,确保其仍然有效,并及时更新。
  • 使用容器技术:容器技术(如Docker)本身就提供了一定的隔离性,可以与SELinux/AppArmor结合使用,进一步增强安全性。
  • 最小权限原则:在配置SELinux/AppArmor策略时,尽量遵循最小权限原则,只授予MySQL进程必要的权限。

总结:安全无小事,防患于未然

各位,今天的“MySQL历险记——沙箱求生记”就到这里了。希望通过今天的学习,大家能够认识到安全的重要性,并学会使用SELinux/AppArmor为MySQL打造一个安全的运行环境。

记住,安全无小事,防患于未然。只有做好安全防护,才能让我们的数据和业务免受威胁。

最后,祝大家编码愉快,永不宕机! 🥳

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注