權限系統介紹
- 權限系統的作用是授予來自某個主機的某個用戶可以查詢、插入、修改、刪除等數據庫操作的權限。
- 不能明確的指定拒絕某個用戶的連接。
- 權限控制(授權與回收)的執行語句包括create user, grant, revoke
- 授權后的權限都會存放在Mysql的內部數據庫中(數據庫名叫mysql),並在數據庫啟動之后把權限信息復制到內存中,這就是為什么授權完以后需要運行
flush Privileges
- mysql用戶認證信息不光包括用戶,還要包含連接發起的主機,比如以下兩個就是不同的用戶
5.1. 'ljf'@'example1.node.com'
5.2. 'ljf'@'example2.node.com'
權限級別介紹
- 全局性的管理權限,作用於整個Mysql實例級別。
- 數據庫級別的權限,作用於某個指定的數據庫上或者所有的數據庫上。
- 數據庫對象級別的權限,作用於指定的數據庫對象上(表、視圖等) 或者所有的數據庫對象上。
權限存儲在mysql庫的user,db,tables_priv,columns_priv,procs_priv這幾個系統表中,待mysql實例啟動后就加載到內存中。
Mysql權限級別介紹
查看mysql實例默認root用戶的權限(來自localhost)
mysql> show grants for root@localhost\G;
too many records ............
mysql> select * from db where user='root' and host='localhost';
Empty set (0.00 sec)
mysql> select * from tables_priv where user='root' and host='localhost';
Empty set (0.00 sec)
mysql> select * from columns_priv where user='root' and host='localhost';
Empty set (0.00 sec)
mysql> select * from procs_pr
Mysql權限詳解
- All/All Privileges 權限代表全局或者全數據庫對象級別的所有權限。
- Alter權限代表允許修改表結構的權限,但必須要求有create和insert權限配合。如果是rename表名,則要求有alter和drop原表,create和insert新表的權限。
- Alter routine權限代表允許修改或者刪除存儲過程、函數的權限。
- Create權限代表允許創建新的數據庫和表權限。
- Create routine權限代表允許創建存儲過程、函數的權限。
- Create table 權限代表允許創建、修改、刪除表空間和日志組的權限。
- Create temporary table權限代表允許創建臨時表的權限。
- Create user權限代表允許創建、修改、刪除、重命名user的權限。
- Create view權限代表允許創建視圖的權限。
- Delete權限代表允許刪除行數據的權限。
- Drop權限代表允許闡述數據庫、表、視圖的權限,包括truncate table命令。
- Event權限代表允許查詢,創建,修改刪除Mysql事件。
- Execute 權限代表允許執行存儲過程和函數的權限。
- File權限代表允許在Mysql可以訪問的目錄進行讀寫磁盤文件操作,可以使用的命令包括load data infile,select .... into outfile, load file() 函數。
- Grant option權限代表是否允許此用戶授權或者收回給其他用戶你給予的權限。
- Index權限代表是否允許創建和刪除索引。
- Insert權限代表是否允許在表里插入數據,同時在執行analyze table,optimize table , repair table語句的時候也需要insert權限。
- Lock權限代表允許對擁有select權限的表進行鎖定,以防止其他鏈接對此表的讀或者寫。
- Process權限代表允許查看Mysql進程信息,比如執行 show processlist,mysqladmin processlist, show engine 等命令
- Reference權限是在5.7.6版本之后引入的,代表是否允許創建外鍵。
- Reload權限代表允許執行flush命令,指明重新加載權限表到系統內存中,refresh命令代表關閉和重新開啟日志文件並刷新所有的表。
- Replication client權限代表允許執行show master status,show slave status,show binary logs命令。
- Replication slave 權限代表允許slave主機通過此用戶連接master以便建立主從復制關系。
- Select權限代表允許重表中查看數據,某些不查詢表數據的select執行則不需要此權限,如Select1+1,select PI()+2;而且select權限在執行update、delete語句中含有where條件的情況下也是需要的。
- show databases權限代表通過執行show databases命令查看所有的數據庫名。
- show view權限代表通過執行show create view 命令查看視圖創建的語句。
- shutdown 權限代表允許關閉數據庫實例,執行語句包括mysqladmin shutdown
- super權限代表允許執行一系列數據庫管理命令,包括kill強制關閉某個連接命令,change master to 創建賦值關系的命令,以及create/alter/drop server等命令。
- Trigger權限表允許創建,刪除,執行,顯示觸發器的權限。
- Update權限表允許修改表中的數據權限。
- Usage權限是創建一個用戶之后的默認權限,其本身代表連接登錄的權限。
mysql> create user abc@localhost identified by '123456';
Query OK, 0 rows affected (0.07 sec)
mysql> show grants for abc@localhost;
+-----------------------------------------+
| Grants for abc@localhost |
+-----------------------------------------+
| GRANT USAGE ON *.* TO `abc`@`localhost` |
+-----------------------------------------+
1 row in set (0.00 sec)
系統權限表
權限存儲在mysql庫的user,db,tables_priv,columns_priv, procs_priv這幾個系統表中,待mysql啟動后加載到內存中。
- user表,存放用戶賬戶信息以及全局級別(所有數據)權限,決定了來自哪些主機的那些用戶可以訪問數據庫實例,如果有全局權限則意味着對所有的數據都有此權限。
- DB表:存放數據庫級別的權限,決定了來自哪些主機的哪些用戶可以訪問此數據庫。
- Tables_priv表,存放表級別的權限,決定了來自哪些主機的哪些用戶可以訪問這數據庫的表。
- Columns_priv表:存放列級別的權限,決定了來自哪些主機的哪些用戶可以訪問數據庫的這個字段。
- procs_priv表:存放存儲過程和函數級別的權限。
User表重要字段解釋
- Plugin,password,authentication_string三個字段存放用戶認證信息
- password_expired設置為Y則表明允許DBA將此用戶的密碼設置為過期而且過期后要求用戶的使用者重置密碼(alter user/set password 來重置)
- password_last_changed作為一個時間戳字段代表密碼上次修改時間,執行create user/alter user /set password / grant等命令創建用戶或者修改用戶密碼時此數值更新。
- password_lifetime代表從password_last_changed時間開始此密碼過期的天數。
- account_locked代表此用戶被鎖定,無法使用。
procs_priv權限表結構
routine_type是代表存儲過程還是函數的類型
系統權限表
- user,password,authencation_string,db,table_name大小寫敏感
- host,column_name,routine_name大小寫不敏感。
舉個例子:
create user ABC@localhost identified by '123456';
create user abc@localhost identified by '123456';
上面是創建了2個用戶。
create user abc@localhost identified by '123456';
create user abc@Localhost identified by '123456';
上面兩條命令還是同一個用戶同一個主機。
授權用戶與查看用戶權限
查看權限
mysql> show grants for abc@localhost;
+-----------------------------------------+
| Grants for abc@localhost |
+-----------------------------------------+
| GRANT USAGE ON *.* TO `abc`@`localhost` |
+-----------------------------------------+
1 row in set (0.00 sec)
mysql> show create user root@localhost;
'''''省略1W字
授權用戶。
- mysql的授權用戶由兩部分組成,用戶名和登錄主機。
- 表達用戶的語法為'username'@'hostname'
- 單引號不是必須的,但是如果其中包含特殊字符則是必須的
- ''@'localhost'代表匿名登錄的用戶
- hostname可以使用ipv4和ipv6的主機,::1代表ipv6的主機。
- hostname字段運行使用%匹配字符,比如'%s'代表所有的主機,'%.node.com'代表來自node.com這個域名下的所有主機。''192.168.1.%'表示這個192.168.1的所有網段,也可以寫成'192.168.10%'
具體含義參考下表:
修改權限后生效
- 執行grant,revoke,set password,rename user命令修改權限之后,mysql會自動將修改后的權限信息同步加載到系統內存中。
- 如果將執行insert/update/delete操作上述的系統權限表之后,則必須再執行刷新權限命令才能同步到系統內存中,刷新權限命令包括:flush privileges/mysqladmin flush-privileges / mysqladmin reload
- 如果是修改tables和columns級別的權限,則客戶端的下次操作新權限就會生效。
- 如果是修改database級別的權限,則新權限會在客戶端執行use database命令后生效,如果是修改global級別的權限,則需要重新創建連接(也就是重連),新的權限才會生效。
- --skip-grant-tables可以跳過所有的系統權限表而允許所有的用戶登錄,旨在特殊情況下臨時使用。
使用mysql
連接mysql
- mysql -uroot -p mysql
- mysql --user=root --password=xxx mysql
創建mysql用戶並授權
創建mysql用戶由兩種方式,
- 通過create user/grant命令
- 通過insert語句直接操作Mysql系統權限表。
例一:
mysql> create user 'abc1'@localhost identified by '123456' ;
mysql> grant all privileges on *.* to 'abc1'@'localhost' with grant option;
例二:
mysql> create user 'abc2'@'%' identified by '123456';
mysql> grant all privileges on *.* to 'abc2'@'%' with grant option;
例三:
mysql> create user 'abc3'@'localhost' identified by '123456';
mysql> grant reload,process on *.* to 'abc3'@'localhost';
mysql> grant select(id) on test.tmp to abc3@localhost;
例四:
mysql> create user 'custom'@'example1.node.com' identified by '123456';
Query OK, 0 rows affected (0.12 sec)
mysql> grant select,insert,update,delete,create,drop on test.tmp to custom@'example1.node.com' ;
回收用戶權限
通過revoke來回收用戶權限,語法如下:
revoke 權限名 on 庫名.表名 from 用戶名@主機名
例子一:
mysql> show grants for custom@'example1.node.com';
+----------------------------------------------------------------------------------------------------+
| Grants for custom@example1.node.com |
+----------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `custom`@`example1.node.com` |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP ON `test`.`tmp` TO `custom`@`example1.node.com` |
+----------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
mysql> revoke delete on test.tmp from custom@'example1.node.com'; #剔除delete權限
Query OK, 0 rows affected (0.10 sec)
mysql> show grants for custom@'example1.node.com';
+--------------------------------------------------------------------------------------------+
| Grants for custom@example1.node.com |
+--------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `custom`@`example1.node.com` |
| GRANT SELECT, INSERT, UPDATE, CREATE, DROP ON `test`.`tmp` TO `custom`@`example1.node.com` | # delete權限消除啦!
+--------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
刪除用戶
通過drop來刪除用戶。語法如下
drop user 用戶名@主機名
例子1
mysql> drop user 'custom'@'example1.node.com';
Query OK, 0 rows affected (0.02 sec)
設置mysql用戶資源限制
- max_user_connections限制所有用戶在同一實際連接mysql實例的數量。通過設置max_user_connections可以限制所有用戶在同一實際連接Mysql的實例的數量,但是此參數無法對每個用戶區別對待,所以Mysql提供了每個用戶的資源限制管理。
- max_queries_per_hour,一個用戶在一個小時內可以執行查詢的次數(基本包含了所有的語句)。
- max_update_per_hour,一個用戶在一個小時內可以執行修改的次數(僅僅包含修改數據庫或者表的語句)
- max_connections_per_hour,一個用戶在一個小時內可以連接mysql的時間。
- max_user_connections ,一個用戶在同一個時間連接mysql實例的數量。
如果不想對某個用戶進行限制了,直接把對應的值改為0即可。
ps:
- 從5.0.3版本開始,對用戶'user'@'%.example.com'的資源限制是指所有通過example.com域名主機連接user用戶的連接,而不是分別從host1.example.com和host2.example.com的主機過來的連接。
- 當針對某個用戶的max_user_connections非0時,則忽略全局系統參數max_user_connections,反之則全局系統參數生效。
開始設置用戶資源限制。
- 創建用戶時進行限制。
mysql> create user 'abc4'@'localhost' identified by '123456' with max_queries_per_hour 20
-> max_updates_per_hour 10
-> max_connections_per_hour 3
-> max_user_connections 2;
- 更改用戶的資源限制。
更改后可以通過show create user
來查看詳細信息。
mysql> alter user 'abc4'@'localhost' with MAX_QUERIES_PER_HOUR 3;
設置mysql用戶的密碼
alter user 'abc4'@'localhost' identified by 'abc4';
- 使用grant和set password在mysql8.0新版不好使了。
設置mysql用戶密碼過期策略
設置系統參數default_password_lifetime作用於所有的用戶賬戶
- default_password_lifetime=180 設置180天過期
- default_password_lifetime=0 設置0天過期
如果為每個用戶設置了密碼過期策略,則會覆蓋上述系統參數。
alter user 'abc1'@'localhost' password expire interval 90 day;
90天過期時間alter user 'abc3'@'localhost' password expire default;
默認過期策略alter user 'abc1'@'localhost' password expire never;
密碼不過期
手動強制某個用戶密碼過期
alter user 'abc1'@'localhost' password expire;
設置完成后,我們切換用戶登錄試試看效果
[root@linux-node2 ~]# mysqladmin -uabc3 -hlocalhost password '123456' -p
mysql> select 1+2;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
修改密碼后看看效果
mysql> alter user user() identified by '123456';
Query OK, 0 rows affected (0.21 sec)
# 切換到另一個終端,使用剛才abc3用戶的連接
mysql> select 1+2
-> ;
+-----+
| 1+2 |
+-----+
| 3 |
+-----+
1 row in set (0.08 sec)
mysql 用戶鎖定
通過執行create user/alter user 命令中帶account locak/unlock子句設置用戶的lock狀態。
- create user的時候鎖定
create user abc5@localhost identified by '123456' account lock;
- alter user的時候鎖定
mysql> alter user 'abc2'@localhost account lock;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
請注意,如果報上面的錯誤(錯誤代碼為1819),請檢查這個用戶是否存在。
mysql> alter user 'abc3'@localhost account lock; # 存在就會更改成功
Query OK, 0 rows affected (0.09 sec)