滚动新闻 →
Windows 11 微软账户有什么用途?同步、应用商店和系统功能全面了解 卢比奥呼吁古巴推动变革 川普称可派其处理 MySQL 用户和权限怎么管理?不要让网站使用 root 账号连接数据库 中共五中全会前政局诡异 5省地方高层换人 古代诗词为什么总喜欢写月亮 绿豆与传统夏季饮食 西藏那曲巴青县发生7.0级地震 余震达892次 羊毫、狼毫和兼毫有什么区别 德国巴伐利亚州希特勒别墅‘鹰巢’遭遇严重火灾 新北新庄工地电梯井施工事故致2名工人坠落送医OHCA 南投草屯镇长竞选车失窃 犯嫌窜至台南落网 朝鲜领导人金正恩经新鸭绿江大桥访华引关注 如何教育孩子不要因为嫉妒贬低别人 台风蔷琵致冲绳航班取消 九州或迎登陆 视频拍摄中存储卡突然停止录制怎么办 宋慧乔加盟造型师丈夫新公司 时隔三年将拍时代剧 明朝为什么能够建立长期稳定的统治 瓦努阿图海域6.9级地震引发一天15次余震 有哪些家居改善不需要大笔装修费用 台女富士河口湖遇害 女嫌称旅途中购刀欲赴房间聊天 面条为什么成为很多亚洲国家的重要主食 远离城市灯光,去加拿大尤克卢利特看太平洋上的星星 发动机故障灯自己熄灭后还需要检查吗 相声演员黄逸豪爆红 讽《习近平传》再次疯传 现代汽车到底有多少种传感器 美国房屋地下室检查应该注意哪些问题 约旦教堂丧礼遭枪击 致6死28伤 美国运通启动全球裁员计划,削减约5%员工规模 13岁少女私售万元金链 金店熔化引发法律争议 应急资金应该放在哪里比较合适 宇树科技人形机器人侧空翻断腿事件引热议 巴基斯坦西南部巴士与汽车相撞 致13死21伤 恒大清盘人追讨许家印13亿艺术品亏损逾10亿 公股银行推出休假奖金制度 休越多领越多 游艇发动机配置如何影响价格 华为伊朗业务金流遭曝光 庭审闭门作证防报复 美军新版作战指南将中国视为首要威胁 苹果折叠屏手机iPhone Duo全球发售引抢购热潮 大陆男子报警遭拒后当街行凶 50刀刺杀强奸犯引争议 敦煌两位女生150万创业无烟酒吧终倒闭,坦言‘关门大吉’

MySQL 用户和权限怎么管理?不要让网站使用 root 账号连接数据库

发布时间: 2026-10-24 05:00:03    最后更新: 2026-10-24 06:20:36    阅读:9  约12 分钟阅读     

MySQL 用户和权限怎么管理?不要让网站使用 root 账号连接数据库
图片说明:示意图   图片来源:Public Domain(公有领域)
很多 PHP 网站能够正常运行,并不代表数据库权限设计就是安全的。最常见的问题之一,就是程序配置文件直接使用 MySQL root 账号连接数据库。开发阶段这样做非常方便,建表、修改结构、读写数据全部不用考虑权限问题,但一旦网站代码、配置文件或者服务器本身出现漏洞,攻击者拿到的就不是一个普通应用账号,而可能是一把能够控制整个 MySQL 实例的钥匙。

MySQL 的权限系统本身就是为了避免这种情况。一个账户到底能做什么,由用户名、连接来源以及被授予的权限共同决定。MySQL 官方提供 CREATE USER、GRANT、REVOKE、DROP USER 等语句管理账户,并可以通过 SHOW GRANTS 查看实际权限。

因此,网站程序最基本的原则应该是:root 用来管理数据库,应用程序使用专门的应用账号。

假设网站使用数据库 mnewstv,PHP 应用运行在数据库服务器本机,可以创建一个专门的账号:

CREATE USER 'mnewstv_app'@'localhost'
IDENTIFIED BY '一个足够强的随机密码';

然后只授予这个网站真正需要的权限:

GRANT SELECT, INSERT, UPDATE, DELETE
ON mnewstv.*
TO 'mnewstv_app'@'localhost';

这样 PHP 程序连接数据库时使用:

$pdo = new PDO(
'mysql:host=localhost;dbname=mnewstv;charset=utf8mb4',
'mnewstv_app',
$password,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]
);

即使网站存在 SQL Injection、文件读取漏洞或者配置文件泄露,攻击者首先获得的也是 mnewstv_app 的权限,而不是整个 MySQL 实例的管理员权限。

这里有一个非常重要的概念:MySQL 的 'user'@'host' 才是完整的账户身份。'web_user'@'localhost' 和 'web_user'@'%' 并不是同一个账户。MySQL 会同时根据用户名和连接来源判断账户身份。

因此,如果 PHP 和 MySQL 在同一台服务器上,通常没有必要写成:

CREATE USER 'web_user'@'%'
IDENTIFIED BY 'password';

更合理的是:

CREATE USER 'web_user'@'localhost'
IDENTIFIED BY 'password';

如果 PHP 应用服务器和 MySQL 是分开的,则可以进一步限制到应用服务器的固定地址,例如:

CREATE USER 'web_user'@'10.10.20.15'
IDENTIFIED BY 'password';

GRANT SELECT, INSERT, UPDATE, DELETE
ON mnewstv.*
TO 'web_user'@'10.10.20.15';

这里需要注意,限制 MySQL 账户的 host 只是第一层控制。数据库服务器的防火墙、安全组以及 MySQL 的网络监听配置也应该同时限制来源。不能因为账户写了一个 IP,就认为整个数据库网络已经安全。

更重要的是,不要为了“方便”直接:

GRANT ALL PRIVILEGES
ON *.*
TO 'web_user'@'%';

这实际上把一个网站账号变成了数据库管理员账号。应用程序通常不需要创建其他数据库用户,也不需要删除数据库、修改 MySQL 全局配置或者管理复制。因此,把管理员权限交给网站程序没有实际必要。

应用账号到底需要哪些权限,应当根据程序真正执行的 SQL 决定。

例如普通 SaaS 网站可能需要:

SELECT
INSERT
UPDATE
DELETE

如果程序需要执行数据库迁移,则可能还需要:

CREATE
ALTER
INDEX
DROP

但这里最好进一步区分运行账号和部署账号。

例如:

mnewstv_app
SELECT
INSERT
UPDATE
DELETE

mnewstv_migrate
CREATE
ALTER
INDEX
DROP
以及迁移工具真正需要的其他权限

mnewstv_admin
用于人工数据库管理

PHP 网站的生产进程只使用 mnewstv_app,而数据库结构升级由部署流程临时使用更高权限的账号完成。这样,即使网站运行环境被攻破,攻击者也不能直接利用应用账号修改整个数据库结构。

MySQL 还支持 Role,可以把一组权限集中管理。例如:

CREATE ROLE 'app_rw';

GRANT SELECT, INSERT, UPDATE, DELETE
ON mnewstv.*
TO 'app_rw';

GRANT 'app_rw'
TO 'mnewstv_app';

SET DEFAULT ROLE 'app_rw'
TO 'mnewstv_app';

Role 特别适合多个应用账号需要相同权限的环境。权限集中定义之后,可以减少逐个账号修改权限造成的遗漏。MySQL 官方也将 Role 作为权限集合管理机制。

权限审计时,不建议直接依赖查询 mysql.user 来判断某个账户最终到底拥有什么权限。MySQL 的权限可能来自全局、数据库、表、列以及角色等多个层级。最直接的检查方式是:

SHOW GRANTS FOR 'mnewstv_app'@'localhost';

如果使用 Role,也应该检查角色本身以及角色授予关系。MySQL 官方明确提供 SHOW GRANTS 用于查看账户的权限分配。

修改权限同样应该使用 GRANT 和 REVOKE,而不是直接修改 mysql 系统库中的授权表。MySQL 官方明确不建议直接通过 INSERT、UPDATE 或 DELETE 修改 grant tables。

例如发现网站实际上不需要删除数据,可以收回:

REVOKE DELETE
ON mnewstv.*
FROM 'mnewstv_app'@'localhost';

然后再次执行:

SHOW GRANTS FOR 'mnewstv_app'@'localhost';

确认最终权限。

数据库连接本身也需要考虑加密。如果 PHP 与 MySQL 在同一台服务器上使用 Unix socket,网络窃听风险与跨服务器 TCP 连接不同;但如果 PHP 应用和 MySQL 位于不同服务器、不同 VLAN 或云环境中,就应该认真考虑 TLS。

MySQL 可以通过:

SET PERSIST require_secure_transport = ON;

要求 TCP/IP 连接使用加密传输。需要注意的是,MySQL 官方对 require_secure_transport 的定义并不是“所有连接必须使用 TLS”,因为 Unix socket 和 Windows shared memory 也属于 secure transport。

对于特定账户,也可以在创建账户时设置连接加密要求。例如:

CREATE USER 'remote_app'@'10.10.20.15'
IDENTIFIED BY 'password'
REQUIRE SSL;

如果要求客户端提供有效的 X.509 证书,则可以使用:

REQUIRE X509;

这种方式适合对数据库连接安全要求更高的生产环境。

密码管理同样不能忽略。数据库密码不应该直接写进 Git 仓库,也不要把生产数据库密码硬编码到公开代码中。PHP 应用可以通过服务器环境变量、受控配置文件或者专门的 Secret 管理系统提供数据库凭据。

同时,不应该把“定期强制更换所有数据库密码”当成唯一的安全策略。对于生产系统,更重要的是随机、唯一、权限受限的凭据,以及在凭据泄露、人员离职、服务器迁移或者安全事件发生时能够快速轮换。

另外,数据库管理员账号和网站应用账号应该彻底分开。

例如:

root / DBA账号
数据库维护
创建用户
授予权限
数据库结构管理

mnewstv_migrate
数据库迁移

mnewstv_app
网站运行

mnewstv_readonly
报表、分析或只读工具

不要让 phpMyAdmin、MySQL Workbench 或日常开发工具长期保存 root 凭据,更不要为了方便让网站后台直接调用具有 CREATE USER、GRANT OPTION 等管理能力的账号。

尤其是 GRANT OPTION,它不是普通的数据读写权限。拥有它的账户可以把自己获得的权限进一步授予其他账户,因此对于网站运行账号通常没有理由授予。MySQL 官方的权限模型也明确区分普通对象权限与账户管理能力。

还有一个经常被忽略的问题:不要只保护数据库账号,却让 MySQL 本身暴露在整个互联网。

如果数据库只供 PHP 应用服务器访问,最理想的网络结构通常是:

Internet
↓
Web Server
↓
PHP Application
↓
Private Network
↓
MySQL

而不是:

Internet
↓
MySQL:3306

即使 MySQL 用户设置得非常严格,也没有必要把数据库端口直接暴露给公网。防火墙、安全组、监听地址和 MySQL 账户 host 限制应该形成多层防护。

最后,还应该定期检查到底有哪些账户存在:

SELECT user, host
FROM mysql.user
ORDER BY user, host;

然后针对具体账户:

SHOW GRANTS FOR 'mnewstv_app'@'localhost';

检查是否存在已经不用的账号、过于宽泛的 '%' host、拥有全局权限的应用账户,以及不再需要的管理员权限。

一个成熟的 PHP SaaS 数据库权限体系,并不是简单地把 root 改名成 web_user。真正有效的设计应该是让不同身份承担不同职责:网站只负责自己的数据,迁移账号负责结构变更,管理员负责数据库管理,报表账号负责读取数据。这样即使应用层出现漏洞,攻击者能够获得的权限也被限制在一个明确的范围内。

数据库安全的核心并不是让任何程序都“绝对不能出问题”,而是在程序、服务器或者凭据真的发生问题时,把爆炸半径限制在尽可能小的范围。对一个 PHP SaaS 系统来说,不使用 root 连接数据库只是第一步,真正成熟的权限设计应该继续落实到最小权限、独立账号、限定连接来源、角色管理、TLS、权限审计以及网络隔离。

喜欢这篇报道?

使用下面的功能,方便以后继续阅读和分享 MNewsTV

设为 Google 新闻首选来源 让 Google 新闻优先显示 MNewsTV 的最新报道 ›
★ 我的收藏 查看已经收藏的文章
关于文章收藏 收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。 删除收藏请进入「我的收藏」进行管理。
分享这篇报道

捐助(Paypal): https://www.paypal.me/observeccp
订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP