[内容] MariaDB & MySQL 安全调优思路

内容一:对网络数据进行加密传输

1.1 生成 SSL

1.1.1 创建 CA 证书
# openssl genrsa 2048 > ca-key.pem
Generating RSA private key, 2048 bit long modulus
..+++
...................................+++
e is 65537 (0x10001)

# openssl req -new -x509 -nodes -days 3600 -key ca-key.pem -out ca.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:ca
Email Address []:

(注意:创建 CA 证书、服务端证书、客户端证书时 Common Name 必须要有值,且必须相互不一样)

1.1.2 创建服务端证书,并去除加密,并使用刚刚的 CA 证书进行签名
# openssl req -newkey rsa:2048 -days 3600 -nodes -keyout server-key.pem -out server-req.pem
Generating a 2048 bit RSA private key
.............+++
...+++
writing new private key to 'server-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

# openssl rsa -in server-key.pem -out server-key.pem
writing RSA key

# openssl x509 -req -in server-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
Signature ok
subject=/C=XX/L=Default City/O=Default Company Ltd
Getting CA Private Key

(注意:创建 CA 证书、服务端证书、客户端证书时 Common Name 必须要有值,且必须相互不一样)

1.1.3 创建客户端证书,并去除加密,并使用刚刚的 CA 证书进行签名
# openssl req -newkey rsa:2048 -days 3600 -nodes -keyout client-key.pem -out client-req.pem
Generating a 2048 bit RSA private key
..................+++
..............................................+++
writing new private key to 'client-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

# openssl rsa -in client-key.pem -out client-key.pem
writing RSA key

# openssl x509 -req -in client-req.pem -days 3600 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
Signature ok
subject=/C=XX/L=Default City/O=Default Company Ltd
Getting CA Private Key
1.1.4 对生成的证书进行验证
# openssl verify -CAfile ca.pem server-cert.pem client-cert.pem
server-cert.pem: OK
client-cert.pem: OK

1.2 将 SSL 添加到 MariaDB & MySQL

1.2.1 将 SSL 放在指定的位置
# mv ca.pem /home/mysql/sslconfig/ca.pem
# mv server-cert.pem /home/mysql/sslconfig/server-cert.pem
# mv server-key.pem /home/mysql/sslconfig/server-key.pem
1.2.2 修改配置文件
# vim /etc/my.cnf

在:

......
[mysqld]

下面添加:

ssl-ca=/home/mysql/sslconfig/ca.pem
ssl-cert=/home/mysql/sslconfig/server-cert.pem
ssl-key=/home/mysql/sslconfig/server-key.pem
......

(补充:这里以 MariaDB 数据库的配置文件是 /etc/my.cnf 为例)

1.2.3 重启数据库
# systemctl restart mariadb

(补充:这里以重启 MariaDB 数据库为例)

1.3 验证 SSL
1.3.1 查看 have_ssl 和 ssl 变量
> show variables like 'have_%ssl';
> show variables like '%ssl%';

(补充:如果它们的参数为 yes ,表示服务端已经开启 SSL)

1.3.2 查看 SSL 的状态
> show status like 'ssl_cipher'

(补充:如果出现 “SSL:Cipher in use is DHE-RSA-AES256-SHA“ 则表示客户端已经使用 SSL 连接了)

1.3.3 确保所有数据库用户使用 SSL
> grant usage on <database>.<table> to '<user>'@'<host>' reouter ssl;
1.3.4 用户通过 SSL 连接数据库的方法
> mysql -u <user> -p -h <host> --ssl-ca=/home/mysql/sslconfig/ca.pem

内容二:开启审计

(如果是 MariaDB 和 MySQL 5.7)

> set global log_warning=2;

(如果是 MySQL 8.0 及以上版本开启审计)

> set global general_log = on;
> set global log_timestamps = SYSTEM;

[步骤] MariaDB & MySQL root 密码的重置

注意:

在重置 MariaDB & MySQL 的 root 密码之前要先安装 MariaDB & MySQL

正文:

步骤一:免密进入数据库

1.1 在 MariaDB&MySQL 文件中添加免密登录参数

# vim /etc/my.cnf

将部分内容修改如下:

......
[mysqld]
skip-grant-tables
......

1.2 使修改的配置生效

1.2.1 MariaDB 使修改的配置生效
# systemctl restart mariadb

(注意:只有当重置 MariaDB 的时候才执行这一步)

1.2.2 MySQL 使修改的配置生效
# systemctl restart mysqld

(注意:只有当重置 MariaDB 的时候才执行这一步)

步骤二:将 root 密码设置为空

2.1 不使用密码进入数据库

# mysql -u root -p

(补充:当提示输入密码时直接敲回车)

2.2 清空 root 用户密码

2.2.1 MariaDB 和 MySQL 5.7 及以下的版本将 root 密码设置为空
> update mysql.user set password='' where user='root';

(注意:只有当是重置 MariaDB 和 MySQL 5.7 及以下版本密码的时候才需要执行这一步)

2.2.2 MySQL 8.0 及以上的版本将 root 密码设置为空
> update mysql.user set authentication_string='' where user='root';

(注意:只有当是重置 MySQL 8.0 及以上版本密码的时候才需要执行这一步)

2.3 退出数据库

> quit;

步骤三:给 root 设置新密码

3.1 在 MariaDB&MySQL 文件中将免密登录参数注释掉

# vim /etc/my.cnf

将部分内容修改如下:

......
[mysqld]
# skip-grant-tables
......

3.2 使修改的配置生效

3.2.1 MariaDB 使修改的配置生效
# systemctl restart mariadb

(注意:只有当重置 MariaDB 的时候才执行这一步)

3.2.2 MySQL 使修改的配置生效
# systemctl restart mysqld

(注意:只有当重置 MySQL 的时候才执行这一步)

3.3 进入数据库

> mysql -u root -p

(补充:当提示输入密码时直接敲回车)

3.4 给 root 设置新密码

> alter user 'root'@'localhost' identified by '<password>';

3.5 退出数据库

> quit;

[实验] MySQL 的安装 (通过 RPM 软件包实现)

纪念:站主于 2019 年 11 月完成了此开源实验,并将过程中的所有命令经过整理和注释以后,形成以下教程

软件准备:

在 MySQL 的官网上下载安装数据库所需要的软件包 MySQL:

https://dev.mysql.com/downloads/mysql/

正文:

步骤一:系统环境要求

1) 服务器的系统需要是 CentOS Linux 7 版本
2) 服务器系统需要有软件源

步骤二:部署安装 MySQL 的环境

2.1 删除系统上的 MariaDB

# systemctl stop mariadb
# rm -rf /var/lib/mysql/*
# rpm -e --nodeps mariadb-server mariadb 

2.2 确保当前目录下拥有如下安装包

# ls
mysql-community-client-8.0.18-1.el7.x86_64.rpm
mysql-community-common-8.0.18-1.el7.x86_64.rpm
mysql-community-devel-8.0.18-1.el7.x86_64.rpm
mysql-community-libs-8.0.18-1.el7.x86_64.rpm
mysql-community-server-8.0.18-1.el7.x86_64.rpm

(补充:这里要安装的是 MySQL 是 8.0.18 社区版)

步骤三:安装 MySQL 数据库

# yum -y localinstall mysql-community-*

步骤四:启动 MySQL 数据库

# systemctl start mysqld

步骤五:修改 MySQL 数据库的 root 密码

5.1 显示初始的 root 密码

# grep 'temporary password' /var/log/mysqld.log 
2019-11-09T09:37:31.347523Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: wAA!w,?e#M2J

(补充:这里查出来的密码是 wAA!w,?e#M2J)

5.2 进入数据库

# mysql -u root -p'wAA!w,?e#M2J'

(补充:这里使用的密码是 wAA!w,?e#M2J)

5.3 修改 root 密码

> alter user user() identified by '<password>';

5.4 退出数据库

> quit;

[实验] MySQL 的安装 (通过 YUM 实现)

纪念:站主于 2019 年 11 月完成了此开源实验,并将过程中的所有命令经过整理和注释以后,形成以下教程

软件准备:

在 MySQL 的官网上下载安装数据库所需要的软件包 MySQL 的 yum 源安装包:

https://dev.mysql.com/downloads/repo/yum/

正文:

步骤一:系统环境要求

1) 服务器的系统需要是 CentOS Linux 7 版本
2) 服务器系统配置好可用的软件源

步骤二:部署安装 MySQL 的环境

2.1 删除系统上的 MariaDB

# systemctl stop mariadb
# rm -rf /var/lib/mysql/*
# rpm -e --nodeps mariadb-server mariadb

2.2 安装 MySQL 的官方软件源

# yum -y localinstall mysql80-community-release-el7-3.noarch.rpm

(补充:这里安装的是 MySQL 是 8.0.18 社区版)

步骤三:安装 MySQL 数据库

# yum -y install mysql-community-server

步骤四:启动 MySQL 数据库

# systemctl start mysqld

步骤五:修改 MySQL 数据库的 root 密码

5.1 显示初始的 root 密码

# grep 'temporary password' /var/log/mysqld.log
2019-11-09T10:04:20.237976Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: 2gSiAAV!+c-1

(补充:这里查出来的密码是 wAA!w,?e#M2J)

5.2 进入数据库

# mysql -u root -p'2gSiAAV!+c-1'

(补充:这里使用的密码是 wAA!w,?e#M2J)

5.3 修改 root 密码

> alter user user() identified by '<password>';

5.4 退出数据库

> quit;

[实验] MariaDB & MySQL 主从同步的搭建 (互为主从)

纪念:站主于 2019 年 11 月完成了此开源实验,并将过程中的所有命令经过整理和注释以后,形成以下教程

步骤一:规划拓扑

1.1 服务器列表

数据库服务器 21 IP 地址:192.168.1.21
数据库服务器 22 IP 地址:192.168.1.22

1.2 服务器列表简介

数据库服务器 21 和 数据库服务器 22 相互同步对方的数据

步骤二:系统环境要求

1) 所有服务器的系统都需要是 CentOS 7 版本
2) 所有服务器都要关闭防火墙
3) 所有服务器都要关闭 SELinux
4) 所有服务器系统都要配置好可用的软件源
5) 需要按照拓扑图给对应的服务器配置好 IP 地址和主机名
6) 所有服务器都要可以相互 ping 通自己和对方的 IP 地址和主机名

步骤三:所有数据库服务器安装 MariaDB 或 MySQL 数据库

3.1 所有数据库服务器安装 MariaDB 或 MySQL

(分别在数据库服务器 21 和数据库服务器 22 上执行以下步骤)

# yum -y install mariadb-server

(补充:这里以安装 MariaDB 数据库为例)

3.2 设置所有数据库服务器开机自启 MariaDB 或 MySQL

(分别在数据库服务器 21 和数据库服务器 22 上执行以下步骤)

# systemctl enable mariadb

(补充:这里以开机自启 MariaDB 数据库为例)

步骤四:配置 MairaDB & MySQL 互为主从结构

4.1 将数据库服务器 22 设置为数据库服务器 21 的从库

4.1.1 开启数据库服务器 21 的 server-id 和 binlog 日志

(只在数据库服务器 21 上执行以下步骤)

# vi /etc/my.cnf

将部分内容修改如下:

[mysqld]
server-id=1
log-bin=mariadb-bin
......


补充:这里以
1) 将 server-id 设置为 1
2) 启动 binlog 日志,并将 binlog 日志的前缀设置为 mariadb-bin
为例

(注意: 集群里的各个数据库的 server id 不能一样)

4.1.2 重启数据库服务器 21 的数据库

(只在数据库服务器 21 上执行以下步骤)

# systemctl restart mariadb

(补充:这里以重启 MariaDB 数据库为例)

4.1.3 在数据库服务器 21 的数据库中创建用于同步的用户
4.1.3.1 进入数据库

(只在数据库服务器 21 上执行以下步骤)

# mysql -p
4.1.3.2 创建数据库服务器 21 用于被数据库服务器 22 同步的 MariaDB 用户

(只在数据库服务器 21 上执行以下步骤)

> grant replication slave on *.* to 'backup'@'192.168.1.22' identified by 'backup';
4.1.3.3 刷新数据库服务器 21 里所有用户的权限

(只在数据库服务器 21 上执行以下步骤)

> flush privileges;
4.1.3.4 显示数据库服务器 21 的 MariaDB 的主库参数

(只在数据库服务器 21 上执行以下步骤)

> show master status;
+--------------------+----------+--------------+------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| mariadb-bin.000003 |      475 |              |                  |
+--------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

(补充:这里显示的 master_log_file 和 master_log_pos 的参数会在后面配置从库中使用)

4.1.4 让数据库服务器 22 同步数据库服务器 21
4.1.4.1 启动数据库服务器 22

(只在数据库服务器 22 上执行以下步骤)

# systemctl start mariadb

(补充:这里以启动 MariaDB 数据库为例)

4.1.4.2 进入数据库服务器 22 的数据库

(只在数据库服务器 22 上执行以下步骤)

# mysql -p
4.1.4.3 同步主库

(只在数据库服务器 22 上执行以下步骤)

> change master to master_host="192.168.1.21",master_user='backup',master_password='backup',master_log_file='mariadb-bin.000003',master_log_pos=475;
4.1.4.4 启动从库状态

(只在数据库服务器 22 上执行以下步骤)

> start slave;
4.1.4.5 显示从库状态

(只在数据库服务器 22 上执行以下步骤)

> show slave status\G;
          Master_Host: 192.168.1.21
              ......
          Slave_IO_Running: Yes  
          Last_IO_Error: ......
              ......
          Slave_SQL_Running: Yes
          Last_SQL_Error: ......
              ......

(补充:这里显示它的主服务器是 192.168.1.21)

(注意:这里要确保 Slave_IO_Running: 和 Slave_SQL_Running: 后面没有报错信息)

4.2 将数据库服务器 21 设置为数据库服务器 22 的从库

4.2.1 关闭数据库服务器 22 的数据库

(只在数据库服务器 22 上执行以下步骤)

# systemctl stop mariadb

(补充:这里以停止 MariaDB 数据库为例)

4.2.2 开启数据库服务器 21 的 server-id 和 binlog 日志

(只在数据库服务器 22 上执行以下步骤)

# vi /etc/my.cnf

(将部分内容修改如下)

[mysqld]
server-id=2
log-bin=mariadb-bin
......


补充:这里以
1) 将 server-id 设置为 2
2) 启动 binlog 日志,并将 binlog 日志的前缀设置为 mariadb-bin
为例

(注意: 集群里的各个数据库的 server id 不能一样)

4.2.3 启动数据库服务器 22 的数据库

(只在数据库服务器 22 上执行以下步骤)

# systemctl start mariadb

(补充:这里以重启 MariaDB 数据库为例)

4.2.4 在数据库服务器 22 的数据库中创建用于同步的用户
4.2.4.1 进入数据库

(只在数据库服务器 22 上执行以下步骤)

# mysql -p
4.2.4.2 创建数据库服务器 21 用于被数据库服务器 22 同步的 MariaDB 用户

(只在数据库服务器 22 上执行以下步骤)

> grant replication slave on *.* to 'backup'@'192.168.1.21' identified by 'backup';
4.2.4.3 刷新数据库服务器 22 数据库里所有用户的权限

(只在数据库服务器 22 上执行以下步骤)

> flush privileges;
4.2.4.4 显示数据库服务器 22 的 MariaDB 的主库参数

(只在数据库服务器 22 上执行以下步骤)

> show master status;
+--------------------+----------+--------------+------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| mariadb-bin.000003 |      475 |              |                  |
+--------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

(补充:这里显示的 master_log_file 和 master_log_pos 的参数会在后面配置从库中使用)

4.2.5 让数据库服务器 21 同步数据库服务器 22
4.2.5.1 进入数据库服务器 21 的数据库

(只在数据库服务器 21 上执行以下步骤)

# mysql -p
4.2.5.2 同步主库

(只在数据库服务器 21 上执行以下步骤)

> change master to master_host="192.168.1.22",master_user='backup',master_password='backup',master_log_file='mariadb-bin.000003',master_log_pos=475;
4.2.5.3 启动从库状态

(只在数据库服务器 21 上执行以下步骤)

> start slave;
4.2.5.4 显示从库状态

(只在数据库服务器 21 上执行以下步骤)

> show slave status\G;
          Master_Host: 192.168.1.22
              ......
          Slave_IO_Running: Yes  
          Last_IO_Error: ......
              ......
          Slave_SQL_Running: Yes
          Last_SQL_Error: ......
              ......

(补充:这里显示它的主服务器是 192.168.1.21)

(注意:这里要确保 Slave_IO_Running: 和 Slave_SQL_Running: 后面没有报错信息)

步骤五:测试 MariaDB & MySQL 互为主从集群

5.1 进入数据库

(分别在数据库服务器 21 和数据库服务器 22 上执行以下步骤)

# mysql -uroot -p

5.2 创建测试库

(只在数据库服务器 21 上执行以下步骤)

> create database test1;

5.3 进入测试库

(分别在数据库服务器 21 和数据库服务器 22 上执行以下步骤)

> use test1;

5.4 创建测试表

(只在数据库服务器 21 上执行以下步骤)

> create table test1a(id int(10),name char(100),age int(10));

(补充:这里随意创建了一张表格)

5.5 在数据库服务器 21 上插入测试数据

(只在数据库服务器 21 上执行以下步骤)

> insert into test1a(id,name,age) values('1','zmy','10');

(补充:这里随意插入了一条数据)

5.6 在数据库服务器 22 上插入测试数据

(只在数据库服务器 22 上执行以下步骤)

> insert into test1a(id,name,age) values('2','ming','20');

(补充:这里随意插入了一条数据)

5.7 在两个数据库里都可以看到对方插入的测试数据

(分别在数据库服务器 21 和数据库服务器 22 上执行以下步骤)

> select * from test1a;
+------+------+------+
| id   | name | age  |
+------+------+------+
|    1 | zmy  |   10 |
|    2 | ming |   20 |
+------+------+------+
2 rows in set (0.00 sec)