MySQL 用户最佳实践:按站分离、改密码、改授权、限制 IP
一台服务器上跑着好几个站,图省事全用 root 连库——这是最常见的做法,也是出事时代价最大的做法。本文讲怎么把数据库账号按站拆开、怎么安全地改密码和授权、怎么把账号锁到指定来源 IP,以及几个容易被忽略的配套问题。 文中场景与配置均已脱敏。 一、为什么要按站分离 假设一台机器上跑两个站:一个商城前台,一个用 WordPress 做的收单页。两个站各有各的库。 如果两个站都用 root 连库,那么任何一个站被打穿,攻击者拿到的就是整台机器上所有库的完全控制权——包括另一个站的订单、用户、支付记录。一个不起眼的插件漏洞,赔上的是全部数据。 正确做法是一站一账号,每个账号只授权自己那个库: CREATE USER 'shop_app'@'%' IDENTIFIED BY '强密码'; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON `shop`.* TO 'shop_app'@'%'; CREATE USER 'wp_app'@'%' IDENTIFIED BY '另一个强密码'; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `wordpress`.* TO 'wp_app'@'%'; FLUSH PRIVILEGES; 这样 WordPress 那个站即使被完全控制,攻击者在数据库层面也只能看到 wordpress 库,商城的数据碰不到。 权限给到什么程度 Web 应用需要的其实就两类: 数据操作:SELECT INSERT UPDATE DELETE——日常读写 结构操作:CREATE DROP INDEX ALTER——迁移(migration)要用 CREATE TEMPORARY TABLES 和 LOCK TABLES 按框架需要给。剩下的一律不给,尤其这几个: 权限 作用 为什么不给 EVENT 数据库定时任务 应用调度一般在系统层(cron / systemd timer),用不上;给了等于让攻击者能植入定时后门 TRIGGER 触发器 业务逻辑写在应用里的项目用不到;给了能悄悄篡改写入的数据 EXECUTE 存储过程 同上 FILE 读写服务器文件 绝对不能给,能直接读 /etc/passwd、写 webshell GRANT OPTION 给别人授权 给了等于账号能自我提权 二、账号分离不等于安全 账号按上面的方式拆开之后,看起来隔离已经做到位了。但如果 WordPress 那个站被一个免登录 RCE 漏洞打穿,情况未必如预期。 ...