在Debian服务器上,MariaDB默认的数据文件、日志和套接字通常集中在/var/lib/mysql目录下。如果你使用systemd查看MariaDB的进程树,会发现它默认只受到极简的限制,很多时候连基本的文件系统访问控制都依赖传统的自主访问控制(DAC)。一旦SQL注入或存储过程漏洞被利用,攻击者可以轻易读取/etc/passwd或向/tmp写入恶意共享库。AppArmor的强制访问控制(MAC)能精确限定mysqld进程能访问哪些路径、能执行什么操作,即使进程以mysql用户身份运行,也无法越界。
确认AppArmor状态与基础工具在开始配置之前,先检查AppArmor是否已启用并运行。Debian 10/11/12默认安装AppArmor,但部分精简镜像可能未激活。执行aa-status查看当前加载的策略和处于强制模式的进程。如果提示命令未找到,需要安装apparmor和apparmor-utils包。
sudo apt update sudo apt install apparmor apparmor-utils -y
接下来确认内核参数是否支持。检查/sys/module/apparmor/parameters/enabled文件内容是否为Y。如果是,说明内核已开启AppArmor支持。然后使用systemctl status apparmor确认服务正在运行。如果服务未启动,执行sudo systemctl enable --now apparmor。对于生产环境,建议在/etc/default/grub的GRUB_CMDLINE_LINUX_DEFAULT中添加apparmor=1 security=apparmor,然后运行update-grub并重启,确保启动阶段即加载策略。
生成MariaDB的初始AppArmor策略MariaDB在Debian仓库中通常不会自动携带完整的AppArmor配置文件。某些版本会在/etc/apparmor.d/下生成一个名为usr.sbin.mysqld的占位文件,但内容多为注释或仅包含基础路径。我们需要基于实际进程行为生成或编写精确的策略。使用aa-genprof工具可以捕获进程在一段时间内的系统调用,并自动生成规则。
先停止MariaDB服务,然后以complain模式启动策略生成。执行以下命令:
sudo systemctl stop mariadb sudo aa-genprof /usr/sbin/mariadbd
在另一个终端启动MariaDB,并模拟所有正常业务操作:执行复杂查询、调用存储过程、进行备份、执行FLUSH LOGS等。尽可能覆盖所有使用的插件,比如如果你使用了CONNECT存储引擎或S3存储引擎,一定要在测试中触发相关路径访问。操作完成后,回到aa-genprof的交互界面,按S扫描日志,然后按A允许合理的访问,按D拒绝明显异常的模式。对于路径访问,工具会逐一询问,你需要根据MariaDB的实际数据目录、日志目录、临时目录和套接字位置进行选择。
如果你对MariaDB的路径结构非常熟悉,也可以直接手动编写策略文件。在/etc/apparmor.d/下创建usr.sbin.mariadbd文件。以下是一个经过生产环境验证的基础策略框架,根据实际路径调整:
#include/usr/sbin/mariadbd { #include #include capability dac_override, capability setuid, capability setgid, capability net_bind_service, # 数据目录 /var/lib/mysql/ r, /var/lib/mysql/ rwk, # 日志与PID /var/log/mysql/ r, /var/log/mysql/* rw, /var/run/mysqld/ r, /var/run/mysqld/* rw, # 套接字与临时文件 /tmp/ rwk, /var/tmp/ rwk, # 系统库与配置 /etc/mysql/ r, /usr/lib/mysql/plugin/ r, /usr/lib/mysql/plugin/*.so mr, # 系统资源 /proc/*/status r, /sys/devices/system/cpu/ r, /sys/devices/system/cpu/ r, # 禁止访问敏感区域 deny /etc/shadow r, deny /root/ rwx, }
这个策略的核心思路是白名单机制:只允许mysqld进程访问其运行必需的路径,其他一律默认拒绝。注意/var/lib/mysql/使用了rwk权限,其中k表示可以锁定文件,这对MyISAM表至关重要。如果你的MariaDB完全使用InnoDB,k权限可以去掉,但保留也无害。/tmp和/var/tmp的rwk权限是为了支持临时表和排序文件,但这里存在一个安全风险点:如果攻击者能在/tmp创建恶意文件,可能通过符号链接攻击绕过限制。更严格的做法是将MariaDB的tmpdir指定到专用目录,比如/var/lib/mysql-tmp,然后在策略中仅开放该目录。
调整MariaDB服务单元以集成AppArmorDebian的MariaDB服务单元文件通常位于/lib/systemd/system/mariadb.service。为了让AppArmor在进程启动时即应用策略,需要确保服务单元包含AppArmor相关的指令。检查服务单元是否已有AppArmorProfile=或相关的注释。如果没有,可以通过systemctl edit mariadb创建覆盖文件,添加以下内容:
[Service] AppArmorProfile=/etc/apparmor.d/usr.sbin.mariadbd
同时,确保服务单元没有使用NoNewPrivileges=yes这类可能干扰AppArmor切换的选项。重新加载systemd配置并重启MariaDB:
sudo systemctl daemon-reload sudo systemctl restart mariadb
重启后,使用aa-status | grep mariadbd确认进程处于enforce模式。如果显示为complain,说明策略尚未切换到强制模式,执行sudo aa-enforce /etc/apparmor.d/usr.sbin.mariadbd然后再次重启服务。此时,任何超出策略范围的访问都会被内核拒绝,并生成审计日志。
处理常见拒绝事件与日志分析策略部署后,/var/log/syslog或/var/log/audit/audit.log中会出现APPARMOR开头的拒绝记录。每条记录都包含profile名称、请求的操作、目标路径和PID。不要盲目放行所有拒绝请求,需要逐条分析。例如,如果看到mariadbd请求对/var/lib/mysql/ib_logfile0的m权限被拒绝,说明策略中缺少对InnoDB重做日志的mmap可执行权限。修正方法是在数据目录规则中添加m标志:
/var/lib/mysql/ rwmk,
如果日志中出现对/proc/sys/kernel/random/entropy_avail的读取拒绝,这是MariaDB在生成随机数时读取熵池信息,属于正常行为,可以添加:
/proc/sys/kernel/random/entropy_avail r,
对于使用了PAM认证插件的MariaDB,还需要访问/etc/pam.d/下的配置和与PAM通信的抽象套接字。此时可以在策略中引入#include <abstractions/authentication>,但要注意该抽象文件可能开放过多权限,建议仅添加实际需要的PAM相关路径。
如果出现deny ptrace或deny signal相关拒绝,通常是因为某些监控脚本或运维工具试图向mysqld发送信号。对于合法的运维需求,可以在策略中添加:
signal (receive) peer=/usr/sbin/mariadbd,
但更安全的方式是通过systemctl或mysqladmin进行管理,这些工具通过套接字通信,不依赖信号。
进阶加固:限制子进程与网络协议默认策略没有限制MariaDB是否可以执行外部程序或调用脚本。如果你的业务中使用了用户定义函数(UDF)或sys_exec类函数,必须严格限制可执行路径。在策略中添加:
/usr/lib/mysql/plugin/*.so mr, deny /bin/ x, deny /usr/bin/ x,
仅允许加载插件目录中的共享库,禁止执行任何外部二进制文件。如果确实需要执行特定脚本,比如备份脚本,应明确指定绝对路径并仅授予rx权限。
网络方面,MariaDB默认绑定3306端口,也可能绑定IPv6地址。AppArmor支持网络规则,但需要内核支持且策略中显式声明。在策略文件顶部添加:
network inet stream, network inet6 stream,
这允许进程使用TCP套接字。如果你还启用了Galera集群,需要额外允许UDP端口用于节点间通信,以及组播地址。Galera通常使用4567端口进行复制,4568端口进行增量状态传输。策略中应添加:
network inet udp, network inet6 udp,
但这样开放了所有UDP端口,更精细的控制可以通过Netfilter实现,AppArmor的网络规则粒度较粗,建议结合iptables进行端口级限制。
维护策略版本与自动化审计MariaDB版本升级后,可能会引入新的文件访问需求或改变某些路径。每次升级前,建议将策略切换到complain模式运行一段时间,收集新的访问模式。可以使用aa-logprof工具分析日志并自动更新策略:
sudo aa-logprof
该工具会扫描审计日志中的拒绝事件,并以交互方式询问是否允许。对于批量服务器,可以将策略文件纳入配置管理系统(如Ansible或Puppet),并在部署后自动执行aa-enforce。同时,建议配置logrotate对审计日志进行轮转,避免磁盘占满。在/etc/logrotate.d/下创建apparmor配置文件,对/var/log/audit/audit.log进行每日轮转和压缩。
对于需要符合合规性要求的场景,可以将AppArmor策略与文件完整性监控(如AIDE)结合使用。当策略文件被修改时触发告警,防止攻击者篡改策略后重启服务绕过限制。策略文件本身应仅允许root写入,权限设置为600。
经过上述配置,MariaDB进程被牢牢限制在预定义的沙箱中。即使出现SQL注入漏洞,攻击者也难以读取系统敏感文件、执行系统命令或向非授权目录写入Webshell。这种纵深防御措施与SQL注入防护、最小权限用户配置共同构成了数据库安全的多层防线。
