資料控制語言(Data Control Language, DCL)用於使用者許可權的管理,包括了GRANT與REVOKE命令。
授權(GRANT)
MySQL有很精細的許可權控制:
伺服器級 ----> DB級 -----------> 表 -----------------> 列 ------------------>物件,儲存過程,檢視等
mysql.user mysql.db mysql.tables_priv mysql.columns_priv mysql.procs_priv
一、授權:
#複製賬戶
create user 'repl'@'172.17.73.%' identified by 'L"04)-Xd*~2/%T';
grant replication slave,replication client on *.* to 'repl'@'172.17.73.%';
#應用賬戶
create user 'xxx'@'172.17.73.%' identified by 'R75,CI8#u[>w9j';
grant select,insert,update,delete,create,create temporary tables,execute,show view,index,create,alter on test.* to 'xxx'@'172.17.73.%';
grant select on mysql.proc to 'xxx'@'172.17.73.%';
#監控賬戶
create user 'monitor'@'localhost' identified by 'mVWp~09K!h#s';
grant select,super,process,show databases,replication slave,replication client on *.* to 'monitor'@'localhost';
#備份賬戶
create user 'backup'@'localhost' identified by 'd*CRK$AZVr2t+{';
grant select,reload,super,replication slave,replication client,show view,alter routine,event,trigger on *.* to 'backup'@'localhost';
#xtrbackup
create user 'xtrbackup'@'localhost' identified by '[{ehE!)w:0xpL8';
grant select,reload,lock tables,PROCESS,replication slave,replication client on *.* to 'xtrbackup'@'localhost';
#中介軟體賬號maxscale許可權
CREATE USER 'maxscale'@'172.17.73.%' identified by 'Oracle_123';
GRANT SELECT on mysql.user to 'maxscale'@'172.17.73.%';
GRANT SELECT ON mysql.db TO 'maxscale'@'172.17.73.%';
GRANT SELECT ON mysql.tables_priv TO 'maxscale'@'172.17.73.%';
GRANT SHOW DATABASES ON *.* TO 'maxscale'@'172.17.73.%';
GRANT REPLICATION SLAVE, REPLICATION CLIENT,SELECT ON *.* TO maxscale@'172.17.73.%';
flush PRIVILEGES;
#開發賬戶
create user 'dev'@'%' identified by 'X0WMbwPrYD';
grant select on test.* to 'dev'@'%';
相容工具或JDBC特性:
grant select on mysql.help_topic to 'xxx'@'172.17.73.%';
grant select on mysql.proc to 'xxx'@'172.17.73.%';
修改使用者名稱:
rename user OLD_NAME to NEW_NAME;
----------------------
修改密碼:
alter user 'root'@'%' identified by '12345678';
也可以:
#新版本5.7MYSQL修改密碼:
update mysql.user set authentication_string=password('zabbix') where user='zabbix';
mariadb及5.6以下:
update mysql.user set password=password('zabbix') where user='zabbix';
修改認證外掛:
ALTER USER 'root'@'%' IDENTIFIED WITH sha256_password BY 'pwd'; 指定認證外掛
update user set plugin='mysql_native_password' where user = 'root' and host = '%';
MySQL 8.0 中,caching_sha2_password 是預設的身份驗證外掛,預設的密碼加密方式是 SHA2。
需要修改my.cnf 中配置項並重啟服務後生效。此選項暫不支援 MySQL 8.0 動態修改特性。
[mysqld]
default_authentication_plugin = mysql_native_password
MySQL 8.0 中已有的 SHA2 密碼修改為 SHA1 的模式。
mysql> ALTER USER 'root'@'127.0.0.1' IDENTIFIED WITH mysql_native_password BY 'password';
mysql> FLUSH PRIVILEGES;
認證中大小寫敏感。
欄位user,password,authencation_string,db,table_name大小寫敏感
欄位host,column_name,routine_name大小寫不敏感
刪除使用者
mysql> drop user 'test'@'localhost';
Query OK, 0 rows affected (0.00 sec)
二、檢視許可權
(1)檢視所有使用者
mysql> select host,user,plugin,authentication_string,password_expired,password_lifetime,account_locked from mysql.user;
+-----------+-------------------+----------------------------------+-------------------------------------------+----------------------------+-------------------+----------------+
| host | user | plugin | authentication_string | password_expired | password_lifetime | account_locked |
+-----------+-------------------+---------------------------------+--------------------------------------------+----------------------------+-------------------+----------------+
| localhost | root | mysql_native_password | | N | NULL | N |
| localhost | mysql.session | mysql_native_password | *THISISNOTAVALIDPASS.... | N | NULL | Y |
| localhost | mysql.sys | mysql_native_password | *THISISNOTAVALIDPASSW | N | NULL | Y |
+-----------+--------------------+---------------------------------+---------------------------------------------+------------------+-------------------+----------------+
認證外掛 密碼加密字串 密碼是否過期 密碼過期時間 賬號登入是否鎖定
(2)檢視使用者的許可權
mysql> show grants for 'root'@'localhost';
+---------------------------------------------------------------------+
| Grants for root@localhost |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
| GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+
2 rows in set (0.02 sec)
user表中host列的值的意義
% 匹配所有主機
localhost localhost不會被解析成IP地址,直接透過UNIXsocket連線
127.0.0.1 會透過TCP/IP協議連線,並且只能在本機訪問;
::1 ::1就是相容支援ipv6的,表示同ipv4的127.0.0.1
(3)忘記root密碼,處理辦法
[root@vm00 ~]# /etc/init.d/mysqld --skip-grant-tables
忽略許可權表啟動。(不檢驗許可權)
Mysql –uroot mysql
更新root密碼:
UPDATE user SET Password=PASSWORD('mysql') where USER='root';
或者:
set password for 'root'@'%' = Password('mysql')
新版本5.7MYSQL修改密碼:
update mysql.user set authentication_string=password('mysql') where user='mysql';
FLUSH PRIVILEGES;
=====================================MySQL 角色管理
MySQL 8.0 角色是指定的許可權集合,和使用者帳戶一樣可以對角色進行許可權的授予和撤消。如果使用者被授予角色許可權,則該使用者擁有該角色的許可權。
(1)MySQL 8.0 提供的角色管理功能如下:
CREATE ROLE 角色建立
DROP ROLE 角色刪除
GRANT 為使用者和角色分配許可權
REVOKE 為使用者和角色撤銷許可權
SHOW GRANTS 顯示使用者和角色的許可權
SET DEFAULT ROLE 指定哪些帳戶角色預設處於活動狀態
SET ROLE 更改當前會話中的活動角色
CURRENT_ROLE() 顯示當前會話中的活動角色
為了清楚區分角色的許可權,建議將角色名稱命名得比較直觀。
mysql> CREATE ROLE 'app', 'dba', 'dev_read';
注:角色名稱格式類似於由使用者和主機部分組成的使用者帳戶,如:role_name@host_name。如果省略主機部分,則預設為 “%”,表示任何主機。
給角色授予對應的許可權。
mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON wordpress.* TO 'app';
mysql> GRANT ALL PRIVILEGES ON wordpress.* TO 'dba';
mysql> GRANT SELECT ON wordpress.* TO 'dev_read';
給使用者分配角色
mysql> GRANT app TO 'app01'@'%';
mysql> GRANT ops TO 'ops01'@'%';
mysql> GRANT dev_read TO 'dev01'@'%';
如果要將多個使用者同時加入多個角色,可以使用類似語句。
mysql> GRANT dev_read, dev_write TO 'dev02'@'%', 'dev03'@'%';
ALL [PRIVILEGES]表示除了GRANT OPTION和PROXY許可權外,授予許可權級別的所有可用許可權。
(2)檢視使用者許可權:
mysql> SHOW GRANTS FOR 'dev01'@'%';
+-------------------------------------+
| Grants for dev01@% |
+-------------------------------------+
| GRANT USAGE ON *.* TO `dev01`@`%` |
| GRANT `dev_read`@`%` TO `dev01`@`%` |
+-------------------------------------+
2 rows in set (0.00 sec)
如果要顯示角色所代表的許可權,需要加上 USING 子句和授權角色的名稱。
mysql> SHOW GRANTS FOR 'dev01'@'%' USING dev_read;
+----------------------------------------------+
| Grants for dev01@% |
+----------------------------------------------+
| GRANT USAGE ON *.* TO `dev01`@`%` |
| GRANT SELECT ON `wordpress`.* TO `dev01`@`%` |
| GRANT `dev_read`@`%` TO `dev01`@`%` |
+----------------------------------------------+
3 rows in set (0.00 sec)
(3)設定預設角色
向使用者帳戶授予角色後,當使用者帳戶連線到資料庫伺服器時,它並不會自動使角色變為活動狀態。
#檢視當前角色。
mysql> SELECT current_role();
+----------------+
| current_role() |
+----------------+
| NONE |
+----------------+
1 row in set (0.00 sec)
要在每次使用者帳戶連線到資料庫伺服器時指定哪些角色應該處於活動狀態,需用使用 SET DEFAULT ROLE 語句來指定。
# 以下語句將把 dev01 帳戶分配的所有角色都設定為預設值。
mysql> SET DEFAULT ROLE ALL TO 'dev01'@'%';
使用者帳戶可以透過指定哪個授權角色處於活動狀態來修改當前使用者在當前會話中的有效許可權。
將活動角色設定為 NONE,表示沒有活動角色。
mysql> SET ROLE NONE;
將活動角色設定為所有授予的角色。
mysql> SET ROLE ALL;
將活動角色設定為由 SET DEFAULT ROLE 語句設定的預設角色。
mysql> SET ROLE DEFAULT;
同時設定多個活動的角色。
mysql> SET ROLE granted_role_1, granted_role_2, ...
(4)撤消角色或角色許可權
正如可以授權某個使用者的角色一樣,也可以從使用者帳戶中撤銷這些角色。
mysql> REVOKE role FROM user;
從 dev_write 角色中撤消掉修改許可權。
REVOKE INSERT, UPDATE, DELETE ON wordpress.* FROM 'dev_write';
角色中撤銷許可權會影響到該角色中任何使用者的許可權。
刪除角色:
DROP ROLE 'role_name', 'role_name', ...;
刪除角色會從授權它的每個帳戶中撤消該角色。
(5)克隆許可權
MySQL 8.0 將每一個使用者帳戶視為角色,因此可以將使用者帳戶授予另一個使用者帳戶。例如:將一開發人員帳號許可權複製到另一開發人員帳號。
將 dev02 使用者帳戶的許可權複製到 dev04 使用者帳戶
mysql> GRANT 'dev02'@'%' TO 'dev04'@'%';
三、回收許可權,密碼過期時間管理,鎖定賬號
revoke跟grant的語法差不多,只需要把關鍵字 “to” 換成 “from” 即可;
mysql> revoke delete on *.* from 'test'@'localhost';
(2)密碼過期時間管理
default_password_lifetime 其預設值為 0,表示禁用自動密碼過期。
default_password_lifetime 的值如是是正整數 N ,則表示允許的設定密碼生存週期 為 N,單位為天 。
如果你要建立一個全域性策略,讓所有使用者的密碼的使用期限為六個月。
[mysqld]
default_password_lifetime=180
也可以設定預設密碼過期策略為 180 天后過期
mysql> SET PERSIST default_password_lifetime = 180;
# 設定預設密碼過期策略為永不過期
mysql> SET PERSIST default_password_lifetime = 0;
# MySQL 8.0 永久動態修改引數會儲存在配置檔案 mysqld-auto.cnf 中,儲存的格式為JSON串。
$ cat /var/lib/mysql/mysqld-auto.cnf
{ "Version" : 1 , "mysql_server" : { "default_password_lifetime" : { "Value" : "180" , "Metadata" : { "Timestamp" : 1525663928688419 , "User" : "root" , "Host" : "" } } } }
建立或修改一個使用者的密碼過期時間為 90 天。
mysql> CREATE USER 'mike'@'%' IDENTIFIED BY '000000' PASSWORD EXPIRE INTERVAL 90 DAY;
mysql> ALTER USER `mike`@`%` PASSWORD EXPIRE INTERVAL 90 DAY;
建立或修改一個使用者的密碼過期時間為永不過期。
mysql> CREATE USER 'mike'@'%' PASSWORD EXPIRE NEVER;
mysql> ALTER USER 'mike'@'%' PASSWORD EXPIRE NEVER;
建立或修改一個遵循全域性到期策略的使用者。
mysql> CREATE USER 'mike'@'%' PASSWORD EXPIRE DEFAULT;
mysql> ALTER USER 'mike'@'%' PASSWORD EXPIRE DEFAULT;
(3)鎖定管理
建立一個帶帳戶鎖的使用者
mysql> CREATE USER 'mike-temp1'@'%' IDENTIFIED BY '000000' ACCOUNT LOCK;
鎖定使用者:
ALTER USER 'mike'@'%' ACCOUNT LOCK;
解鎖此使用者
mysql> ALTER USER 'mike-temp1'@'%' ACCOUNT UNLOCK;
(4)密碼重用
從 MySQL 8.0 開始允許限制重複使用以前的密碼。可以根據密碼更改次數、已用時間或兩者來建立密碼重用限制。
如果根據密碼更改次數限制帳戶,則無法從指定數量的最新密碼中選擇新密碼。例如:如果密碼更改的最小數量設定為 3,則新密碼不能與任何最近的3個密碼相同。
如果根據密碼修改時間來限制帳戶,則無法將指定時間歷史記錄中的密碼中選擇為新密碼。例如:如果密碼重用間隔設定為 60,則新密碼不得在最近 60 天內選擇的密碼相同。
注:空密碼不記錄在密碼歷史記錄中,並隨時可以重複使用。
要建立全域性密碼重用策略,可修改 password_history 和 password_reuse_interval 系統變數。
禁止重複使用最近 6 個密碼或最近 180 天內使用過的任何密碼為例。
[mysqld]
password_history=6
password_reuse_interval=180
該引數是支援永久動態設定,也可以直接用下面語句進行設定。
mysql> SET PERSIST password_history = 6;
mysql> SET PERSIST password_reuse_interval = 180;
四、密碼3種檢驗策略
mysql對於密碼有3種檢驗策略,預設validate_password_policy為MEDIUM。
LOW :僅僅驗證密碼長度,至少8個字元。
MEDIUM 在low基礎上,密碼必須至少包含1個數字字元、1個小寫和大寫字元以及1個特殊(非字母數字)字元。
STRONG :長度為4或更長的密碼子字串不能與單詞匹配。
如果需要密碼校驗,需要安裝外掛:
mysql> INSTALL PLUGIN validate_password SONAME 'validate_password.so';
檢驗密碼複雜度
mysql> select VALIDATE_PASSWORD_STRENGTH('abc1235jeme');
+-------------------------------------------+
| VALIDATE_PASSWORD_STRENGTH('abc1235jeme') |
+-------------------------------------------+
| 50 |
+-------------------------------------------+
修改密碼策略:
SHOW VARIABLES LIKE 'validate_password%';
validate_password_number_count 引數是密碼中至少含有的數字個數,當密碼策略是MEDIUM或以上時生效。
validate_password_special_char_count 引數是密碼中非英文數字等特殊字元的個數,當密碼策略是MEDIUM或以上時生效。
validate_password_mixed_case_count 引數是密碼中英文字元大小寫的個數,當密碼策略是MEDIUM或以上時生效。
validate_password_length 引數是密碼的長度,這個引數由下面的公式生成
validate_password_number_count+ validate_password_special_char_count+ (2 * validate_password_mixed_case_count)
validate_password_dictionary_file 引數是指定密碼驗證的字典檔案路徑。
validate_password_policy 這個引數可以設為0、1、2,分別代表從低到高的密碼強度,此引數的預設值為1,如果想將密碼強度改弱,則更改此引數為0。
更改密碼策略為LOW
mysql> set global validate_password_policy=0;
更改密碼長度
mysql> set global validate_password_length=0;
/etc/my.cnf配置檔案中也可開啟或關閉相關密碼策略
[mysqld]
validate_password=off
五、MySQL支援的許可權
ALL或ALL PRIVILEGES 代表指定許可權等級的所有許可權。
ALTER 允許使用ALTER TABLE來改變表的結構,ALTER TABLE同時也需要CREATE和INSERT許可權。
重新命名一個表需要對舊錶具有ALTER和DROP許可權,對新表具有CREATE和INSERT許可權。
ALTER ROUTINE 允許改變和刪除儲存過程和函式
CREATE 允許建立新的資料庫和表
CREATE ROUTINE 允許建立儲存過程和包
CREATE TABLESPACE 允許建立、更改和刪除表空間和日誌檔案組
CREATE TEMPORARY TABLES 允許建立臨時表
CREATE USER 允許更改、建立、刪除、重新命名使用者和收回所有許可權
CREATE VIEW 允許建立檢視
DELETE 允許從資料庫的表中刪除行
DROP 允許刪除資料庫、表和檢視
EVENT 允許在事件排程裡面建立、更改、刪除和檢視事件
EXECUETE 允許執行儲存過程和包
FILE 允許在伺服器的主機上透過LOAD DATA INFILE、SELECT ... INTO OUTFILE和LOAD_FILE()函式讀寫檔案
GRANT OPTION 允許向其他使用者授予或移除許可權
INDEX 允許建立和刪除索引
INSERT 允許向資料庫的表中插入行
LOCK TABLE 允許執行LOCK TABLES語句來鎖定表
PROCESS 允許顯示在伺服器上執行的執行緒資訊,即被會話所執行的語句資訊。
這個許可權允許你執行SHOW PROCESSLIST和mysqladmin processlist命令來檢視執行緒,同時這個許可權也允許你執行SHOW ENGINE命令。
PROXY 允許使用者冒充成為另外一個使用者
REFERENCES 允許建立外來鍵
RELOAD 允許使用FLUSH語句
REPLICATION CLIENT 允許執行SHOW MASTER STATUS,SHOW SLAVE STATUS和SHOW BINARY LOGS命令
REPLICATION SLAVE 允許SLAVE伺服器連線到當前伺服器來作為他們的主伺服器。
SELECT 允許從資料庫中查詢表
SHOW DATABASES 允許賬戶執行SHOW DATABASE語句來檢視資料庫。沒有這個許可權的賬戶只能看到他們具有許可權的資料庫。
SHOW VIEW 允許執行SHOW CREATE VIEW語句
SHUTDOWN 允許執行SHUTDOWN語句和mysqladmin shutdown已經mysql_shutdown() C API函式
SUPER 允許使用者執行CHANGE MASTER TO,KILL或mysqladmin kill命令來殺掉其他使用者的執行緒,允許執行PURGE BINARY LOGS命令,
透過SET GLOBAL來設定系統引數,執行mysqladmin debug命令,開啟和關閉日誌,即使read_only引數開啟也可以執行update語句,
開啟和關閉從伺服器上面的複製,允許在連線數達到max_connections的情況下連線到伺服器。super許可權可以對全域性變數更改。
TRIGGER 允許操作觸發器
UPDATE 允許更新資料庫中的表
USAGE 代表沒有任何許可權,只能登陸