mysql必须用mysql低权限用户启动,否则存在root提权风险;需验证ps aux中mysqld进程uid、/var/lib/mysql属主与750权限、systemd service文件中user=mysql且execstart指向mysqld而非mysqld_safe。

MySQL 必须用专用低权限系统用户(如 mysql)启动,否则一旦进程被攻破,攻击者直接拿到宿主机 root 权限——这不是假设,是已知的提权路径。
确认当前 mysqld 进程运行身份
别猜,直接看真实 UID:
- 执行
ps aux | grep mysqld,找主进程(不是 grep 自身那行),看第一列用户名。如果是root,立刻停服务,别继续往下配 - 若显示为
mysql,再验证是否真由 systemd 控制:运行systemctl status mysqld,确认 Active 状态且 Loaded 行指向正确的 service 文件 - 常见陷阱:看到
mysql用户,但实际是mysqld_safe启动的——它会忽略 systemd 的User=设置,偷偷切回 root。查systemctl cat mysqld中ExecStart=是否指向mysqld二进制,而非mysqld_safe
设置数据目录归属与最小权限
MySQL 启动失败 70% 以上源于 /var/lib/mysql(或你自定义的 datadir)权限不对,my.cnf 里的 user=mysql 配置项完全不生效。
- 先确保属主正确:
chown -R mysql:mysql /var/lib/mysql(路径按实际datadir值调整) - 目录权限必须是
750:chmod -R 750 /var/lib/mysql。禁止777、775或任何 group/other 可写权限,否则 mysqld 拒绝启动并报Permission denied或Operating system error number 13 - 关键文件(
ibdata1、ib_logfile*、*.ibd、*.frm)建议设为640:find /var/lib/mysql -type f -exec chmod 640 {} \; - 上级目录(如
/var/lib)也应限制:确保mysql用户能进入,但其他用户不能遍历或写入
修正 systemd service 文件中的 User/Group
现代 Linux(CentOS 8+/Ubuntu 20.04+)全部走 systemd,User= 和 Group= 必须显式声明在 [Service] 段内,且不能留空或写 root。
- 编辑 service 文件:
sudo systemctl edit --full mysqld(或直接改/usr/lib/systemd/system/mysqld.service) - 在
[Service]下确认存在且仅存在一行:User=mysql和Group=mysql - 检查
ExecStart=:必须是/usr/sbin/mysqld或类似绝对路径,不能含mysqld_safe - 重载并重启:
sudo systemctl daemon-reload && sudo systemctl restart mysqld - 重启后立刻验证:
ps aux | grep mysqld+ls -ld /var/lib/mysql
配置文件与日志路径权限不能漏
很多人修完 data 目录就以为万事大吉,结果 log-error 或 pid-file 路径不可写,导致服务静默失败。
-
my.cnf(如/etc/my.cnf)权限设为644或更严的640,属主可为root:mysql,确保mysql用户有读权限 - 错误日志目录(如
/var/log/mysqld.log所在目录)必须属主mysql:mysql,权限750;日志文件本身建议640 - 若自定义了
pid-file或socket路径(如/var/run/mysqld/mysqld.pid),对应目录必须存在且mysql用户可创建文件 - SELinux/AppArmor 启用时,还需适配策略,否则即使文件权限全对也会被拦截——先用
setenforce 0临时关闭测试,确认是策略问题再针对性放行
真正难的不是命令怎么敲,而是每次修改后都要交叉验证三处:进程 UID、data 目录属主与权限、service 文件中 User= 是否被 mysqld_safe 绕过。漏掉任意一环,加固就形同虚设。











