滚动新闻 →
密西西比州参议员科洛姆获川普公开肯定 民主党中期选举成果显现 SpaceX星舰第15次试飞突破轨道技术 机械哥斯拉首次亮相 唐元隽因涉嫌为中共搜集美国异议人士信息被纽约法院判缓刑三年 欧洲参与俄乌和谈遭分歧 战俘交换后冲突再升级 美国财长:伊朗黑客利用中国AI攻击法国超市冷藏系统 唐元隽涉非法搜集海外异议人士信息被判缓刑 双黄丑闻蔓延白宫 卢特尼克或因放水被问责 黄仁勋辞任事件引安全担忧 中共渗透手段升级 加拿大政界呼吁彻查中共海外警务据点 清华特等奖学金评选引争议 AI方向占比近全 前CIA局长之子因传播儿童色情制品被起诉 突发:新奥尔良港油轮撞上客船 多人落水 美国联邦航空总署实施全国航班停飞措施 退伍军人事务部长披露福利审批通过率高达94% 黄仁勋被美众议院三大委员会要求出席闭门听证会 法国10月通胀率突破3.7% 创近3年新高 山西男子砍伤妻岳母未被批捕 释放后勒死妻子引争议 黄仁勋辞职引台湾日本政界高度关注 唐元隽因向中共提供情报获三年缓刑 欧几里得望远镜发布首批观测数据 助力探索暗宇宙之谜 内蒙古化工厂氨气泄漏事件引争议,官方称属无毒催泪弹演练 英伟达共谍风暴升级 高阶芯片流向成焦点 西安村民因欠款问题冲击政务中心 无锡超算中心遭黑客入侵数据遭出售 网民质疑掩盖真相 Anthropic IPO超额认购六倍 加拿大各界在老兵纪念日缅怀阵亡将士并致敬军人 习近平称继承孙中山理念 学者质疑历史背离 孙中山纪念大会异常引关注 习健康状况引猜测 中国AI模型被指用于伊朗网络攻击 法国超市遭大规模破坏 雕刻大师现场展示技艺 纽约跨年水晶球亮相时代广场 Google Distributed Cloud 是什么,无法全部迁移到公有云的企业可以怎样部署 新疆库车市发生5.0级地震 乌鲁木齐民众普遍感知明显 美以海军高层会谈 土耳其卡塔尔签署防御协议 涉嫌为中共搜集情报 唐元隽纽约获三年缓刑 上海交大基因编辑实验致女童死亡 处罚仅限开除引争议 民主党参议院领袖选举引争议 范霍伦挑战舒默权威 江苏句容城管强抢餐车引摊贩冲突 中共借孙中山纪念进行统战操作 学者质疑继承论述模糊 黄乐与华为关联引调查 深圳数据中心牵出供应链疑云 京沪高铁山东段故障引争议 施工挖断电缆遭质疑

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

发布时间: 2026-10-24 05:00:03    最后更新: 2026-11-13 12:11:58    阅读:82  约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、权限审计以及网络隔离。
本文作者
程越(Kevin Cheng)
IT与人工智能技术资深编辑

喜欢这篇报道?

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

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

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