前言
數據庫安全的第一道防線是賬號體系。MySQL 5.7+ 推薦使用 CREATE USER、GRANT、REVOKE 標準語法,摒棄直接操作 mysql.user 表的舊方式。本文覆蓋用戶全生命周期管理、權限模型解析、最小權限落地模板、常見坑點修復。
一、標準化用戶創建流程
-- 1. 創建用戶(指定主機、強密碼、認證插件)
CREATE USER 'app_user'@'10.0.%.%' IDENTIFIED WITH mysql_native_password BY 'Str0ngP@ssw0rd!';
-- 2. 授權(具體庫、具體表、具體權限)
GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app_user'@'10.0.%.%';
-- 3. 生效
FLUSH PRIVILEGES;
二、權限層級與常用權限項
| 層級 | 語法示例 | 適用場景 |
| 全局 | GRANT SELECT ON *.* TO 'readonly'@'%'; | 監控、備份賬號 |
| 庫級 | GRANT ALL ON app_db.* TO 'app_admin'@'%'; | 應用管理員、DBA |
| 表級 | GRANT SELECT, INSERT ON app_db.orders TO 'etl'@'%'; | ETL、數據分析 |
| 列級 | GRANT SELECT (id, name) ON app_db.users TO 'api'@'%'; | 敏感字段隔離(密碼、身份證) |
| 存儲程序/函數 | GRANT EXECUTE ON PROCEDURE app_db.proc TO 'dev'@'%'; | 開發調試 |
| 代理用戶 | GRANT PROXY ON 'real_user'@'%' TO 'proxy_user'@'%'; | 連接池、中間件透傳 |
常用權限關鍵字
ALL PRIVILEGES:除 GRANT OPTION 外所有權限
SELECT/INSERT/UPDATE/DELETE:DML 基礎權限
CREATE/DROP/ALTER/INDEX:DDL 權限(謹慎授予)
REFERENCES:外鍵創建
RELOAD/SHUTDOWN/PROCESS/SUPER:管理權限(極度受限)
REPLICATION SLAVE/CLIENT:複製專用
三、最小權限原則落地模板
3.1 應用讀寫賬號
CREATE USER 'app_rw'@'10.0.%.%' IDENTIFIED BY 'RwPass#2024';
GRANT SELECT, INSERT, UPDATE, DELETE ON app_db.* TO 'app_rw'@'10.0.%.%';
3.2 只讀賬號(報表/分析)
CREATE USER 'app_ro'@'10.0.%.%' IDENTIFIED BY 'RoPass#2024';
GRANT SELECT ON app_db.* TO 'app_ro'@'10.0.%.%';
-- 限制單查詢最大行數/執行時間(需資源組/ProxySQL 配合)
3.3 遷移/同步賬號
CREATE USER 'repl'@'10.0.%.%' IDENTIFIED BY 'ReplPass#2024';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.0.%.%';
3.4 監控/備份賬號
CREATE USER 'monitor'@'10.0.%.%' IDENTIFIED BY 'MonPass#2024';
GRANT SELECT, PROCESS, REPLICATION CLIENT, SHOW DATABASES ON *.* TO 'monitor'@'10.0.%.%';
四、密碼策略與安全加固
-- 修改密碼
ALTER USER 'app_rw'@'10.0.%.%' IDENTIFIED BY 'NewRwPass#2024';
-- 密碼過期策略(5.7+)
ALTER USER 'app_rw'@'10.0.%.%' PASSWORD EXPIRE INTERVAL 90 DAY;
ALTER USER 'app_rw'@'10.0.%.%' PASSWORD HISTORY 5; -- 禁止重用近 5 次
-- 鎖定/解鎖賬號
ALTER USER 'app_rw'@'10.0.%.%' ACCOUNT LOCK;
ALTER USER 'app_rw'@'10.0.%.%' ACCOUNT UNLOCK;
-- 連接限制
ALTER USER 'app_rw'@'10.0.%.%' WITH MAX_QUERIES_PER_HOUR 10000 MAX_CONNECTIONS_PER_HOUR 100;
五、常見報錯與修復
| 報錯 | 原因 | 修復 |
Field 'ssl_cipher' doesn't have a default value | 直接 INSERT mysql.user 缺少非空列 | 改用 CREATE USER,或設置 sql_mode=NO_ENGINE_SUBSTITUTION 重啟 |
Access denied for user 'x'@'localhost' | 主機名不匹配(localhost ≠ 127.0.0.1) | 創建 'x'@'localhost' 和 'x'@'127.0.0.1' 兩賬號,或用 'x'@'%' |
Password fails policy | validate_password 插件強制複雜度 | 調整 validate_password.length/policy 或使用更強密碼 |
六、審計與清理腳本
-- 查看用戶權限
SHOW GRANTS FOR 'app_rw'@'10.0.%.%';
-- 刪除用戶
DROP USER 'app_rw'@'10.0.%.%';
-- 定期審計:無權限用戶、通配符主機 '%'、空密碼、超級權限濫用
SELECT User, Host, authentication_string FROM mysql.user WHERE authentication_string = '' OR authentication_string IS NULL;