開門見山
與其他服務軟件類似,MySQL的用戶管理用於控制不同用戶的不同權限,用以實現不同用戶的不同數據訪問需求,同時保證數據的安全性。
MySQL使用雙層驗證模式來響應用戶的連接和查詢請求,即認證Authentication和授權Authorization,具體驗證過程如下:
認證Authentication:即驗證用戶的身份。MySQL客戶端每次連接至服務器時,都需要進行認證,除非服務端開啓免認證模式。
授權Authorization:即驗證用戶的權限。MySQL對用戶的每次請求進行權限驗證,只有當用戶的相關權限驗證成功,才允許執行相關操作。
本文將就MySQL的認證Authentication進行詳細描述。
MySQL認證雜貨
- 用戶信息查看
MySQL自帶mysql數據庫中user表用於存儲用戶信息。包括用戶名user、用戶主機host(客戶端主機)、用戶權限、資源限制等。查看user表的建表語句如下:
mysql> show create table mysql.user \G;
*************************** 1. row ***************************
Table: user
Create Table: CREATE TABLE `user` (
`Host` char(60) COLLATE utf8_bin NOT NULL DEFAULT '',
`User` char(32) COLLATE utf8_bin NOT NULL DEFAULT '',
`Select_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Insert_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Update_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Delete_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Drop_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Reload_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Shutdown_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`File_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Grant_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Index_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Alter_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Show_db_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_tmp_table_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Lock_tables_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Execute_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Repl_slave_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Repl_client_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_user_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`Create_tablespace_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`ssl_type` enum('','ANY','X509','SPECIFIED') CHARACTER SET utf8 NOT NULL DEFAULT '',
`ssl_cipher` blob NOT NULL,
`x509_issuer` blob NOT NULL,
`x509_subject` blob NOT NULL,
`max_questions` int(11) unsigned NOT NULL DEFAULT '0',
`max_updates` int(11) unsigned NOT NULL DEFAULT '0',
`max_connections` int(11) unsigned NOT NULL DEFAULT '0',
`max_user_connections` int(11) unsigned NOT NULL DEFAULT '0',
`plugin` char(64) COLLATE utf8_bin NOT NULL DEFAULT 'mysql_native_password',
`authentication_string` text COLLATE utf8_bin,
`password_expired` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
`password_last_changed` timestamp NULL DEFAULT NULL,
`password_lifetime` smallint(5) unsigned DEFAULT NULL,
`account_locked` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N',
PRIMARY KEY (`Host`,`User`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='Users and global privileges'
1 row in set (0.00 sec)
- 查看所有用戶信息
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| common | % |
| root | % |
| debian-sys-maint | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
+------------------+-----------+
5 rows in set (0.00 sec)
注意:
1. user表中的host列是客戶端host名(不是server端host名),可以爲localhost(本機),可以爲%等通配符,還可以是IP地址;
2. 若客戶端與服務端爲同一主機,使用mysql連接時可以不指定服務端主機名;若客戶端與服務端不爲同一主機,則mysql連接時需要指定server端主機名或IP地址,如下:
mysql -u<username> -p<password> -h<server_host>
- Creating a User Account創建用戶賬戶
MySQL使用CREATE USER...IDENTIFIED BY語句來創建相關賬戶信息,如下:
MySQL [192.168.124.12] SQL> create user 'common'@'%' identified by 'common';
Query OK, 0 rows affected (0.0523 sec)
注意:
- 賬戶名包含用戶名和用戶主機兩部分,分別通過單引號包圍;
- 從MySQL8.0.4開始,創建用戶時默認的密碼認證插件從之前的mysql_native_password修改爲caching_sha2_password,所以若需要使用如上原始密碼驗證,需要修改創建語句如下:
create USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密碼';
- Host Name Patterns主機名模式
MySQL支持豐富主機名格式,包括hostname(如localhost)、Qualified host name(如localhost.example.com)、IP地址/掩碼、通配符(’%’、‘_’)等。其中通配符’%’匹配任意長度字符串、通配符’_’匹配單個字符;
此外,可創建匿名的MySQL用戶,如下:
mysql> CREATE USER ''@'localhost';
注意:5.7.24-0ubuntu0.16.04.1-log版本創建匿名用戶後,導致有名用戶不能用。具體原因不明。
- 設置/修改用戶密碼
官方推薦使用alter user XXX語句修改用戶密碼,如下:
alter user 'root'@'localhost' IDENTIFIED BY 'root';
若因爲忘記密碼採用skip-grant-tables選項啓動的mysqld守護進程,直接執行此命令可能會報錯,如下:
需要先flush privileges;刷新權限系統相關表。
- 強制使密碼到期
DBA在某些場合可以強制使應用用戶密碼到期,如下:
ALTER USER 'common'@'%' PASSWORD EXPIRE;
到期後的用戶還是可以登錄到mysql,只是不能執行任何操作,如下:
- 其他
MySQL還支持其他插件模塊進行認證授權,如Linux系統的PAM(Pluggable Authentication Modules)認證,此認證方式下,MySQL本身並不存儲用戶密碼信息,而是使用OS的認證機制對密碼進行認證。同時,客戶端也是用使用mysql_clear_password實現用戶密碼的純文本發送,如:
jwlLinux jwllinux # cat /etc/mysql/conf.d/mysql.cnf
[client]
enable-cleartext-plugin
# add by zavier 20190720
user=root
password=root
show-warnings
總結
MySQL的所有的用戶認證/授權都記錄在mysql.user表中,合理的配置用戶認證方式與權限是DBA的主要職責之一。合理的用戶認證/授權可防止應用用戶非故意的破壞操作,也可防止惡意用戶的非法破壞。