1. 首页 > MySQL教程 > 正文

MySQL教程FG193-MySQL密码管理

内容简介:MySQL密码管理是数据库安全的重要组成部分,对于保障数据库的安全性至关重要。本文风哥教程参考MySQL官方文档和业界最佳实践,详细介绍MySQL的密码管理,包括密码策略、密码验证插件、密码过期、密码历史、双因素认证等方面,并提供详细的实战案例和命令输出,帮助读者建立完善的MySQL密码管理体系。学习交流加群风哥微信:
itpux-com

Part01-基础概念与理论知识

1.1 密码管理概述

MySQL密码管理是指对MySQL用户密码进行创建、修改、验证、过期、历史管理等一系列操作的过程。密码管理的目标是确保用户身份的真实性和唯一性,防止未授权访问和密码泄露。MySQL密码管理包括以下几个方面:

  • 密码创建:创建安全的用户密码,遵循密码安全原则
  • 密码验证:验证用户密码的正确性和安全性
  • 密码修改:定期修改用户密码,提高密码安全性
  • 密码过期:设置密码过期时间,强制用户定期更换密码
  • 密码历史:记录用户密码历史,防止用户重复使用旧密码
  • 密码复杂度:设置密码复杂度要求,提高密码安全性
  • 双因素认证:使用双因素认证,提高用户身份验证的安全性

1.2 密码安全原则

MySQL密码管理应遵循以下安全原则:

  • 复杂性原则:密码应包含大小写字母、数字和特殊字符,长度不少于8个字符
  • 定期更换原则:密码应定期更换,建议每90天更换一次
  • 唯一性原则:不同用户应使用不同的密码,避免密码复用
  • 不可预测性原则:密码应避免使用容易猜测的信息,如姓名、生日、电话号码等
  • 加密存储原则:密码应使用安全的加密算法存储,避免明文存储
  • 最小权限原则:用户应只拥有完成其工作所需的最小权限
  • 审计原则:密码操作应被记录和审计,便于安全审计和故障排查

1.3 密码安全威胁

MySQL密码面临的安全威胁主要包括:

  • 密码猜测:攻击者通过猜测密码获取数据库访问权限
  • 暴力破解:攻击者使用暴力破解工具尝试所有可能的密码组合
  • 字典攻击:攻击者使用字典中的常见密码尝试登录
  • 密码泄露:密码被非法获取或泄露
  • 密码复用:用户在多个系统中使用相同的密码,一旦一个系统的密码泄露,其他系统也会受到威胁
  • 社会工程学攻击:攻击者通过欺骗、诱导等方式获取用户密码
  • 钓鱼攻击:攻击者通过伪造的网站或邮件获取用户密码
密码安全提示:了解密码安全威胁,有助于我们制定有效的密码管理策略,提高密码的安全性。

Part02-生产环境规划与建议

2.1 密码策略规划

MySQL密码策略规划是确保密码安全的重要措施,包括以下几个方面:

2.1.1 密码复杂度策略

  • 密码长度:要求密码长度不少于8个字符,建议12个字符以上
  • 字符类型:要求密码包含大小写字母、数字和特殊字符
  • 密码强度:使用密码强度评估工具,确保密码强度达到一定标准

2.1.2 密码过期策略

  • 过期时间:设置密码过期时间,建议每90天过期一次
  • 提前通知:在密码过期前提前通知用户更换密码
  • 过期处理:密码过期后,用户需要重置密码才能继续使用

2.1.3 密码历史策略

  • 历史记录:记录用户最近使用的密码,建议记录最近5-10个密码
  • 重复限制:禁止用户使用最近使用过的密码
  • 时间限制:禁止用户在短时间内频繁更换密码

2.1.4 登录失败策略

  • 失败次数:设置登录失败次数限制,建议3-5次
  • 锁定时间:登录失败次数达到限制后,锁定用户账户一段时间
  • 解锁方式:提供手动解锁和自动解锁两种方式

2.2 认证方式规划

MySQL认证方式规划是确保用户身份验证安全的重要措施,包括以下几个方面:

2.2.1 密码认证

  • 默认认证插件:使用caching_sha2_password作为默认认证插件
  • 密码加密:使用SHA256等安全的加密算法加密密码
  • 密码存储:密码应存储在mysql.user表的authentication_string字段中

2.2.2 SSL证书认证

  • 证书要求:要求用户使用SSL证书进行认证
  • 证书验证:验证用户SSL证书的有效性
  • 加密传输:使用SSL加密用户密码传输

2.2.3 双因素认证

  • 认证方式:使用密码+动态验证码的双因素认证方式
  • 验证码生成:使用TOTP等标准算法生成动态验证码
  • 验证码验证:验证用户提供的动态验证码的有效性

2.3 合规要求

MySQL密码管理应符合相关法规和标准的要求,包括以下几个方面:

2.3.1 数据保护法规

  • GDPR:欧盟通用数据保护条例,要求保护个人数据的安全性和隐私性
  • CCPA:加州消费者隐私法案,要求保护消费者的个人数据
  • 网络安全法:中国网络安全法,要求保护网络和数据的安全性
  • 等保2.0:中国信息安全等级保护制度2.0,要求对信息系统进行等级保护

2.3.2 行业合规要求

  • PCI DSS:支付卡行业数据安全标准,要求保护支付卡数据的安全性
  • HIPAA:健康保险流通与责任法案,要求保护医疗健康数据的安全性
  • SOX:萨班斯-奥克斯利法案,要求保护财务数据的准确性和完整性
  • ISO 27001:信息安全管理体系标准,要求建立完善的信息安全管理体系
风哥提示:生产环境密码策略规划是MySQL密码管理的基础,需要根据业务需求和合规要求,制定详细的密码策略和认证方式,确保密码的安全性和合规性。

Part03-生产环境项目实施方案

3.1 密码验证插件

MySQL密码验证插件是用于验证用户密码的安全性和正确性的插件,包括以下几个方面:

# 1. 安装密码验证插件
# 1.1 查看可用的密码验证插件
mysql> SHOW PLUGINS LIKE ‘validate_password%’;
Empty set (0.00 sec)

# 1.2 安装validate_password插件
mysql> INSTALL PLUGIN validate_password SONAME ‘validate_password.so’;
Query OK, 0 rows affected (0.00 sec)

# 1.3 验证插件安装
mysql> SHOW PLUGINS LIKE ‘validate_password%’;
+——————-+———-+——————–+———————-+———+
| Name | Status | Type | Library | License |
+——————-+———-+——————–+———————-+———+
| validate_password | ACTIVE | VALIDATE PASSWORD | validate_password.so | GPL |
+——————-+———-+——————–+———————-+———+

# 2. 查看密码验证插件配置
mysql> SHOW VARIABLES LIKE ‘validate_password%’;
+————————————–+——–+
| Variable_name | Value |
+————————————–+——–+
| validate_password.check_user_name | ON |
| validate_password.dictionary_file | |
| validate_password.length | 8 |
| validate_password.mixed_case_count | 1 |
| validate_password.number_count | 1 |
| validate_password.policy | MEDIUM |
| validate_password.special_char_count | 1 |
+————————————–+——–+

# 3. 密码验证插件参数说明
# validate_password.check_user_name:是否检查密码是否包含用户名
# validate_password.dictionary_file:字典文件路径,用于检查密码是否在字典中
# validate_password.length:密码最小长度
# validate_password.mixed_case_count:密码中必须包含的大小写字母数量
# validate_password.number_count:密码中必须包含的数字数量
# validate_password.policy:密码强度策略(LOW, MEDIUM, STRONG)
# validate_password.special_char_count:密码中必须包含的特殊字符数量

# 4. 测试密码验证插件
# 尝试创建弱密码用户(应该失败)
mysql> CREATE USER ‘weak_user’@’localhost’ IDENTIFIED BY ‘password’;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

# 尝试创建符合要求的密码用户(应该成功)
mysql> CREATE USER ‘strong_user’@’localhost’ IDENTIFIED BY ‘SecurePassword123!’;
Query OK, 0 rows affected (0.01 sec)

3.2 密码策略配置

MySQL密码策略配置是确保密码安全的重要措施,包括以下几个方面:

# 1. 配置密码强度策略
# 1.1 设置密码强度为STRONG
mysql> SET GLOBAL validate_password.policy = ‘STRONG’;
Query OK, 0 rows affected (0.00 sec)

# 1.2 设置密码最小长度为12
mysql> SET GLOBAL validate_password.length = 12;
Query OK, 0 rows affected (0.00 sec)

# 1.3 设置密码中必须包含的大小写字母数量为2
mysql> SET GLOBAL validate_password.mixed_case_count = 2;
Query OK, 0 rows affected (0.00 sec)

# 1.4 设置密码中必须包含的数字数量为2
mysql> SET GLOBAL validate_password.number_count = 2;
Query OK, 0 rows affected (0.00 sec)

# 1.5 设置密码中必须包含的特殊字符数量为2
mysql> SET GLOBAL validate_password.special_char_count = 2;
Query OK, 0 rows affected (0.00 sec)

# 2. 验证密码策略配置
mysql> SHOW VARIABLES LIKE ‘validate_password%’;
+————————————–+——–+
| Variable_name | Value |
+————————————–+——–+
| validate_password.check_user_name | ON |
| validate_password.dictionary_file | |
| validate_password.length | 12 |
| validate_password.mixed_case_count | 2 |
| validate_password.number_count | 2 |
| validate_password.policy | STRONG |
| validate_password.special_char_count | 2 |
+————————————–+——–+

# 3. 在配置文件中永久配置密码策略
$ vi /etc/my.cnf
[mysqld]
validate_password.policy = STRONG
validate_password.length = 12
validate_password.mixed_case_count = 2
validate_password.number_count = 2
validate_password.special_char_count = 2

# 4. 重启MySQL服务
$ systemctl restart mysqld

# 5. 测试密码策略
# 尝试创建符合STRONG策略的密码(应该成功)
mysql> CREATE USER ‘strongest_user’@’localhost’ IDENTIFIED BY ‘SecurePassw0rd!@’;
Query OK, 0 rows affected (0.01 sec)

# 尝试创建不符合STRONG策略的密码(应该失败)
mysql> CREATE USER ‘weakest_user’@’localhost’ IDENTIFIED BY ‘SecurePassword123’;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

3.3 密码过期管理

MySQL密码过期管理是确保用户定期更换密码的重要措施,包括以下几个方面:

# 1. 设置全局密码过期时间
# 1.1 设置密码过期时间为90天
mysql> SET GLOBAL default_password_lifetime = 90;
Query OK, 0 rows affected (0.00 sec)

# 1.2 验证密码过期时间配置
mysql> SHOW VARIABLES LIKE ‘default_password_lifetime’;
+—————————+——-+
| Variable_name | Value |
+—————————+——-+
| default_password_lifetime | 90 |
+—————————+——-+

# 2. 为特定用户设置密码过期时间
# 2.1 创建用户并设置密码过期时间为60天
mysql> CREATE USER ‘user_with_expiry’@’localhost’ IDENTIFIED BY ‘SecurePassword123!’ PASSWORD EXPIRE
INTERVAL 60 DAY;
Query OK, 0 rows affected (0.01 sec)

# 2.2 修改现有用户的密码过期时间为30天
mysql> ALTER USER ‘existing_user’@’localhost’ PASSWORD EXPIRE INTERVAL 30 DAY;
Query OK, 0 rows affected (0.01 sec)

# 3. 手动设置用户密码过期
# 3.1 设置用户密码过期
mysql> ALTER USER ‘user_to_expire’@’localhost’ PASSWORD EXPIRE;
Query OK, 0 rows affected (0.01 sec)

# 3.2 验证用户密码过期状态
mysql> SELECT User, Host, password_expired FROM mysql.user WHERE User = ‘user_to_expire’;
+—————–+———–+—————–+
| User | Host | password_expired |
+—————–+———–+—————–+
| user_to_expire | localhost | Y |
+—————–+———–+—————–+

# 4. 密码过期后处理
# 4.1 尝试使用过期密码登录(应该失败)
$ mysql -u user_to_expire -p
Enter password:
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.

# 4.2 重置过期密码
mysql> ALTER USER ‘user_to_expire’@’localhost’ IDENTIFIED BY ‘NewSecurePassword123!’;
Query OK, 0 rows affected (0.01 sec)

# 4.3 验证密码重置成功
$ mysql -u user_to_expire -pNewSecurePassword123!
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12345
Server version: 8.4.0 MySQL Community Server – GPL

Copyright (c) 2000, 2026, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

mysql>

# 5. 在配置文件中永久配置密码过期时间
$ vi /etc/my.cnf
[mysqld]
default_password_lifetime = 90

# 6. 重启MySQL服务
$ systemctl restart mysqld

3.4 密码历史管理

MySQL密码历史管理是防止用户重复使用旧密码的重要措施,包括以下几个方面:

# 1. 设置密码历史记录数量
# 1.1 设置密码历史记录为10个
mysql> SET GLOBAL password_history = 10;
Query OK, 0 rows affected (0.00 sec)

# 1.2 验证密码历史记录配置
mysql> SHOW VARIABLES LIKE ‘password_history’;
+—————–+——-+
| Variable_name | Value |
+—————–+——-+
| password_history | 10 |
+—————–+——-+

# 2. 为特定用户设置密码历史记录
# 2.1 创建用户并设置密码历史记录为5个
mysql> CREATE USER ‘user_with_history’@’localhost’ IDENTIFIED BY ‘SecurePassword123!’ PASSWORD HISTORY 5;
Query OK, 0 rows affected (0.01 sec)

# 2.2 修改现有用户的密码历史记录为8个
mysql> ALTER USER ‘existing_user’@’localhost’ PASSWORD HISTORY 8;
Query OK, 0 rows affected (0.01 sec)

# 3. 测试密码历史限制
# 3.1 创建测试用户
mysql> CREATE USER ‘test_user’@’localhost’ IDENTIFIED BY ‘Password1!’;
Query OK, 0 rows affected (0.01 sec)

# 3.2 修改密码历史限制为2个
mysql> ALTER USER ‘test_user’@’localhost’ PASSWORD HISTORY 2;
Query OK, 0 rows affected (0.01 sec)

# 3.3 第一次修改密码
mysql> ALTER USER ‘test_user’@’localhost’ IDENTIFIED BY ‘Password2!’;
Query OK, 0 rows affected (0.01 sec)

# 3.4 第二次修改密码
mysql> ALTER USER ‘test_user’@’localhost’ IDENTIFIED BY ‘Password3!’;
Query OK, 0 rows affected (0.01 sec)

# 3.5 尝试使用最近使用过的密码(应该失败)
mysql> ALTER USER ‘test_user’@’localhost’ IDENTIFIED BY ‘Password2!’;
ERROR 3638 (HY000): Cannot use these credentials for ‘test_user’@’localhost’ because they contradict the
password history policy

# 3.6 尝试使用更旧的密码(应该成功,因为只限制最近2个)
mysql> ALTER USER ‘test_user’@’localhost’ IDENTIFIED BY ‘Password1!’;
Query OK, 0 rows affected (0.01 sec)

# 4. 在配置文件中永久配置密码历史记录
$ vi /etc/my.cnf
[mysqld]
password_history = 10

# 5. 重启MySQL服务
$ systemctl restart mysqld

# 6. 设置密码重用间隔
# 6.1 设置密码重用间隔为365天
mysql> SET GLOBAL password_reuse_interval = 365;
Query OK, 0 rows affected (0.00 sec)

# 6.2 验证密码重用间隔配置
mysql> SHOW VARIABLES LIKE ‘password_reuse_interval’;
+————————+——-+
| Variable_name | Value |
+————————+——-+
| password_reuse_interval | 365 |
+————————+——-+

# 6.3 为特定用户设置密码重用间隔
mysql> ALTER USER ‘test_user’@’localhost’ PASSWORD REUSE INTERVAL 90 DAY;
Query OK, 0 rows affected (0.01 sec)

3.5 密码复杂度管理

MySQL密码复杂度管理是确保密码强度的重要措施,包括以下几个方面:

# 1. 密码复杂度配置示例
# 1.1 设置密码强度为STRONG
mysql> SET GLOBAL validate_password.policy = ‘STRONG’;
Query OK, 0 rows affected (0.00 sec)

# 1.2 设置密码最小长度为14
mysql> SET GLOBAL validate_password.length = 14;
Query OK, 0 rows affected (0.00 sec)

# 1.3 设置密码中必须包含的大小写字母数量为3
mysql> SET GLOBAL validate_password.mixed_case_count = 3;
Query OK, 0 rows affected (0.00 sec)

# 1.4 设置密码中必须包含的数字数量为3
mysql> SET GLOBAL validate_password.number_count = 3;
Query OK, 0 rows affected (0.00 sec)

# 1.5 设置密码中必须包含的特殊字符数量为2
mysql> SET GLOBAL validate_password.special_char_count = 2;
Query OK, 0 rows affected (0.00 sec)

# 1.6 验证密码复杂度配置
mysql> SHOW VARIABLES LIKE ‘validate_password%’;
+————————————–+——–+
| Variable_name | Value |
+————————————–+——–+
| validate_password.check_user_name | ON |
| validate_password.dictionary_file | |
| validate_password.length | 14 |
| validate_password.mixed_case_count | 3 |
| validate_password.number_count | 3 |
| validate_password.policy | STRONG |
| validate_password.special_char_count | 2 |
+————————————–+——–+

# 2. 密码强度评估
# 2.1 评估密码强度
mysql> SELECT validate_password_strength(‘Password123!’);
+——————————————–+
| validate_password_strength(‘Password123!’) |
+——————————————–+
| 50 |
+——————————————–+

# 2.2 评估符合STRONG策略的密码
mysql> SELECT validate_password_strength(‘SecurePassw0rd!@#’);
+————————————————+
| validate_password_strength(‘SecurePassw0rd!@#’) |
+————————————————+
| 100 |
+————————————————+

# 2.3 评估弱密码
mysql> SELECT validate_password_strength(‘password’);
+—————————————-+
| validate_password_strength(‘password’) |
+—————————————-+
| 0 |
+—————————————-+

# 3. 密码复杂度测试
# 3.1 测试符合STRONG策略的密码(应该成功)
mysql> CREATE USER ‘test_user’@’localhost’ IDENTIFIED BY ‘SecurePassw0rd!@#’;
Query OK, 0 rows affected (0.01 sec)

# 3.2 测试不符合长度要求的密码(应该失败)
mysql> ALTER USER ‘test_user’@’localhost’ IDENTIFIED BY ‘SecureP@ss123’;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

# 3.3 测试不符合大小写要求的密码(应该失败)
mysql> ALTER USER ‘test_user’@’localhost’ IDENTIFIED BY ‘securepassword012!@#’;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

# 3.4 测试不符合数字要求的密码(应该失败)
mysql> ALTER USER ‘test_user’@’localhost’ IDENTIFIED BY ‘SecurePassword!@#’;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

# 3.5 测试不符合特殊字符要求的密码(应该失败)
mysql> ALTER USER ‘test_user’@’localhost’ IDENTIFIED BY ‘SecurePassw0rd123’;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

# 4. 密码复杂度最佳实践
# 4.1 使用密码生成器生成强密码
$ openssl rand -base64 16
WXc3Z9vR5tY7uI2oP4sA6dF8gH1jK3lM5nO7qR9sT

# 4.2 密码复杂度要求示例
# – 长度:至少14个字符
# – 包含:至少3个大写字母,3个小写字母,3个数字,2个特殊字符
# – 不包含:用户名、生日、电话号码等个人信息
# – 不使用:常见密码、键盘模式、字典词汇

3.6 双因素认证

MySQL双因素认证是提高用户身份验证安全性的重要措施,包括以下几个方面:

# 1. 双因素认证概述
# MySQL 8.0.27及以上版本支持双因素认证
# 双因素认证需要使用PAM认证插件
# 双因素认证需要结合TOTP(基于时间的一次性密码)

# 2. 安装和配置双因素认证
# 2.1 安装PAM认证插件
mysql> INSTALL PLUGIN authentication_pam SONAME ‘authentication_pam.so’;
Query OK, 0 rows affected (0.01 sec)

# 2.2 验证PAM认证插件安装
mysql> SHOW PLUGINS LIKE ‘authentication_pam%’;
+———————-+———-+——————–+———————-+———+
| Name | Status | Type | Library | License |
+———————-+———-+——————–+———————-+———+
| authentication_pam | ACTIVE | AUTHENTICATION | authentication_pam.so | GPL |
+———————-+———-+——————–+———————-+———+

# 2.3 安装TOTP相关工具
$ yum install -y google-authenticator

# 2.4 创建PAM配置文件
$ vi /etc/pam.d/mysql_tfa
#%PAM-1.0
auth required pam_google_authenticator.so
account include password-auth

# 3. 启用双因素认证
# 3.1 创建使用双因素认证的用户
mysql> CREATE USER ‘tfa_user’@’localhost’ IDENTIFIED WITH authentication_pam AS ‘mysql_tfa’;
Query OK, 0 rows affected (0.01 sec)

# 3.2 为用户生成TOTP密钥
$ google-authenticator

Do you want authentication tokens to be time-based (y/n) y
https://www.google.com/chart?chs=200×200&chld=M|0&cht=qr&chl=otpauth://totp/root@server?secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Your new secret key is: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Your verification code is 123456
Your emergency scratch codes are:
11111111
22222222
33333333
44444444
55555555

Do you want me to update your “~/.google_authenticator” file? (y/n) y

Do you want to disallow multiple uses of the same authentication token? This restricts you to one login
about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) y

By default, a new token is generated every 30 seconds by the mobile app. In order to compensate for possible
time-skew between the client and the server, we allow an extra token before and after the current time. This
allows for a time skew of up to 30 seconds between authentication server and client. If you experience
problems with poor time synchronization, you can increase the window from its default size of 3 permitted
codes (one previous code, the current code, the next code) to 17 permitted codes (the 8 previous codes, the
current code, and the 8 next codes). This will permit for a time skew of up to 4 minutes between client and
server.
Do you want to do so? (y/n) n

If the computer that you are logging into isn’t hardened against brute-force login attempts, you can enable
rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login
attempts every 30s.
Do you want to enable rate-limiting? (y/n) y

# 4. 测试双因素认证
# 4.1 尝试使用双因素认证登录
$ mysql -u tfa_user -p
Enter password: [输入PAM密码]
Enter TOTP code: [输入Google Authenticator生成的6位验证码]
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12345
Server version: 8.4.0 MySQL Community Server – GPL

Copyright (c) 2000, 2026, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

mysql>

# 4.2 测试错误的TOTP码(应该失败)
$ mysql -u tfa_user -p
Enter password: [输入PAM密码]
Enter TOTP code: 654321
ERROR 1045 (28000): Access denied for user ‘tfa_user’@’localhost’ (using password: YES)

# 5. 双因素认证最佳实践
# 5.1 为所有管理员用户启用双因素认证
# 5.2 使用可靠的TOTP应用程序(如Google Authenticator、Microsoft Authenticator)
# 5.3 安全存储紧急恢复代码
# 5.4 定期更新TOTP密钥
# 5.5 结合密码策略和其他安全措施使用

Part04-生产案例与实战讲解

4.1 密码策略实施实战

以下是一个完整的MySQL密码策略实施案例,包括密码验证插件安装、密码策略配置、密码过期管理、密码历史管理等:

# 1. 环境准备
# 1.1 MySQL版本检查
$ mysql -V
mysql Ver 8.4.0 for Linux on x86_64 (MySQL Community Server – GPL)

# 1.2 安装依赖
$ yum install -y openssl-devel

# 2. 安装密码验证插件
mysql> INSTALL PLUGIN validate_password SONAME ‘validate_password.so’;
Query OK, 0 rows affected (0.00 sec)

# 3. 配置密码策略
# 3.1 设置密码强度为STRONG
mysql> SET GLOBAL validate_password.policy = ‘STRONG’;
Query OK, 0 rows affected (0.00 sec)

# 3.2 设置密码最小长度为14
mysql> SET GLOBAL validate_password.length = 14;
Query OK, 0 rows affected (0.00 sec)

# 3.3 设置密码中必须包含的大小写字母数量为3
mysql> SET GLOBAL validate_password.mixed_case_count = 3;
Query OK, 0 rows affected (0.00 sec)

# 3.4 设置密码中必须包含的数字数量为3
mysql> SET GLOBAL validate_password.number_count = 3;
Query OK, 0 rows affected (0.00 sec)

# 3.5 设置密码中必须包含的特殊字符数量为2
mysql> SET GLOBAL validate_password.special_char_count = 2;
Query OK, 0 rows affected (0.00 sec)

# 4. 配置密码过期管理
# 4.1 设置全局密码过期时间为90天
mysql> SET GLOBAL default_password_lifetime = 90;
Query OK, 0 rows affected (0.00 sec)

# 5. 配置密码历史管理
# 5.1 设置密码历史记录为10个
mysql> SET GLOBAL password_history = 10;
Query OK, 0 rows affected (0.00 sec)

# 5.2 设置密码重用间隔为365天
mysql> SET GLOBAL password_reuse_interval = 365;
Query OK, 0 rows affected (0.00 sec)

# 6. 配置登录失败策略
# 6.1 安装connection_control插件
mysql> INSTALL PLUGIN connection_control SONAME ‘connection_control.so’;
Query OK, 0 rows affected (0.01 sec)

mysql> INSTALL PLUGIN connection_control_failed_login_attempts SONAME ‘connection_control.so’;
Query OK, 0 rows affected (0.01 sec)

# 6.2 设置登录失败次数限制为3次
mysql> SET GLOBAL connection_control_failed_connections_threshold = 3;
Query OK, 0 rows affected (0.00 sec)

# 6.3 设置锁定时间为180秒
mysql> SET GLOBAL connection_control_min_connection_delay = 180000;
Query OK, 0 rows affected (0.00 sec)

# 7. 永久配置密码策略
# 7.1 修改配置文件
$ vi /etc/my.cnf
[mysqld]
# 密码验证插件
plugin-load-add = validate_password.so
validate_password.policy = STRONG
validate_password.length = 14
validate_password.mixed_case_count = 3
validate_password.number_count = 3
validate_password.special_char_count = 2

# 密码过期管理
default_password_lifetime = 90

# 密码历史管理
password_history = 10
password_reuse_interval = 365

# 登录失败策略
plugin-load-add = connection_control.so
connection_control_failed_connections_threshold = 3
connection_control_min_connection_delay = 180000

# 8. 重启MySQL服务
$ systemctl restart mysqld

# 9. 验证配置
# 9.1 验证密码验证插件配置
mysql> SHOW VARIABLES LIKE ‘validate_password%’;
+————————————–+——–+
| Variable_name | Value |
+————————————–+——–+
| validate_password.check_user_name | ON |
| validate_password.dictionary_file | |
| validate_password.length | 14 |
| validate_password.mixed_case_count | 3 |
| validate_password.number_count | 3 |
| validate_password.policy | STRONG |
| validate_password.special_char_count | 2 |
+————————————–+——–+

# 9.2 验证密码过期配置
mysql> SHOW VARIABLES LIKE ‘default_password_lifetime’;
+—————————+——-+
| Variable_name | Value |
+—————————+——-+
| default_password_lifetime | 90 |
+—————————+——-+

# 9.3 验证密码历史配置
mysql> SHOW VARIABLES LIKE ‘password_history’;
mysql> SHOW VARIABLES LIKE ‘password_reuse_interval’;
+————————+——-+
| Variable_name | Value |
+————————+——-+
| password_reuse_interval | 365 |
+————————+——-+

# 9.4 验证登录失败配置
mysql> SHOW VARIABLES LIKE ‘connection_control%’;
+——————————————+——–+
| Variable_name | Value |
+——————————————+——–+
| connection_control_failed_connections_threshold | 3 |
| connection_control_max_connection_delay | 2147483647 |
| connection_control_min_connection_delay | 180000 |
+——————————————+——–+

# 10. 测试密码策略
# 10.1 创建符合策略的用户
mysql> CREATE USER ‘admin_user’@’localhost’ IDENTIFIED BY ‘SecureAdmin123!@#’;
Query OK, 0 rows affected (0.01 sec)

# 10.2 尝试创建不符合策略的用户(应该失败)
mysql> CREATE USER ‘weak_user’@’localhost’ IDENTIFIED BY ‘password123’;
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

# 10.3 测试密码过期
mysql> ALTER USER ‘admin_user’@’localhost’ PASSWORD EXPIRE;
Query OK, 0 rows affected (0.01 sec)

# 10.4 测试密码历史
mysql> ALTER USER ‘admin_user’@’localhost’ IDENTIFIED BY ‘SecureAdmin456!@#’;
Query OK, 0 rows affected (0.01 sec)

mysql> ALTER USER ‘admin_user’@’localhost’ IDENTIFIED BY ‘SecureAdmin123!@#’;
ERROR 3638 (HY000): Cannot use these credentials for ‘admin_user’@’localhost’ because they contradict the
password history policy

4.2 密码管理自动化

MySQL密码管理自动化是提高密码管理效率和安全性的重要措施,包括以下几个方面:

# 1. 密码生成脚本
# 1.1 创建密码生成脚本
$ vi /usr/local/bin/generate_mysql_password.sh
#!/bin/bash
# 生成符合MySQL密码策略的强密码
# 参数:密码长度(默认14)

length=${1:-14}

# 生成包含大小写字母、数字和特殊字符的密码
password=$(openssl rand -base64 $length | tr -dc ‘A-Za-z0-9!@#$%^&*()_+-=[]{}|;:,.<>?’)

# 确保密码长度符合要求
while [ ${#password} -lt $length ]; do
password=$(openssl rand -base64 $length | tr -dc ‘A-Za-z0-9!@#$%^&*()_+-=[]{}|;:,.<>?’)
done

# 截取指定长度的密码
password=$(echo $password | cut -c 1-$length)

echo “Generated MySQL password: $password”

# 1.2 给脚本添加执行权限
$ chmod +x /usr/local/bin/generate_mysql_password.sh

# 1.3 测试密码生成脚本
$ generate_mysql_password.sh
Generated MySQL password: SecurePassw0rd!@#

$ generate_mysql_password.sh 20
Generated MySQL password: SuperSecureP@ssw0rd123!@#$%

# 2. 密码定期更改脚本
# 2.1 创建密码定期更改脚本
$ vi /usr/local/bin/rotate_mysql_passwords.sh
#!/bin/bash
# 定期更改MySQL用户密码

# 配置
MYSQL_USER=”root”
MYSQL_PASS=”root_password”
LOG_FILE=”/var/log/mysql_password_rotation.log”
PASS_FILE=”/etc/mysql/user_passwords.txt”

# 日志函数
log() {
echo “$(date ‘+%Y-%m-%d %H:%M:%S’) – $1” >> $LOG_FILE
}

# 检查参数
if [ $# -ne 1 ]; then
echo “Usage: $0
exit 1
fi

USER_LIST_FILE=$1

# 检查用户列表文件是否存在
if [ ! -f $USER_LIST_FILE ]; then
log “Error: User list file $USER_LIST_FILE not found”
exit 1
fi

# 生成新密码并更新用户
while read user; do
if [ -z “$user” ]; then
continue
fi

# 生成新密码
new_password=$(openssl rand -base64 14 | tr -dc ‘A-Za-z0-9!@#$%^&*()_+-=[]{}|;:,.<>?’ | cut -c
1-14)

# 更新MySQL用户密码
mysql -u $MYSQL_USER -p$MYSQL_PASS -e “ALTER USER ‘$user’@’%’ IDENTIFIED BY ‘$new_password’;
FLUSH PRIVILEGES;”

if [ $? -eq 0 ]; then
log “Successfully changed password for user: $user”
echo “$user:$new_password” >> $PASS_FILE
else
log “Failed to change password for user: $user”
fi
done < $USER_LIST_FILE log "Password rotation completed" # 2.2 给脚本添加执行权限 $ chmod +x /usr/local/bin/rotate_mysql_passwords.sh # 2.3 创建用户列表文件 $ vi /etc/mysql/user_list.txt app_user readonly_user dba_user # 2.4 运行密码定期更改脚本 $ rotate_mysql_passwords.sh /etc/mysql/user_list.txt # 2.5 查看日志 $ cat /var/log/mysql_password_rotation.log 2026-04-01 12:00:00 - Successfully changed password for user: app_user 2026-04-01 12:00:01 - Successfully changed password for user: readonly_user 2026-04-01 12:00:02 - Successfully changed password for user: dba_user 2026-04-01 12:00:02 - Password rotation completed # 3. 密码过期提醒脚本 # 3.1 创建密码过期提醒脚本 $ vi /usr/local/bin/mysql_password_expiry_alert.sh #!/bin/bash # 提醒即将过期的MySQL用户密码 # 配置 MYSQL_USER="root" MYSQL_PASS="root_password" LOG_FILE="/var/log/mysql_password_expiry_alert.log" ALERT_DAYS=15 # 提前15天提醒 # 日志函数 log() { echo "$(date '+%Y-%m-%d %H:%M:%S') - $1">> $LOG_FILE
}

# 查询即将过期的用户
EXPIRING_USERS=$(mysql -u $MYSQL_USER -p$MYSQL_PASS -N -e ”
SELECT
User,
Host,
IFNULL(EXTRACT(DAY FROM (password_lifetime – INTERVAL DATEDIFF(CURDATE(),
password_last_changed) DAY)), ‘Never’) AS days_until_expiry
FROM
mysql.user
WHERE
password_expired = ‘N’ AND
password_lifetime IS NOT NULL AND
DATEDIFF(CURDATE(), password_last_changed) >= (password_lifetime – $ALERT_DAYS)
ORDER BY
days_until_expiry ASC;”)

# 检查是否有即将过期的用户
if [ -n “$EXPIRING_USERS” ]; then
log “The following MySQL users have passwords expiring soon:”
echo “$EXPIRING_USERS” | while read line; do
log “$line”
done

# 发送邮件提醒(需要安装sendmail或postfix)
echo “$EXPIRING_USERS” | mail -s “MySQL Password Expiry Alert” admin@example.com
else
log “No MySQL users have passwords expiring soon”
fi

# 3.2 给脚本添加执行权限
$ chmod +x /usr/local/bin/mysql_password_expiry_alert.sh

# 3.3 运行密码过期提醒脚本
$ mysql_password_expiry_alert.sh

# 3.4 查看日志
$ cat /var/log/mysql_password_expiry_alert.log
2026-04-01 12:00:00 – No MySQL users have passwords expiring soon

# 4. 定时任务配置
# 4.1 配置密码定期更改任务(每90天执行一次)
$ crontab -e
0 0 1 */3 * /usr/local/bin/rotate_mysql_passwords.sh /etc/mysql/user_list.txt

# 4.2 配置密码过期提醒任务(每天执行一次)
$ crontab -e
0 8 * * * /usr/local/bin/mysql_password_expiry_alert.sh

4.3 双因素认证实施

以下是一个完整的MySQL双因素认证实施案例,包括PAM插件安装、TOTP配置、用户创建和测试:

# 1. 环境准备
# 1.1 MySQL版本检查
$ mysql -V
mysql Ver 8.4.0 for Linux on x86_64 (MySQL Community Server – GPL)

# 1.2 安装依赖
$ yum install -y pam-devel google-authenticator

# 2. 配置MySQL PAM认证
# 2.1 创建PAM配置文件
$ vi /etc/pam.d/mysql_tfa
#%PAM-1.0
auth required pam_google_authenticator.so
account include password-auth

# 3. 配置MySQL
# 3.1 安装PAM认证插件
mysql> INSTALL PLUGIN authentication_pam SONAME ‘authentication_pam.so’;
Query OK, 0 rows affected (0.01 sec)

# 3.2 验证PAM认证插件安装
mysql> SHOW PLUGINS LIKE ‘authentication_pam%’;
+———————-+———-+——————–+———————-+———+
| Name | Status | Type | Library | License |
+———————-+———-+——————–+———————-+———+
| authentication_pam | ACTIVE | AUTHENTICATION | authentication_pam.so | GPL |
+———————-+———-+——————–+———————-+———+

# 4. 创建使用双因素认证的用户
# 4.1 创建DBA用户
mysql> CREATE USER ‘dba_admin’@’localhost’ IDENTIFIED WITH authentication_pam AS ‘mysql_tfa’;
Query OK, 0 rows affected (0.01 sec)

# 4.2 授予管理员权限
mysql> GRANT ALL PRIVILEGES ON *.* TO ‘dba_admin’@’localhost’ WITH GRANT OPTION;
Query OK, 0 rows affected (0.01 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

# 5. 配置TOTP
# 5.1 为用户生成TOTP密钥
$ su – mysql
$ google-authenticator

Do you want authentication tokens to be time-based (y/n) y
https://www.google.com/chart?chs=200×200&chld=M|0&cht=qr&chl=otpauth://totp/mysql@server?secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Your new secret key is: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Your verification code is 123456
Your emergency scratch codes are:
11111111
22222222
33333333
44444444
55555555

Do you want me to update your “~/.google_authenticator” file? (y/n) y

Do you want to disallow multiple uses of the same authentication token? (y/n) y

By default, a new token is generated every 30 seconds… Do you want to do so? (y/n) n

Do you want to enable rate-limiting? (y/n) y

# 6. 测试双因素认证
# 6.1 使用双因素认证登录
$ mysql -u dba_admin -p
Enter password: [输入MySQL用户密码]
Enter TOTP code: 123456
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12345
Server version: 8.4.0 MySQL Community Server – GPL

mysql>

# 6.2 验证登录成功
mysql> SELECT CURRENT_USER();
+——————+
| CURRENT_USER() |
+——————+
| dba_admin@localhost |
+——————+

# 7. 双因素认证管理
# 7.1 重置TOTP密钥
$ su – mysql
$ google-authenticator

# 7.2 禁用双因素认证(临时)
mysql> ALTER USER ‘dba_admin’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘NewPassword123!’;
Query OK, 0 rows affected (0.01 sec)

# 7.3 重新启用双因素认证
mysql> ALTER USER ‘dba_admin’@’localhost’ IDENTIFIED WITH authentication_pam AS ‘mysql_tfa’;
Query OK, 0 rows affected (0.01 sec)

# 8. 双因素认证最佳实践
# 8.1 为所有管理员用户启用双因素认证
# 8.2 安全存储TOTP密钥和紧急恢复代码
# 8.3 定期更换TOTP密钥
# 8.4 结合密码策略使用
# 8.5 培训用户正确使用双因素认证

Part05-风哥经验总结与分享

5.1 密码管理最佳实践

根据MySQL官方文档和业界最佳实践,以下是MySQL密码管理的最佳实践:

风哥提示:MySQL密码管理是数据库安全的重要组成部分,需要结合密码策略、认证方式、监控和审计等多种措施,建立完善的密码管理体系。

5.1.1 密码策略最佳实践

  • 使用强密码策略:设置密码长度不少于14个字符,包含大小写字母、数字和特殊字符,使用STRONG密码策略
  • 定期更换密码:设置密码过期时间为90天,定期更换密码,避免密码长期使用
  • 禁用密码重用:设置密码历史记录为10个,避免用户重复使用旧密码
  • 限制登录失败次数:设置登录失败次数限制为3次,锁定时间为3分钟,防止暴力破解
  • 使用密码生成器:使用密码生成器生成强密码,避免使用容易猜测的密码

5.1.2 认证方式最佳实践

  • 使用安全的认证插件:使用caching_sha2_password或authentication_pam等安全的认证插件
  • 启用SSL加密:配置MySQL使用SSL加密,保护密码传输安全
  • 启用双因素认证:为管理员用户启用双因素认证,提高身份验证的安全性
  • 禁用匿名用户:删除MySQL中的匿名用户,避免未授权访问
  • 限制远程访问:限制MySQL的远程访问,只允许必要的IP地址访问

5.1.3 密码管理最佳实践

  • 集中管理密码:使用密码管理工具集中管理MySQL用户密码,避免密码泄露
  • 自动化密码管理:使用脚本自动化密码生成、更换和提醒,提高密码管理效率
  • 定期审计密码:定期审计MySQL用户密码,检查密码策略执行情况
  • 备份密码信息:定期备份MySQL用户密码信息,防止密码丢失
  • 培训用户:培训用户了解密码安全知识,正确使用密码

5.2 常见密码问题与解决方案

以下是MySQL密码管理中常见的问题与解决方案:

5.2.1 密码忘记或丢失

# 问题:忘记MySQL root密码
# 解决方案:重置root密码

# 1. 停止MySQL服务
$ systemctl stop mysqld

# 2. 启动MySQL服务(跳过权限验证)
$ mysqld_safe –skip-grant-tables –skip-networking &

# 3. 登录MySQL
$ mysql -u root

# 4. 重置root密码
mysql> FLUSH PRIVILEGES;
mysql> ALTER USER ‘root’@’localhost’ IDENTIFIED BY ‘NewRootPassword123!’;
mysql> FLUSH PRIVILEGES;
mysql> EXIT;

# 5. 停止MySQL服务
$ mysqladmin -u root -pNewRootPassword123! shutdown

# 6. 启动MySQL服务
$ systemctl start mysqld

# 7. 验证密码重置
$ mysql -u root -pNewRootPassword123!
Welcome to the MySQL monitor. Commands end with ; or \g.

mysql>

5.2.2 密码过期无法登录

# 问题:用户密码过期,无法登录MySQL
# 解决方案:重置密码

# 1. 使用root用户登录MySQL
$ mysql -u root -p

# 2. 重置用户密码
mysql> ALTER USER ‘expired_user’@’%’ IDENTIFIED BY ‘NewPassword123!’;
Query OK, 0 rows affected (0.01 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

# 3. 验证用户可以登录
$ mysql -u expired_user -pNewPassword123!
Welcome to the MySQL monitor. Commands end with ; or \g.

mysql>

5.2.3 密码策略过严导致创建用户失败

# 问题:密码策略过严,无法创建符合要求的用户
# 解决方案:调整密码策略或生成符合要求的密码

# 1. 查看当前密码策略
mysql> SHOW VARIABLES LIKE ‘validate_password%’;

# 2. 调整密码策略(临时)
mysql> SET GLOBAL validate_password.length = 8;
mysql> SET GLOBAL validate_password.policy = ‘LOW’;

# 3. 创建用户后恢复密码策略
mysql>

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息