如何限制操作系统用户读取MySQL数据目录

作者:袖梨 2026-08-17

MySQL数据目录安全不靠限制用户组,而是通过属主属组为mysql:mysql、权限750、清理mysql组冗余成员、配置SELinux/AppArmor上下文及管控tmpdir/socket日志等协同实现。

mysql 数据目录(如 /var/lib/mysql)不是靠“限制用户组”实现隔离的,而是靠 Unix 文件权限 + 进程运行身份 + 安全模块协同控制。只要配置稍有偏差,普通用户甚至能直接 cat.ibd 文件或通过 mysqld 崩溃时残留的内存映射访问数据。

datadir 归属和权限必须设为 750

MySQL 服务以 mysql 用户身份运行,默认也属于 mysql 组。目录权限 750 意味着:属主可读写执行、属组可读执行、其他人无任何权限。

若设成 755 或 775,任意本地用户都能 ls /var/lib/mysql 查看库名,甚至用 strings 提取部分明文字段;设成 777 更是直接放弃防线。

  1. 先确认真实路径:mysql -e "SELECT @@datadir;" 或查 my.cnfdatadir 配置项
  2. 递归修正归属:sudo chown -R mysql:mysql /var/lib/mysql
  3. 设目录权限(仅顶层目录,子目录继承 umask):sudo chmod 750 /var/lib/mysql
  4. 严禁对子目录单独 chmod:MySQL 启动时会校验顶层目录权限,子目录权限宽松不影响启动,但可能被利用绕过(如临时文件写入)

mysql 组里不能有非服务账号

mysql 组成员 ≠ “可读 datadir 的人”,而是“具备组权限”的所有本地账户。只要某人被加进 mysql 组,哪怕没密码、没 shell,也能 su -s /bin/sh -c 'ls /var/lib/mysql' mysql 成功执行——因为组权限生效不依赖登录态。

  1. 检查当前成员:getent group mysql
  2. 清理冗余用户:sudo gpasswd -d deploy mysqlsudo gpasswd -d admin mysql
  3. 理想状态是只含 mysql 用户本身,或为空(mysql:x:27:
  4. 不要用 usermod -aG mysql $USER 给运维账号加组——这是最常见误操作

SELinux 或 AppArmor 必须补上下文

即使文件权限正确,SELinux(RHEL/CentOS)或 AppArmor(Ubuntu/Debian)若未放行,mysqld 进程可能因 denied 权限崩溃;反之,若策略宽松,攻击者可通过提权后的进程绕过文件权限读取数据。

  1. CentOS/RHEL:sudo semanage fcontext -a -t mysqld_db_t "/var/lib/mysql(/.*)?",再 sudo restorecon -Rv /var/lib/mysql
  2. Ubuntu:sudo nano /etc/apparmor.d/usr.sbin.mysqld,确保含 /var/lib/mysql/** rwk,,然后 sudo systemctl reload apparmor
  3. 验证是否生效:ls -Z /var/lib/mysql 应显示 mysqld_db_t 上下文(SELinux)或 aa-status | grep mysqld 显示 enforce 模式(AppArmor)

别忽略 tmpdir 和 socket 文件的连带风险

datadir 安全了,不代表整个 MySQL 数据面就安全。攻击者常从旁路切入:

  1. tmpdir(如 /tmp)若被设为全局可写,SELECT ... INTO OUTFILE 可能绕过 secure_file_priv 写出敏感内容——应设为 /var/tmp/mysql-tmpchown mysql:mysql && chmod 700
  2. mysql.sock 文件(如 /var/run/mysqld/mysqld.sock)若权限为 666,本地任意用户都能连接并执行 SHOW VARIABLES 获取配置细节——必须 chmod 660 且属主为 mysql:mysql
  3. 日志文件(error.logslow.log)若包含明文 SQL 或路径信息,也应 chmod 640 并归属 mysql:mysql

真正难的是持续性——mysqld 升级、备份脚本重置权限、运维人员手动 chown -R 到错误路径,都会瞬间击穿这层防线。每次变更后,都得跑一遍 ls -ld /var/lib/mysqlgetent group mysql 确认。

相关文章

精彩推荐