如何通过SSL加密在Ubuntu 9.10上设置MySQL数据库复制
本教程介绍如何使用SSL连接在MySQL中设置数据库复制进行加密(使黑客无法嗅出主站和从站之间传输的密码和数据)。 MySQL复制允许您从其他服务器(从服务器)上的主服务器获取数据库的准确副本,并且主服务器上数据库的所有更新都将立即复制到从服务器上的数据库,以便两个数据库都处于同步状态。 这不是备份策略,因为也会在从属设备上执行意外发出的DELETE命令; 但复制可以帮助防止硬件故障。
我不会保证这将为您工作!
1初步说明
在本教程中,我将演示如何将IP地址为192.168.0.100
的服务器server1.example.com
(master)的数据库exampledb
复制
到服务器server2.example.com
(从站),IP地址为192.168.0.101
。 两个系统都运行Ubuntu 9.10; 然而,配置应该适用于几乎所有的配置,很少或没有修改。 具有表和数据的数据库exampledb
已经存在于主服务器上,但不存在于从服务器上。
本教程与如何在MySQL中设置数据库复制相同在Ubuntu 9.10中 ,但是它为从主设备到从设备的连接添加了SSL加密以实现额外的安全性。
我使用root权限运行本教程中的所有步骤,因此请确保以root用户身份登录:
sudo su
2安装MySQL 5并启用SSL支持
如果MySQL5尚未安装在server1
和server2上
,请立即安装:
server1 / server2:
aptitude install mysql-server mysql-client
您将被要求为MySQL root用户提供密码 - 此密码对用户root @ localhost
以及root@server1.example.com
/ root@server2.example.com有效
,因此我们不必稍后手动指定MySQL根密码:
MySQL“root”用户的新密码:
< - yourrootsqlpassword
重复MySQL“root”用户的密码:
< - yourrootsqlpassword
现在我们必须检查两个MySQL服务器是否支持SSL连接。 登录MySQL ...
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.00 sec)
mysql>
...这意味着MySQL是使用SSL支持编译的,但目前尚未启用。 要启用它,请先离开MySQL shell?
quit;
...并打开/etc/mysql/my.cnf
:
vi /etc/mysql/my.cnf
向下滚动到*安全功能
部分(在[mysqld]
部分内)),并添加一行与单词ssl
给它:
[...] # * Security Features # # Read the manual, too, if you want chroot! # chroot = /var/lib/mysql/ # # For generating SSL certificates I recommend the OpenSSL GUI "tinyca". ssl # ssl-ca=/etc/mysql/cacert.pem # ssl-cert=/etc/mysql/server-cert.pem # ssl-key=/etc/mysql/server-key.pem [...] |
重启MySQL ...
/etc/init.d/mysql 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在master ( server1
)上的所有接口上监听,因此我们在/etc/mysql/my.cnf中注释了bind-address =
127.0.0.1
:
server1:
vi /etc/mysql/my.cnf
[...] # Instead of skip-networking the default is now to listen only on # localhost which is more compatible and is not less secure. #bind-address = 127.0.0.1 [...] |
之后重启MySQL:
/etc/init.d/mysql restart
然后检查
netstat -tap | grep mysql
MySQL正在监听主节点上的所有接口:
root@server1:~# netstat -tap | grep mysql
tcp 0 0 *:mysql *:* LISTEN 2166/mysqld
root@server1:~#
现在,我们创建了SSL连接所需的CA,服务器和客户端证书。 我在目录/ etc / mysql / newcerts
中创建这些证书,我必须先创建它们:
mkdir /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:/etc/mysql/newcerts# ls -l
total 32
-rw-r--r-- 1 root root 1346 2010-02-04 18:21 ca-cert.pem
-rw-r--r-- 1 root root 1679 2010-02-04 18:21 ca-key.pem
-rw-r--r-- 1 root root 1099 2010-02-04 18:22 client-cert.pem
-rw-r--r-- 1 root root 1679 2010-02-04 18:22 client-key.pem
-rw-r--r-- 1 root root 956 2010-02-04 18:22 client-req.pem
-rw-r--r-- 1 root root 1099 2010-02-04 18:22 server-cert.pem
-rw-r--r-- 1 root root 1675 2010-02-04 18:22 server-key.pem
-rw-r--r-- 1 root root 956 2010-02-04 18:22 server-req.pem
root@server1:/etc/mysql/newcerts#
现在我们必须将ca-cert.pem
, client-cert.pem
和client-key.pem
传输到slave( server2
); 在我们这样做之前,我们在server2
上创建目录/ etc / mysql / newcerts
:
server2:
mkdir /etc/mysql/newcerts
此外,启用server2
上的root帐户(如果您还没有这样做),以便我们可以使用scp
将文件从server1
传输到server2
:
passwd root
在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/mysql/my.cnf
...
vi /etc/mysql/my.cnf
...并修改*安全功能
部分; 取消注释ssl-ca
, ssl-cert
和ssl-key
行,并填写正确的值:
[...] # * Security Features # # Read the manual, too, if you want chroot! # chroot = /var/lib/mysql/ # # For generating SSL certificates I recommend the OpenSSL GUI "tinyca". 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 [...] |
重启MySQL:
/etc/init.d/mysql 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/mysql/my.cnf
(在[mysqld]
部分)中添加/启用以下行):
vi /etc/mysql/my.cnf
[...] # The following can be used as easy to replay backup logs or for replication. # note: if you are setting up a replication slave, see README.Debian about # other settings you may need to change. server-id = 1 log_bin = /var/log/mysql/mysql-bin.log expire_logs_days = 10 max_binlog_size = 100M binlog_do_db = exampledb [...] |
然后重启MySQL:
/etc/init.d/mysql 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 | 3096424 | 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;