MySQL及MariaDB安全配置记录

2022-03-01 00:00:00 备份 设置 密码 配置 脚本

简介

简单记录下MySQL及MariaDB安装后进行的一些安全配置,主要包含用户密码复杂度、禁止root远程登录、定期用户修改密码、创建单独的管理账户、密码重试次数及锁定配置、异地逻辑备份、binlog异地备份等。

详细配置可参考官方文档中的说明。

用户密码复杂度

MySQL

安装完成后运行mysql_secure_installation,根据提示即可完成配置。

 -- 查看是否启用
 root@localhost : (none) 01:48:47> show variables like '%validate%' ;
 +--------------------------------------+--------+
 | Variable_name                       | Value |
 +--------------------------------------+--------+
 | innodb_validate_tablespace_paths     | ON     |
 | 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             | STRONG |
 | validate_password.special_char_count | 1     |
 +--------------------------------------+--------+
 8 rows in set (0.02 sec)

MariaDB

MariaDB通过安装插件实现:

 MariaDB [(none)]> INSTALL SONAME 'simple_password_check';
 Query OK,  rows affected (0.026 sec)
 
 ## 配置文件
 [mariadb]
 ...
 plugin_load_add = simple_password_check
 
 # 参数
 show variables like '%simple%' ;


禁止root远程登录

安装完成后运行mysql_secure_installation,根据提示即可完成配置。(MySQL、MariaDB均适用)。

 -- 验证是否生效,查看mysql.user。
 mysql > select user,host from mysql.user;

定期修改密码提醒

MySQL

 -- 查看现有用户信息,关注password_lifetime的值
 mysql > select user,host,password_expired,password_lifetime,password_last_changed,account_locked from mysql.user;
 
 # 单独设置某个账号密码90天过期(root,admin),业务账户不具备设置条件。
 mysql > ALTER USER 'admin'@'%' PASSWORD EXPIRE INTERVAL 90 DAY;
 mysql > ALTER USER 'root'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
 
 mysql > select user,host,password_expired,password_lifetime,password_last_changed,account_locked from mysql.user;
 
 -- 全局设定
 SET GLOBAL default_password_lifetime = 90;  # 全部用户都会在90天的时候提示更改密码,一般业务用户不便更改密码,谨慎配置。
 

MariaDB

 -- 创建用户并设置密码90天过期
 mysql > CREATE USER 'monty'@'localhost' PASSWORD EXPIRE INTERVAL 90 DAY;
 -- 创建用户并设置密码永不过期
 mysql > CREATE USER 'konstantin'@'localhost' PASSWORD EXPIRE NEVER;
 
 -- 验证
 mysql > SHOW CREATE USER 'monty'@'localhost';
 
 
 -- 全局设置参数:default_password_lifetime,可参考:http://mariadb.com/kb/en/server-system-variables/#default_password_lifetime
 
 
 ## 查询用户信息
 WITH password_expiration_info AS (
   SELECT User, Host,
   IF(
    IFNULL(JSON_EXTRACT(Priv, '$.password_lifetime'), -1) = -1,
    @@global.default_password_lifetime,
    JSON_EXTRACT(Priv, '$.password_lifetime')
  ) AS password_lifetime,
  JSON_EXTRACT(Priv, '$.password_last_changed'AS password_last_changed
   FROM mysql.global_priv
 )
 SELECT pei.User, pei.Host,
  pei.password_lifetime,
  FROM_UNIXTIME(pei.password_last_changedAS password_last_changed_datetime,
  FROM_UNIXTIME(
    pei.password_last_changed +
    (pei.password_lifetime * 60 * 60 * 24)
  ) AS password_expiration_datetime
   FROM password_expiration_info pei
   WHERE pei.password_lifetime != 
    AND pei.password_last_changed IS NOT NULL
 UNION
 SELECT pei.User, pei.Host,
  pei.password_lifetime,
  FROM_UNIXTIME(pei.password_last_changedAS password_last_changed_datetime,
    AS password_expiration_datetime
   FROM password_expiration_info pei
   WHERE pei.password_lifetime = 
    OR pei.password_last_changed IS NULL;


创建日常管理账户

具体的权限可以根据实际情况进行赋予。

 mysql > create user admin@'%' identified with mysql_native_password by 'password';
 mysql > GRANT SELECT, INSERT, UPDATE, DELETE,FILE,CREATE, ALTER, INDEX, DROP, CREATE TEMPORARY TABLES, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EXECUTE, CREATE VIEW, EVENT, TRIGGER on *.* to admin@'%' ;


密码重试次数及锁定

MySQLMariaDB配置不一样。下面分别设置:

MySQL

 -- 安装插件
 mysql > install plugin CONNECTION_CONTROL soname 'connection_control.so';
 mysql > install plugin CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS soname 'connection_control.so';
 -- 验证安装情况
 mysql > SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'connection%';
 
 -- 设置密码重试次数为5次
 mysql > SET GLOBAL connection_control_failed_connections_threshold = 5;
 -- 输错5次锁定5分钟,5分钟后自动解锁。
 mysql > SET GLOBAL connection_control_min_connection_delay = 300000;
 
 -- 持久化配置,在参数文件my.cnf中加入如下配置,防止MySQL重启后失效:
 [mysqld]
 plugin-load-add=connection_control.so
 connection_control_failed_connections_threshold=5
 connection_control_min_connection_delay=300000

MariaDB

 MariaDB [(none)]> show variables like 'max_password_errors' ;
 +---------------------+------------+
 | Variable_name       | Value     |
 +---------------------+------------+
 | max_password_errors | 5 |
 +---------------------+------------+
 1 row in set (0.000 sec)
 
 ## 超过5次,报错如下,使用root用户执行flush privileges可解锁。
 [root@ ~]# mysql -umonty -p****
 ERROR 4150 (HY000): User is blocked because of too many credential errors; unblock with 'FLUSH PRIVILEGES'


异地逻辑备份

使用mydumper进行异地备份,脚本如下:

[root@ ~]# more scripts/bak.sh 
#!/bin/sh
echo ">>> start: `date +%F_%H:%M:%S` "
TTIME=`date +%F-%H-%M-%S`
for ip in "192.168.114.61"
do
echo ">>> executing `date +%F_%H:%M:%S` " ${ip} " MySQL mydumper backup ......"
dir=/backup/mysqlbackups/${TTIME}/${ip}
mkdir -p ${dir}
/bin/mydumper -u bkuser -p mlPMNYqLy2Zqxq2yAh9t! -t 4 -h ${ip} -c -o ${dir}
done
echo ">>> end: `date +%F_%H:%M:%S` "

dt90=$(perl -e 'use POSIX;print strftime "%Y-%m-%d",localtime time-90 * 24 * 3600;')
#dt90=$(perl -e 'use POSIX;print strftime "%Y-%m-%d",localtime time-0 * 24 * 3600;')
dt91=$(perl -e 'use POSIX;print strftime "%Y-%m-%d",localtime time-91 * 24 * 3600;')
dt92=$(perl -e 'use POSIX;print strftime "%Y-%m-%d",localtime time-92 * 24 * 3600;')

for dt in ${dt90} ${dt91} ${dt92}
do
if [ -d "/backup/mysqlbackups/${dt}" ]; then
echo
echo ">>> delete directory ...</backup/mysqlbackups/${dt}*>..."
echo
cd /backup/mysqlbackups/
rm -rf /backup/mysqlbackups/${dt}*
fi
done

binlog异地备份

过程省略,可参考如下脚本执行过程。

# 定时启动检查,防止服务器重启或进程异常。
[root@ ~]# crontab -l
0 */1 * * * /root/scripts/binlog.sh

# 主脚本,根据脚本是否运行进行判断,如没有运行,则调用备份脚本,如已在运行,则退出,保证下面的脚本binlogbak.sh只有一个进程在运行。
[root@app ~]# more /root/scripts/binlog.sh
#!/bin/sh
cnt=$(ps -ef | grep "/bin/mysqlbinlog" | grep -vc "grep")
if [ ${cnt} -gt 0 ] ;then
echo "Script is currently in progress..aborting..."
exit 3
fi
/root/scripts/binlogbak.sh

# binlog备份脚本,后台执行。
[root@app ~]# more /root/scripts/binlogbak.sh
#!/bin/sh
MBL=/usr/local/mysql/bin/mysqlbinlog
H=**.**.**.**
P=3306
U=bkuser
PASS=password
D=/backup/binlog_backup/
cd $D
nohup $MBL --raw --read-from-remote-server --stop-never --host=$H --port=$P --user=$U --password=$PASS 要备份的服务器上存在的个binlog的名字 --result-file=${D} 备份的服务器上存在的个binlog的名字 &

审计插件

MySQL企业版有,社区版没有。

MariaDB自带,其配置过程记录如下:

[root@ ~]# find / -name "server_audit.so"  # 安装MariaDB后就有
/usr/lib64/mysql/plugin/server_audit.so

# 安装
MariaDB [(none)]> INSTALL SONAME 'server_audit';
Query OK, 0 rows affected (0.029 sec)

启用

MariaDB [(none)]> SET GLOBAL server_audit_logging=ON;

持久化参数

[MYSQLD]
server_audit_logging=ON
-- 或者使用下面的也可以
[mariadb]
plugin_load_add = server_audit
server_audit=FORCE_PLUS_PERMANENT

查看相关的参数

MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'server_audit%';



来源 https://mp.weixin.qq.com/s/PUVUOSbfCd_IC7Y-sljdZQ

相关文章