数据安全是随着互联网时代快速发展,是不可不重视的问题。目前MySQL在这方面应对大方向上技术手段有:网络安全,权限控制,key秘钥认证,数据加密脱敏 等方式。综合考虑,虽然很多环境无法把这些安全策略应用上,但作为DBA,在可控制范围内能做到一定的防范。但一些最基础又简单设置,最容易忽略,往往导致安全事故频繁触发。
不影响整体规划的情况下,那些方面是DBA有可操作性,应该那些方面尽量避免
- 服务器上配置明文密码避免;
- 操作记录,密码信息避免;
- 复制密码安全;
- 安全相关的插件使用;
MySQL密码明文暴露
当运行客户端程序连接到MySQL服务器时,不建议指定密码,显示密码,使其暴露给其他用户。这里列出了在运行客户机程序时用来指定密码的方法,以及对每种方法的风险的评估。简而言之,最安全的方法是让客户端程序提示输入密码,或者在受适当保护的选项文件中指定不是明文密码。
密码显示
Use a --password=password or -ppassword option on the command line. For example:
$> mysql -uroot -p123456 -S /opt/data8.0/data/mysql.sock
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 8.0.30 MySQL Community Server - GPL
#密码记录在操作系统history里
$> history | grep mysql
。。。
260 ps -ef | grep mysql
261 mysql -uroot -p123456 -S /opt/data8.0/data/mysql.sock
#正确的操作
$> mysql -uroot -p -S /opt/data8.0/data/mysql.sock
Enter password: ********
MYSQL_CONFIG_EDITOR
上面方式每次输入密码是否比较麻烦,MySQL官方工具了提供mysql_config_editor实用程序,它使能够将身份验证凭据存储在名为.mylogin.cnf的加密登录路径文件中。该文件被MySQL客户端程序读取,以获得连接到MySQL服务器的认证凭据。
#1.设置登录path
$> mysql_config_editor set --login-path=dba3380 --host=localhost --user=root --password -S /opt/data8.0/data/mysql.sock
Enter password:
#2.查看设置信息(可以设置多个)
$> mysql_config_editor print --all
[dba3380]
user = "root"
password = *****
host = "localhost"
socket = "/opt/data8.0/data/mysql.sock"
#3.登录方式
$> mysql --login-path=dba3310
#4.删除登录path
$> mysql_config_editor remove --login-path=[localhost]
#5.查看底层.mylogin.cnf文件
[root@schouse ~]# ll ~/ -a
-rw------- 1 root root 188 Sep 20 11:13 .mylogin.cnf
[root@schouse ~]# cat ~/.mylogin.cnf
G¯¹¤HK¸7Ig°?|¹ݸ5 <OQBd ºz+Y.q+̺ᖀ ¢¯° *<𪖌-ԻᒁΞH<J WLɥ¹±pPµҺa£¡]CVD刴a?C$®
注意:操作系统层面需要保护好系统账号。因为能登录到这个用户下,都可以使用这个方式访问数据库。
MYSQL_HISTFILE
MySQL客户端可以为交互执行的语句执行以下类型的日志记录:
在Unix上MySQL将语句写入一个历史文件。默认情况下,这个文件在主目录中命名为.mysql_history。要指定一个不同的文件,设置MYSQL_HISTFILE环境变量的值。
$> touch /opt/.mydb_history
$> chown -R mysql.mysql /opt/.mydb_history
$> export MYSQL_HISTFILE=/opt/.mydb_history
$> echo $MYSQL_HISTFILE
/opt/.mydb_history

如果不想维护历史文件,首先删除.mysql_history(如果它存在的话)。然后使用以下任何一种技术来防止它再次被创建:
$> rm -rf ~/.mysql_history
$> ln -s /dev/null $HOME/.mysql_history
配置文件
以下有几种配置文件明文登录方式:
1./etc/my.cnf配置文件,将密码存储在[client]里
[client]
socket = /opt/data8.0/data/mysql.sock
user = root
password=123456
2.将密码存储在一个选项文件中:在Unix上,在主目录的.my.cnf文件的[client]:
[client]
socket = /opt/data8.0/data/mysql.sock
user = root
password=123456
为了保证密码的安全,除了自己以外,任何人都不能访问该文件。为此,将文件访问模式设置为400或600。但还是存在比较高的风险。
$> chmod 600 .my.cnf
3.用别名方式,配置在 bash_profile:
alias mysqlroot="mysql -uroot -p123456 -S /opt/data8.0/data/mysql.sock"
已别名(alias)方式设置,以简写命令,提高操作效率。但安全系数非常差。
复制源密码
副本将复制源服务器的连接的密码存储在其连接元数据存储库中,默认情况下,该存储库是mysql数据库中名为slave_master_info的表。8.0版本现在已弃用数据目录中的文件作为连接元数据存储库,但仍然可以使用。所以确保只有数据库管理员才能访问元数据存储库。
mysql> CHANGE REPLICATION SOURCE TO
SOURCE_HOST = '192.168.244.130',
SOURCE_PORT = 3390,
SOURCE_USER = 'repl',
SOURCE_PASSWORD = '123456',
SOURCE_AUTO_POSITION =1;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> select * from mysql.slave_master_info\G
*************************** 1. row ***************************
Number_of_lines: 33
Master_log_name:
Master_log_pos: 4
Host: 192.168.244.130
User_name: repl
User_password: 123456
Port: 3390
Connect_retry: 60
。。。
1 row in set (0.00 sec)
密码插件 & 组件
MySQL将用户帐户的密码存储在MySQL用户系统表。对该表的访问权限绝不应授予任何非管理帐户。但可能一些方式可以暴力破解密码。目前对于MySQL账号关联有2个可用(组件 和 插件目前各有1个),密码强度组件 和 登录失败插件。
- Validate_password:通过提升密码的强度和复杂性来提高安全性。
- Connection-Control:尝试连续失败的次数达到配置值后,增加服务器响应的延迟。该功能提供了一种威慑,可以减缓针对MySQL用户帐户的暴力攻击。
validate_password组件
是MySQL5.6以后可以引入的一个新密码校验插件,在MySQL 8.0中,validate_password插件被重新实现为validate_password组件。
#加载组件
mysql> INSTALL COMPONENT 'file://component_validate_password';
Query OK, 0 rows affected (0.01 sec)
#查看组件是否加载
mysql> SELECT * FROM mysql.component;
+--------------+--------------------+------------------------------------+
| component_id | component_group_id | component_urn |
+--------------+--------------------+------------------------------------+
| 4 | 4 | file://component_validate_password |
+--------------+--------------------+------------------------------------+
#组件参数
mysql> show variables like 'validate%';
+--------------------------------------+--------+
| 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 |
+--------------------------------------+--------+
7 rows in set (0.00 sec)
#卸载组件
mysql> UNINSTALL COMPONENT 'file://component_validate_password';
Query OK, 0 rows affected, 1 warning (0.00 sec)
对应组件相关参数:
| 参数 | 说明 |
|---|---|
| validate_password_check_user_name | 用户帐户的用户名部分进行比较 |
| validate_password_dictionary_file | 插件用于验证密码强度的字典文件路径。 |
| validate_password_length | 密码最小长度。 |
| validate_password_mixed_case_count | 密码至少要包含的小写字母个数和大写字母个数。 |
| validate_password_number_count | 密码至少要包含的数字个数。 |
| validate_password_policy | 密码强度检查等级,0/LOW(只检查长度)、1/MEDIUM(检查长度、数字、大小写、特殊字符。)、2/STRONG(检查长度、数字、大小写、特殊字符字典文件)。 |
| validate_password_special_char_count | 密码至少要包含的特殊字符数。 |
Connection-Control插件
用来控制客户端在登录操作连续失败一定次数后的响应的延迟。可防止客户端暴力破解。
#my.cnf配置文件设置
[mysqld]
plugin-load-add=connection_control.so
#加载插件
mysql> INSTALL PLUGIN CONNECTION_CONTROL SONAME 'connection_control.so';
Query OK, 0 rows affected (0.00 sec)
mysql> INSTALL PLUGIN CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS SONAME 'connection_control.so';
Query OK, 0 rows affected (0.01 sec)
#查看插件
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE
'connection%';
+------------------------------------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+------------------------------------------+---------------+
| CONNECTION_CONTROL | ACTIVE |
| CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS | ACTIVE |
+------------------------------------------+---------------+
2 rows in set (0.00 sec)
#插件参数
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 | 1000 |
+-------------------------------------------------+------------+
3 rows in set (0.00 sec)
#卸载插件
mysql> uninstall plugin CONNECTION_CONTROL;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> uninstall plugin CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS;
Query OK, 0 rows affected (0.00 sec)
对应插件相关参数:
| 参数 | 说明 |
|---|---|
| connection_control_failed_connections_threshold | 连续失败最大次数3次,0表示不开启。 |
| connection_control_max_connection_delay | 连接失败的最大延迟,以毫秒为单位。 |
| connection_control_min_connection_delay | 连接失败的最小延迟,以毫秒为单位。 |
备注:对于这两个组件&插件,只要做好对应的防护,不需要使用。但对于安全意思弱的时候,建议开启。
总结
密码安全也是平时关注的一个重点。密码暴露方式,本身提供方便使用和维护,但使用不恰当会导致灾难性问题。当服务器破解登录,密码暴力破解的时。合理配置这些设施,对于数据库来说也是非常重要的一个防火墙。
参考
https://dev.mysql.com/doc/mysql-security-excerpt/8.0/en/general-security-issues.html
https://dev.mysql.com/doc/refman/8.0/en/validate-password.html
https://dev.mysql.com/doc/refman/8.0/en/connection-control-installation.html




