MySQL 權限 = 主機 + 用戶 二元組唯一識別。root@localhost ≠ root@192.168.1.%。所有授權資訊儲於 mysql 系統庫三張表:
user:全域權限(基線)。db:庫級權限。host:輔助 db 表,定義「安全主機清單」。| 表 | 主鍵 | 關鍵權限欄位 |
|---|---|---|
user | (Host, User) | Select_priv, Insert_priv, ..., File_priv, Process_priv, Super_priv |
db | (Host, Db, User) | Select_priv, Insert_priv, ..., Create_priv, Drop_priv |
host | (Host, Db) | 同 db,但僅在 db.Host 為空時生效 |
密碼欄位 Password **必須**用 PASSWORD('plain') 加密儲存,明文會導致認證失敗。
Host(無通配符 → 有通配符 → 空)再按 User 同序排序,取第一匹配行作為 GlobalPriv。Host 同序排序,取第一匹配行作為 DbPriv。db.Host 為空,且 GlobalPriv.Host 在 host 表中 → EffectivePriv = GlobalPriv | host_privs。EffectivePriv = GlobalPriv | DbPriv(布林 OR)。需求:用戶 custom,密碼 stupid,允許從 localhost、server.domain、whitehouse.gov 連線;bankaccount 僅限 localhost 存取;customers 三主機皆可。
INSERT INTO user (Host,User,Password) VALUES
('localhost','custom',PASSWORD('stupid')),
('server.domain','custom',PASSWORD('stupid')),
('whitehouse.gov','custom',PASSWORD('stupid'));
INSERT INTO db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv) VALUES
('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y'),
('%','customers','custom','Y','Y','Y','Y','Y','Y');
FLUSH PRIVILEGES;
mysql_install_db 初始化授權表?mysql -u root mysql 進入系統庫?FLUSH PRIVILEGES 或 mysqladmin reload?--skip-grant-tables 啟動?PASSWORD() 加密?-ppass 無空格?User='')。DELETE FROM user WHERE User='root' AND Host!='localhost';。FILE、PROCESS、SUPER、SHUTDOWN 給應用帳號。--skip-name-resolve,授權表只存 IP/localhost。--skip-networking 僅允許 Unix Socket。--secure 驗證 IP 一致性(但會阻擋 NAT 環境)。