前言
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。
在学习这一章节的时候,我们可以先了解一下【数据库原理 • 五】数据库安全性与完整性的定义
和【数据库原理 • 三】关系数据库标准语言SQL的概念和发展历史
当我们连接mysql的时候
服务首先检查凭据,然后检查账户的锁定状态。任一步骤失败都会拒绝访问,没有问题就接收连接。锁定状态记录在user表account_locked列中。
mysql> select user,account_locked from user;
+--------+----------------+
| user | account_locked |
+--------+----------------+
| root | N |
| multis | N |
| multis | N |
| root | N |
+--------+----------------+
4 rows in set (0.00 sec)
下表显示了如何将各种的组合User和Host值在 user表适用于传入的连接
User | Host | 允许的连接 |
---|---|---|
‘fred’ | h1.example.net | 来自h1.example.net的fred |
‘’ | ‘h1.example.net’ | 来自h1.example.net的任何用户 |
‘fred’ | ‘%’ | 任何主机的fred |
‘’ | ‘’ | 任何主机的任何用户 |
‘fred’ | ‘%.example.net’ | 从example.net的任何主机的fred |
‘fred’ | ‘x.example.net%’ | 从x.example.net,从x.example.com等的任何主机的fred |
‘fred’ | ‘198.51.100.177’ | 从ip198.51.100.177主机的fred |
‘fred’ | ‘198.51.100.%’ | 从ip198.51.100C类网中任何主机的fred |
‘fred’ | '198.51.100.0/255.255.255.0 | 与前面相同 |
当有多个匹配项时,需要确认使用哪个匹配项,按照以下的方式解决问题
排序顺序
示例一
要查看其工作原理,假设user 表如下所示:
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| % | root | ...
| % | jeffrey | ...
| localhost | root | ...
| localhost | | ...
+-----------+----------+-
读入到内存时,自动排序后的结果如下所示:
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| localhost | root | ...
| localhost | | ...
| % | jeffrey | ...
| % | root | ...
+-----------+----------+-
挡localhost 上的root用户连接mysql时候,这个时候会匹配| localhost | root |这个条目对应的权限。 其他条目虽然也满足, 但不会匹配它们对应的权限。
示例二
创建如下两个用户,进行连接的优先级的测试
[root@mysql1 ~]# [root@mysql2 ~]# mysql -root-p123456
mysql> create user ''@'192.168.79.140' identified by '123456';
mysql> create user 'test'@'%' identified by '123456';
mysql> select host,user from user;
+----------------+------+
| host | user |
+----------------+------+
| % | test |
| 192.168.79.140 | |
| localhost | root |
+----------------+------+
3 rows in set (0.00 sec)
mysql> exit;
用刚才我们创建的用户登录mysql
[root@mysql2 ~]# mysql -utest -p123456 -h192.168.79.140
读入到内存时,自动排序后的结果如下所示:
+----------------+------+
| host | user |
+----------------+------+
| 192.168.79.140 | |
| localhost | root |
| % | test |
+----------------+------+
第一行匹配test的连接是| 192.168.79.140 | |
我们可以通过CURRENT_USER()函数查看,当前用户
mysql> select current_user();
+-----------------+
| current_user() |
+-----------------+
| @192.168.79.140 |
+-----------------+
1 row in set (0.00 sec)
建议生产不要有不带用户名只有主机的用户
建立连接后,服务器进入访问控制的第二阶段。该连接发出的每个请求,会检查是否具有足够的权限。
这些权限对应着: user(用户),db(数据库),tables_priv(表),columns_priv(列),或procs_priv(存储过程),proxies_priv(代理用户权限) 这些表。
我们需要知道的,mysql用户名和主机名在一起才是一个有效的用户。
语法和Oracle是相似的,如下
create user 'user'@'localhost' identified by 'passwd' [ACCOUNT UNLOCK]
ACCOUNT UNLOCK 用户默认是没有锁定的,如果账户所有,我登录账号不会有第二阶段的请求验证。如下创建一个本地可以登陆的multis用户,默认账户为未锁定状态。
mysql> create user 'multis'@'localhost' identified by '123456' account unlock;
Query OK, 0 rows affected (0.00 sec)
查询用户状态
mysql> select user,host,account_locked from user;
+--------+-----------+----------------+
| user | host | account_locked |
+--------+-----------+----------------+
| root | localhost | N |
| multis | localhost | N |
+--------+-----------+----------------+
2 rows in set (0.00 sec)
1、使用alter修改用户状态
mysql> alter user 'multis'@'localhost' account lock;
Query OK, 0 rows affected (0.00 sec)
mysql> select user,host,account_locked from user;
+--------+-----------+----------------+
| user | host | account_locked |
+--------+-----------+----------------+
| root | localhost | N |
| multis | localhost | Y |
+--------+-----------+----------------+
2 rows in set (0.00 sec)
重新打开一个窗口进行mysql登陆,登陆时候报错帐户被锁定
[root@mysql2 ~]# mysql -umultis -p
Enter password:
ERROR 3118 (HY000): Access denied for user 'multis'@'localhost'. Account is locked.
2、使用alter修改用户密码
mysql> alter user 'test'@'localhost' identified by '654321';
Query OK, 0 rows affected (0.01 sec)
直接更新mysql.user表的信息后,需要flush privileges,将内存和磁盘中的数据保持一致。
1、修改用户名
mysql> update mysql.user set user = 'test' where user = 'multis' and host='localhost';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
2、修改用户ip
mysql> update mysql.user set host = '127.0.0.1' where user = 'test' and host='localhost';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> select user,host,account_locked from user;
+------+-----------+----------------+
| user | host | account_locked |
+------+-----------+----------------+
| root | localhost | N |
| test | 127.0.0.1 | N |
+------+-----------+----------------+
2 rows in set (0.00 sec)
方法一:
mysql> drop user 'test'@'localhost';
Query OK, 0 rows affected (0.00 sec
mysql> create user 'test'@'localhost' identified by '123456' account unlock;
Query OK, 0 rows affected (0.00 sec)
方案二:
mysql> create user 'test'@'localhost' identified by '123456' account unlock;
Query OK, 0 rows affected (0.00 sec)
mysql> delete from mysql.user where user = 'test' and host='localhost';
Query OK, 1 row affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> create user test@'localhost' identified by '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> show create user 'test'@'localhost' \G;
*************************** 1. row ***************************
CREATE USER for test@localhost: CREATE USER 'test'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK
1 row in set (0.00 sec)
ERROR:
No query specified
mysql> select * from mysql.user where user='test' and host='localhost' \G;
*************************** 1. row ***************************
Host: localhost
User: test
Select_priv: N
Insert_priv: N
Update_priv: N
Delete_priv: N
Create_priv: N
Drop_priv: N
Reload_priv: N
Shutdown_priv: N
Process_priv: N
File_priv: N
Grant_priv: N
References_priv: N
Index_priv: N
Alter_priv: N
Show_db_priv: N
Super_priv: N
Create_tmp_table_priv: N
Lock_tables_priv: N
Execute_priv: N
Repl_slave_priv: N
Repl_client_priv: N
Create_view_priv: N
Show_view_priv: N
Create_routine_priv: N
Alter_routine_priv: N
Create_user_priv: N
Event_priv: N
Trigger_priv: N
Create_tablespace_priv: N
ssl_type:
ssl_cipher:
x509_issuer:
x509_subject:
max_questions: 0
max_updates: 0
max_connections: 0
max_user_connections: 0
plugin: mysql_native_password
authentication_string: *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9
password_expired: N
password_last_changed: 2023-04-18 22:00:36
password_lifetime: NULL
account_locked: N
1 row in set (0.00 sec)
ERROR:
No query specified
mysql> select current_user;
+----------------+
| current_user |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
mysql> select user();
+----------------+
| user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
mysql> alter user 'test'@'localhost' identified by '654321';
Query OK, 0 rows affected (0.01 sec)
[root@mysql2 ~]# mysqladmin -utest -p654321 password
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
New password:
Confirm new password:
Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety.
1 、使用默认加密
mysql> set password for 'test'@'%' ='abcdefg';
Query OK, 0 rows affected (0.01 sec)
2、使用PASSWORD()函数加密(mysql使用该方式进行密码加密)
mysql> set password for 'test'@'%' =password('123456');
Query OK, 0 rows affected (0.01 sec)
mysql> alter user current_user() identified by '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> alter user user() identified by '123456';
Query OK, 0 rows affected (0.00 sec)
在设置密码过期时 identified by '123456'
可以忽略
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
重置密码后才能正常登陆
1、修改用户密码过期
mysql> alter user 'test'@'localhost' identified by '123456' password expire;
Query OK, 0 rows affected (0.00 sec)
mysql> show create user 'test'@localhost \G;
*************************** 1. row ***************************
CREATE USER for test@localhost: CREATE USER 'test'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' REQUIRE NONE PASSWORD EXPIRE ACCOUNT UNLOCK
1 row in set (0.00 sec)
ERROR:
No query specified
2、我们可以发现密码策略从PASSWORD EXPIRE DEFAULT变为PASSWORD EXPIRE,登陆mysql,使用sql语句无法使用。
mysql> select current_user();
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
3、使用root用户修改密码
mysql> alter user 'test'@'localhost' identified by '123456';
Query OK, 0 rows affected (0.01 sec)
4、密码修改完成,可以正常登陆mysql
[root@mysql2 ~]# mysql -utest -p123456
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
+--------------------+
1 row in set (0.00 sec)
1、查询test用户非权限属性
mysql> show create user 'test'@'localhost' \G;
*************************** 1. row ***************************
CREATE USER for test@localhost: CREATE USER 'test'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK
1 row in set (0.00 sec)
ERROR:
No query specified
2、修改test用户密码永不过期
mysql> alter user 'test'@'localhost' identified by '123456' password expire;
Query OK, 0 rows affected (0.00 sec)
3、查询test用户非权限属性
mysql> show create user 'test'@'localhost' \G;
*************************** 1. row ***************************
CREATE USER for test@localhost: CREATE USER 'test'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' REQUIRE NONE PASSWORD EXPIRE NEVER ACCOUNT UNLOCK
1 row in set (0.00 sec)
ERROR:
No query specified
1、查询test用户非权限属性
mysql> show create user 'test'@'localhost' \G;
*************************** 1. row ***************************
CREATE USER for test@localhost: CREATE USER 'test'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' REQUIRE NONE PASSWORD EXPIRE NEVER ACCOUNT UNLOCK
1 row in set (0.00 sec)
ERROR:
No query specified
2、我们可以看出当前test密码是永不过期,我们修改为默认设置过期时间
mysql> alter user 'test'@'localhost' password expire default;
Query OK, 0 rows affected (0.01 sec)
3、查询test用户非权限属性
mysql> show create user 'test'@'localhost' \G;
*************************** 1. row ***************************
CREATE USER for test@localhost: CREATE USER 'test'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK
1 row in set (0.00 sec)
ERROR:
No query specified
1、查询test用户非权限属性
mysql> show create user 'test'@'localhost' \G;
*************************** 1. row ***************************
CREATE USER for test@localhost: CREATE USER 'test'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' REQUIRE NONE PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK
1 row in set (0.00 sec)
ERROR:
No query specified
2、我们可以看出当前test密码是默认过期时间,我们修改为指定过期间隔
mysql> alter user 'test'@'localhost' password expire interval 90 day;
Query OK, 0 rows affected (0.00 sec)
3、查询test用户非权限属性
mysql> show create user 'test'@'localhost' \G;
*************************** 1. row ***************************
CREATE USER for test@localhost: CREATE USER 'test'@'localhost' IDENTIFIED WITH 'mysql_native_password' AS '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' REQUIRE NONE PASSWORD EXPIRE INTERVAL 90 DAY ACCOUNT UNLOCK
1 row in set (0.00 sec)
ERROR:
No query specified
使用Sset password修改密码有两种
1 、使用默认加密
mysql> set password for 'test'@'%' ='abcdefg';
Query OK, 0 rows affected (0.01 sec)
2、使用password()函数加密(mysql采用该方式进行密码的加密)
mysql> set password for 'test'@'%' =password('123456');
Query OK, 0 rows affected (0.01 sec)
我们可以使用select @@default_password_lifetime来查询密码过期的全局参数,默认值为0
mysql> select @@default_password_lifetime ;
+-----------------------------+
| @@default_password_lifetime |
+-----------------------------+
| 0 |
+-----------------------------+
1 row in set (0.00 sec)
如果需要修改全局参数,在服务器中my.cnf参数文件中修改或者添加default_password_lifetime参数,重启服务mysql服务生效
[mysqld]
default_password_lifetime=180
default_password_lifetime=180 密码有效期为6个月,最大值65535
default_password_lifetime=0 密码永不过期
1、停止mysql服务
mysql> shutdown;
Query OK, 0 rows affected (0.01 sec)
mysql> exit
2、修改参数文件
[root@mysql2 ~]# vim /etc/my.cnf
[root@mysql2 ~]# cat /etc/my.cnf
[root@mysql2 ~]# nohup mysqld --defaults-file=/etc/my.cnf &
[root@mysql2 ~]# lsof -i:3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 1321 mysql 15u IPv6 24478 0t0 TCP *:mysql (LISTEN)
4、登陆msyql,查询全局参数
[root@mysql2 ~]# mysql -uroot -p123456
## 忽略mysql登陆部分 ##
mysql> select @@default_password_lifetime;
+-----------------------------+
| @@default_password_lifetime |
+-----------------------------+
| 180 |
+-----------------------------+
1 row in set (0.00 sec)
现在要求每90天更改一次密码,我们可以创建用户的时候指定90天后密码过期
mysql> create user 'test1'@'localhost' identified by '123456' password expire interval 90 day;
Query OK, 0 rows affected (0.00 sec)
后续慢慢更新