如何通过SSL加密设置MySQL数据库复制在CentOS 5.4上
本教程介绍如何使用SSL连接在MySQL中设置数据库复制进行加密(使黑客无法嗅出主站和从站之间传输的密码和数据)。 MySQL复制允许您从其他服务器(从服务器)上的主服务器获取数据库的准确副本,并且主服务器上数据库的所有更新都将立即复制到从服务器上的数据库,以便两个数据库都处于同步状态。 这不是备份策略,因为也会在从属设备上执行意外发出的DELETE命令; 但复制可以帮助防止硬件故障。
我不会保证这将为您工作!
1初步说明
在本教程中,我将演示如何将IP地址为192.168.0.100
的服务器server1.example.com
(master)的数据库exampledb
复制
到服务器server2.example.com
(从站),IP地址为192.168.0.101
。 两个系统都运行CentOS 5.4; 然而,配置应该适用于几乎所有的配置,很少或没有修改。 具有表和数据的数据库exampledb
已经存在于主服务器上,但不存在于从服务器上。
本教程还介绍了从主服务器到从服务器的连接的SSL加密,以获得更多安全性。
我使用root权限运行本教程中的所有步骤,因此请确保以root用户身份登录。
2安装MySQL 5并启用SSL支持
如果MySQL5尚未安装在server1
和server2上
,请立即安装:
server1 / server2:
yum install mysql mysql-devel mysql-server
然后,我们为MySQL创建系统启动链接(以便每当系统启动时,MySQL自动启动)并启动MySQL服务器:
chkconfig --levels 235 mysqld on
/etc/init.d/mysqld start
跑
server1:
mysqladmin -u root password yourrootsqlpassword
mysqladmin -h server1.example.com -u root password yourrootsqlpassword
server2:
mysqladmin -u root password yourrootsqlpassword
mysqladmin -h server2.example.com -u root password yourrootsqlpassword
为用户root
设置密码(否则任何人都可以访问您的MySQL数据库!)。
现在我们必须检查两个MySQL服务器是否支持SSL连接。 登录MySQL ...
server1 / server2:
mysql -u root -p
...并在MySQL shell上运行以下命令:
show variables like '%ssl%';
如果输出如下( has_openssl
和have_ssl都
显示为DISABLED
)...
mysql> show variables like '%ssl%';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| have_openssl | DISABLED |
| have_ssl | DISABLED |
| ssl_ca | |
| ssl_capath | |
| ssl_cert | |
| ssl_cipher | |
| ssl_key | |
+---------------+----------+
7 rows in set (0.01 sec)
mysql>
...这意味着MySQL是使用SSL支持编译的,但目前尚未启用。 要启用它,请先离开MySQL shell?
quit;
...并打开/etc/my.cnf
:
vi /etc/my.cnf
在[mysqld]
部分添加一行含有ssl
的行:
[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Default to using old password format for compatibility with mysql 3.x # clients (those using the mysqlclient10 compatibility package). old_passwords=1 ssl [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid |
重启MySQL ...
/etc/init.d/mysqld restart
...并再次检查SSL是否启用:
mysql -u root -p
show variables like '%ssl%';
输出应该如下,这意味着SSL现在启用:
mysql> show variables like '%ssl%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_openssl | YES |
| have_ssl | YES |
| ssl_ca | |
| ssl_capath | |
| ssl_cert | |
| ssl_cipher | |
| ssl_key | |
+---------------+-------+
7 rows in set (0.00 sec)
mysql>
类型...
quit;
...离开MySQL shell。
3配置主机
首先我们为MySQL bin-logs创建一个日志目录:
server1:
mkdir /var/log/mysql
chown mysql:mysql /var/log/mysql
现在,我们创建了SSL连接所需的CA,服务器和客户端证书。 我在目录/ etc / mysql / newcerts
中创建这些证书,我必须先创建它们:
mkdir -p /etc/mysql/newcerts && cd /etc/mysql/newcerts
创建CA证书:
openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 1000 -key ca-key.pem > ca-cert.pem
创建服务器证书:
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout server-key.pem > server-req.pem
openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem
创建客户端证书:
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout client-key.pem > client-req.pem
openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem
的输出...
ls -l
...现在应该看如下:
[root@server1 newcerts]# ls -l
total 32
-rw-r--r-- 1 root root 1375 Feb 8 17:37 ca-cert.pem
-rw-r--r-- 1 root root 1679 Feb 8 17:37 ca-key.pem
-rw-r--r-- 1 root root 1119 Feb 8 17:37 client-cert.pem
-rw-r--r-- 1 root root 1675 Feb 8 17:37 client-key.pem
-rw-r--r-- 1 root root 968 Feb 8 17:37 client-req.pem
-rw-r--r-- 1 root root 1119 Feb 8 17:37 server-cert.pem
-rw-r--r-- 1 root root 1679 Feb 8 17:37 server-key.pem
-rw-r--r-- 1 root root 968 Feb 8 17:37 server-req.pem
[root@server1 newcerts]#
现在我们必须将ca-cert.pem
, client-cert.pem
和client-key.pem
传输到slave( server2
); 在我们这样做之前,我们在server2
上创建目录/ etc / mysql / newcerts
:
server2:
mkdir -p /etc/mysql/newcerts
在server1上
,我们可以将三个文件传输到server2
,如下所示:
server1:
scp /etc/mysql/newcerts/ca-cert.pem root@192.168.0.101:/etc/mysql/newcerts
scp /etc/mysql/newcerts/client-cert.pem root@192.168.0.101:/etc/mysql/newcerts
scp /etc/mysql/newcerts/client-key.pem root@192.168.0.101:/etc/mysql/newcerts
接下来,打开/etc/my.cnf
...
vi /etc/my.cnf
...并添加以下ssl-ca
, ssl-cert
和ssl-key
行:
[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Default to using old password format for compatibility with mysql 3.x # clients (those using the mysqlclient10 compatibility package). old_passwords=1 ssl ssl-ca=/etc/mysql/newcerts/ca-cert.pem ssl-cert=/etc/mysql/newcerts/server-cert.pem ssl-key=/etc/mysql/newcerts/server-key.pem [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid |
重启MySQL:
/etc/init.d/mysqld restart
现在我们设置一个可以由server2
使用的复制用户slave_user
来访问server1
上的MySQL数据库:
mysql -u root -p
在MySQL shell上,运行以下命令:
GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'%' IDENTIFIED BY 'slave_password' REQUIRE SSL;
REQUIRE SSL
字符串是可选的; 如果将其留下, slave_user
将被允许通过加密和未加密的连接进行连接。 如果使用REQUIRE SSL
,则只允许加密连接。
(如果您已经设置了复制用户,现在要修改它,以便它只能通过SSL连接,可以按照以下方式修改用户:
GRANT USAGE ON *.* TO 'slave_user'@'%' REQUIRE SSL;
)
FLUSH PRIVILEGES;
quit;
此外,我们必须告诉MySQL哪个数据库应该写入日志(这些日志被从机使用以查看主机上发生了什么变化),哪个日志文件应该使用,我们必须指定这个MySQL服务器是主。 我们要复制数据库exampledb
,所以我们在/etc/my.cnf
(在[mysqld]
部分)中添加了server-id
, log_bin
, expire_logs_days
, max_binlog_size
和binlog_do_db
行
):
vi /etc/my.cnf
[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Default to using old password format for compatibility with mysql 3.x # clients (those using the mysqlclient10 compatibility package). old_passwords=1 ssl ssl-ca=/etc/mysql/newcerts/ca-cert.pem ssl-cert=/etc/mysql/newcerts/server-cert.pem ssl-key=/etc/mysql/newcerts/server-key.pem server-id = 1 log_bin = /var/log/mysql/mysql-bin.log expire_logs_days = 10 max_binlog_size = 100M binlog_do_db = exampledb [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid |
然后重启MySQL:
/etc/init.d/mysqld restart
接下来,我们将exampledb
数据库锁定在server1上
,了解server1
的主状态,创建一个exampledb
的SQL转储(我们将导入到server2
中的exampledb
,以便两个数据库都包含相同的数据),并解锁数据库可以再次使用:
mysql -u root -p
在MySQL shell上,运行以下命令:
USE exampledb;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
最后一个命令应该是这样的(请写下来,稍后我们需要)
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 3096416 | exampledb | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
mysql>
现在不要离开MySQL shell,因为如果你离开它,数据库锁将被删除,这不是我们现在想要的,因为我们现在必须创建一个数据库转储。 当MySQL shell仍然打开时,我们打开一个第二个命令行窗口,我们创建SQL转储snapshot.sql
并将其传输到server2
(使用scp;再次确保在server2
上启用了root帐户):
server1:
cd /tmp
mysqldump -u root -pyourrootsqlpassword --opt exampledb > snapshot.sql
scp snapshot.sql root@192.168.0.101:/tmp
之后,可以关闭第二个命令行窗口。 在第一个命令行窗口中,我们现在可以解锁数据库并离开MySQL shell:
server1:
UNLOCK TABLES;
quit;