之前一直忽視了MySQL的權限這一塊的內容,以為一般般的知識點,隨時用隨時學就好了,導致自己這方面稍微有點不太明白的地方,總是踩坑,所以后來就總結一下:
1、MySQL權限系統的工作原理
1、對連接的用戶進行身份驗證,合法的用戶通過認證並建立連接。不合法的用戶拒絕連接. 2、對通過認證的合法用戶賦予相應的權限,用戶可以在這些權限范圍內對數據庫做相應的操作。
注意兩點:
1、MySQL通過IP地址和用戶名聯合進行確認的,同樣的一個用戶名如果來自不同的IP地址,MySQL則視為不同的用戶。
2、MySQL的權限在數據庫啟動的時候就載入內存了,當用戶通過身份認證后,就在內存中進行相應權限的操作。
2、權限表的存取:
”mysql“數據庫中有三個重要的權限表:
這三個表:user、host、db中,最重要的權限表是user表,其次是db表,要掌握這兩個。user標准一共分為四部分:用戶列、權限列、安全列、資源控制列。
用的最多的就是用戶列和權限列,權限列又分為普通權限和管理權限。普通權限指對數據庫的操作:如select_priv、create_priv。而管理權限指對數據庫的管理:process_priv、super_priv等。
3、當用戶通過權限認證、進行權限分配的流程是這樣子的:
1、權限分配按照user->db->tables_priv->columns_priv的順序進行權限分配,即先檢查全局權限表user,如果user中對應權限為‘Y’,則此用戶對所有的數據庫的權限都為‘Y’,此時不再檢查db、tables_priv和columns_priv這些表。
2、如果user中對應權限為‘N’,則到db表中檢查此用戶對應的具體數據庫,並得到db中為‘Y’的權限;
3、如果db中相應的權限為‘N’,則檢查table_priv中此數據庫對應的具體表,取得表中為‘Y’的權限;
4、如果tables_priv中相應權限為'N',則檢查columns_priv中此表對應的具體列,取得列中為'Y'的權限。
我們可以看個例子:

4、賬號管理
1、我們常用的授權all privileges到底有哪些權限呢?以及帶來的安全隱患有哪些?
mysql> grant all privileges on *.* to 'test'@'%' identified by '123456' ; Query OK, 0 rows affected, 1 warning (0.01 sec) mysql> select * from user where user='test'\G *************************** 1. row *************************** Host: % User: test Select_priv: Y Insert_priv: Y Update_priv: Y Delete_priv: Y Create_priv: Y Drop_priv: Y Reload_priv: Y Shutdown_priv: Y Process_priv: Y File_priv: Y Grant_priv: N References_priv: Y Index_priv: Y Alter_priv: Y Show_db_priv: Y Super_priv: Y Create_tmp_table_priv: Y Lock_tables_priv: Y Execute_priv: Y Repl_slave_priv: Y Repl_client_priv: Y Create_view_priv: Y Show_view_priv: Y Create_routine_priv: Y Alter_routine_priv: Y Create_user_priv: Y Event_priv: Y Trigger_priv: Y Create_tablespace_priv: Y account_locked: N
看得出來當授予all privileges權限的時候,除了沒有grant_priv權限和account_locked以為,其他的權限全部都有,這是非常危險的。並且還能從任意主機來登陸MySQL數據庫,在安全方面做得相當差,所以一般情況下我們最好不要這樣子設置。如果有必要的話才可以這樣做,此外我們也會見到這樣子的操作:
mysql> grant all privileges on *.* to 'test'@'%' identified by '123456' with grant option; Query OK, 0 rows affected, 1 warning (0.00 sec)
后面加上了”with grant option“參數,表示賦予grant_priv權限。那么此時這個用戶真的是擁有了超級用戶的管理權限了。在生產環境中最好慎用。
2、創建賬戶的時候最好分配指定的權限,這樣子安全也高
就像這樣子的,讓某個用戶僅對某個數據庫擁有一部分權限即可。本例中的權限適合於大多數應用賬號。不過本例中的IP是設置為所有的主機都可連接,建議還是指定特定的主機進行連接。
注意:MySQL數據庫的user表中host的值為”%“或為空,表示所有外部IP都可以連接,但是不寶庫哦本地服務器localhost,因此要包括本地服務器,必須單獨為localhost賦予權限。
3、管理權限SUPER、PROCESS、FILE權限給用戶
這三個權限要慎用給一般用戶。最好是不要把這三個權限授權給管理員以外的用戶。
我們來看一下這三個權限的作用是什么:
1)FILE權限
2)PROCESS權限
3)SUPER權限
4、除root外,任何用戶不要有mysql庫user表的操作權限
5、權限外流
6、revoke命令的漏洞
這個是說用戶被多次賦予權限,由於各種原因,需要將此用戶的權限全部取消,此時revoke命令可能並不會按照我們的意願執行。
mysql> show grants for 'test'@'%';
+-------------------------------------------------------------+
| Grants for test@% |
+-------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'test'@'%' WITH GRANT OPTION |
| GRANT ALL PRIVILEGES ON `haha`.* TO 'test'@'%' |
+-------------------------------------------------------------+
2 rows in set (0.00 sec)
此時取消這個用戶的全部權限
mysql> revoke all privileges on *.* from 'test'@'%'; Query OK, 0 rows affected (0.00 sec) mysql> show grants for 'test'@'%'; +----------------------------------------------------+ | Grants for test@% | +----------------------------------------------------+ | GRANT USAGE ON *.* TO 'test'@'%' WITH GRANT OPTION | | GRANT ALL PRIVILEGES ON `haha`.* TO 'test'@'%' | +----------------------------------------------------+ 2 rows in set (0.00 sec)
現在我們使用這個test用戶登陸MySQL查看一下是否對haha這個數據庫有操作權限。
mysql> select user(); +----------------+ | user() | +----------------+ | test@localhost | +----------------+ 1 row in set (0.00 sec) mysql> use haha Database changed mysql> insert into hehe values (1,'chaofeng'); Query OK, 1 row affected (0.00 sec)
真是沒想到居然還能操作。
所以說我們要親自取消這個才行
mysql> revoke all ON haha.* from 'test'@'%'; Query OK, 0 rows affected (0.00 sec)
mysql> show grants for 'test'@'%'; +----------------------------------------------------+ | Grants for test@% | +----------------------------------------------------+ | GRANT USAGE ON *.* TO 'test'@'%' WITH GRANT OPTION | +----------------------------------------------------+ 1 row in set (0.00 sec)
這個時候就行了。