兩階段存取控制模型
- 階段一:連線驗證 —— 依據
Host、User、Password 判斷是否允許連線。
- 階段二:請求授權 —— 連線成功後,每個 SQL 指令皆依權限表檢查是否具備對應權限(SELECT、INSERT、DROP 等)。
五大授權表結構
| 表名 | 範圍欄位 | 權限欄位 | 適用層級 |
| user | Host, User, Password | 全域權限 (Select_priv, Grant_priv...) | 全域 (超級用戶) |
| db | Host, Db, User | 資料庫級權限 | 資料庫 |
| host | Host, Db | 資料庫級權限 | 資料庫 (輔助 db 表) |
| tables_priv | Host, Db, User, Table_name | Table_priv (SET 型態) | 資料表 |
| columns_priv | Host, Db, User, Table_name, Column_name | Column_priv (SET 型態) | 欄位 |
權限檢查邏輯與優先序
- 先查
user 表,依 Host → User 排序:無萬用字元 > 有萬用字元 > 空值。
- 再查
db 表,依 Host → Db → User 排序。
- 若
db.Host 為空,再查 host 表合併權限(host 表不受 GRANT/REVOKE 影響)。
- 最後疊加
tables_priv、columns_priv 細粒度權限。
- 全域權限 (
user) 為基礎,資料庫/資料表/欄位權限為加法疊加。
萬用字元匹配規則
%:匹配任意字元 (含 0 字元)。
_:匹配單一字元。
- IP 可用 CIDR 表示法:
192.168.1.0/255.255.255.0。
實戰授權範例
-- 建立超級用戶
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' IDENTIFIED BY 'pass' WITH GRANT OPTION;
-- 建立唯讀帳號,限定來源 IP
GRANT SELECT ON mydb.* TO 'readonly'@'192.168.1.%' IDENTIFIED BY 'pass';
-- 撤銷權限
REVOKE INSERT ON mydb.* FROM 'readonly'@'192.168.1.%';
-- 刪除用戶
DROP USER 'readonly'@'192.168.1.%';
安全強化清單
- 刪除匿名帳號:
DELETE FROM mysql.user WHERE User='';
- 移除
Host='%' 的 root 帳號。
- 設定強制密碼策略 (validate_password 插件)。
- 最小權限原則:應用程式帳號僅授予必要資料庫的 CRUD 權限。
- 啟用
--skip-show-database 隱藏資料庫列表。