How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

16
How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 By Falko Timme Published: 2010-02-07 18:04 How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 Version 1.0 Author: Falko Timme <ft [at] falkotimme [dot] com> Follow me on Twitter Last edited 02/05/2010 This tutorial describes how to set up database replication in MySQL using an SSL connection for encryption (to make it impossible for hackers to sniff out passwords and data transferred between the master and slave). MySQL replication allows you to have an exact copy of a database from a master server on another server (slave), and all updates to the database on the master server are immediately replicated to the database on the slave server so that both databases are in sync. This is not a backup policy because an accidentally issued DELETE command will also be carried out on the slave; but replication can help protect against hardware failures though. I do not issue any guarantee that this will work for you! 1 Preliminary Note In this tutorial I will show how to replicate the database exampledb from the server server1.example.com (master) with the IP address 192.168.0.100 to the server server2.example.com (slave) with the IP address 192.168.0.101. Both systems are running Ubuntu 9.10; however, the configuration should apply to almost all distributions with little or no modifications. The database exampledb with tables and data is already existing on the master, but not on the slave. This tutorial is the same as How To Set Up Database Replication In MySQL On Ubuntu 9.10 , however it adds SSL encryption for connections from the master to the slave for additional security. I'm running all the steps in this tutorial with root privileges, so make sure you're logged in as root: Copyright © 2011 All Rights Reserved. HowtoForge Page 1 of 16

Transcript of How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

Page 1: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10

By Falko TimmePublished: 2010-02-07 18:04

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10

Version 1.0 Author: Falko Timme <ft [at] falkotimme [dot] com>

Follow me on TwitterLast edited 02/05/2010

This tutorial describes how to set up database replication in MySQL using an SSL connection for encryption (to make it impossible for hackers to sniff outpasswords and data transferred between the master and slave). MySQL replication allows you to have an exact copy of a database from a master server onanother server (slave), and all updates to the database on the master server are immediately replicated to the database on the slave server so that bothdatabases are in sync. This is not a backup policy because an accidentally issued DELETE command will also be carried out on the slave; but replicationcan help protect against hardware failures though.

I do not issue any guarantee that this will work for you!

 1 Preliminary Note

In this tutorial I will show how to replicate the database exampledb from the server server1.example.com (master) with the IP address 192.168.0.100to the server server2.example.com (slave) with the IP address 192.168.0.101. Both systems are running Ubuntu 9.10; however, the configurationshould apply to almost all distributions with little or no modifications. The database exampledb with tables and data is already existing on the master, butnot on the slave.

This tutorial is the same as How To Set Up Database Replication In MySQL On Ubuntu 9.10, however it adds SSL encryption for connections from themaster to the slave for additional security.

I'm running all the steps in this tutorial with root privileges, so make sure you're logged in as root:

Copyright © 2011 All Rights Reserved. HowtoForge Page 1 of 16

Page 2: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

sudo su

 2 Installing MySQL 5 And Enabling SSL Support

If MySQL 5 isn't already installed on server1 and server2, install it now:

server1/server2:

aptitude install mysql-server mysql-client

You will be asked to provide a password for the MySQL root user - this password is valid for the user root@localhost as well as [email protected] / [email protected], so we don't have to specify a MySQL root password manually later on:

New password for the MySQL "root" user: <-- yourrootsqlpassword

Repeat password for the MySQL "root" user: <-- yourrootsqlpassword

Now we must check if both MySQL server support SSL connections. Log into MySQL...

mysql -u root -p

... and run the following command on the MySQL shell:

show variables like '%ssl%';

If the output is as follows (both have_openssl and have_ssl show DISABLED)...

mysql> show variables like '%ssl%';

+---------------+----------+

| Variable_name | Value    |

Copyright © 2011 All Rights Reserved. HowtoForge Page 2 of 16

Page 3: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

+---------------+----------+

| have_openssl  | DISABLED |

| have_ssl      | DISABLED |

| ssl_ca        |          |

| ssl_capath    |          |

| ssl_cert      |          |

| ssl_cipher    |          |

| ssl_key       |          |

+---------------+----------+

7 rows in set (0.00 sec)

mysql>

... it means that MySQL was compiled with SSL support, but it's currently not enabled. To enable it, leave the MySQL shell first...

quit;

... and open /etc/mysql/my.cnf:

vi /etc/mysql/my.cnf

Scroll down to the * Security Features section (within the [mysqld] section) and add a line with the word ssl to it:

[...]

# * Security Features

#

# Read the manual, too, if you want chroot!

# chroot = /var/lib/mysql/

#

# For generating SSL certificates I recommend the OpenSSL GUI "tinyca".

Copyright © 2011 All Rights Reserved. HowtoForge Page 3 of 16

Page 4: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

ssl

# ssl-ca=/etc/mysql/cacert.pem

# ssl-cert=/etc/mysql/server-cert.pem

# ssl-key=/etc/mysql/server-key.pem

[...]

Restart MySQL...

/etc/init.d/mysql restart

... and check again if SSL is now enabled:

mysql -u root -p

show variables like '%ssl%';

Output should be as follows which means that SSL is now enabled:

mysql> show variables like '%ssl%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| have_openssl  | YES   |

| have_ssl      | YES   |

| ssl_ca        |       |

| ssl_capath    |       |

| ssl_cert      |       |

| ssl_cipher    |       |

| ssl_key       |       |

Copyright © 2011 All Rights Reserved. HowtoForge Page 4 of 16

Page 5: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

+---------------+-------+

7 rows in set (0.00 sec)

mysql>

Type...

quit;

... to leave the MySQL shell.

 3 Configuring The Master

To make sure that the replication can work, we must make MySQL listen on all interfaces on the master (server1), therefore we comment out the line bind-address = 127.0.0.1 in /etc/mysql/my.cnf:

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

[...]

Restart MySQL afterwards:

/etc/init.d/mysql restart

Copyright © 2011 All Rights Reserved. HowtoForge Page 5 of 16

Page 6: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

Then check with

netstat -tap | grep mysql

that MySQL is really listening on all interfaces on the master:

root@server1:~# netstat -tap | grep mysql

tcp        0      0 *:mysql                 *:*                     LISTEN      2166/mysqld

root@server1:~#

Now we create the CA, server, and client certificates that we need for the SSL connections. I create these certificates in the directory /etc/mysql/newcerts which I have to create first:

mkdir /etc/mysql/newcerts && cd /etc/mysql/newcerts

Create CA certificate:

openssl genrsa 2048 > ca-key.pem

openssl req -new -x509 -nodes -days 1000 -key ca-key.pem > ca-cert.pem

Create server certificate:

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

Create client certificate:

Copyright © 2011 All Rights Reserved. HowtoForge Page 6 of 16

Page 7: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

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

The output of...

ls -l

... should now look as follows:

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#

We must now transfer ca-cert.pem, client-cert.pem, and client-key.pem to the slave (server2); before we do this, we create the directory /etc/mysql/newcerts on server2:

server2:

mkdir /etc/mysql/newcerts

Also, enable the root account on server2 (in case you haven't already done so) so that we can transfer the files from server1 to server2 with scp:

Copyright © 2011 All Rights Reserved. HowtoForge Page 7 of 16

Page 8: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

passwd root

Back on server1, we can transfer the three files to server2 as follows:

server1:

scp /etc/mysql/newcerts/ca-cert.pem [email protected]:/etc/mysql/newcerts

scp /etc/mysql/newcerts/client-cert.pem [email protected]:/etc/mysql/newcerts

scp /etc/mysql/newcerts/client-key.pem [email protected]:/etc/mysql/newcerts

Next, open /etc/mysql/my.cnf...

vi /etc/mysql/my.cnf

... and modify the * Security Features section; uncomment the ssl-ca, ssl-cert, and ssl-key lines and fill in the correct values:

[...]

# * 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

Copyright © 2011 All Rights Reserved. HowtoForge Page 8 of 16

Page 9: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

ssl-cert=/etc/mysql/newcerts/server-cert.pem

ssl-key=/etc/mysql/newcerts/server-key.pem

[...]

Restart MySQL:

/etc/init.d/mysql restart

Now we set up a replication user slave_user that can be used by server2 to access the MySQL database on server1:

mysql -u root -p

On the MySQL shell, run the following commands:

GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'%' IDENTIFIED BY 'slave_password' REQUIRE SSL;

The REQUIRE SSL string is optional; if you leave it out, slave_user will be allowed to connect through encrypted and also unencrypted connections. If youuse REQUIRE SSL, then only encrypted connections are allowed.

(If you've already set up a replication user, and now want to modify it so that it can only connect through SSL, you can modify the user as follows:

GRANT USAGE ON *.* TO 'slave_user'@'%' REQUIRE SSL;

)

FLUSH PRIVILEGES;

quit;

Copyright © 2011 All Rights Reserved. HowtoForge Page 9 of 16

Page 10: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

Furthermore we have to tell MySQL for which database it should write logs (these logs are used by the slave to see what has changed on the master), whichlog file it should use, and we have to specify that this MySQL server is the master. We want to replicate the database exampledb, so we add/enable thefollowing lines in /etc/mysql/my.cnf (in the [mysqld]section):

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

[...]

Then restart MySQL:

/etc/init.d/mysql restart

Next we lock the exampledb database on server1, find out about the master status of server1, create an SQL dump of exampledb (that we will importinto exampledb on server2 so that both databases contain the same data), and unlock the database so that it can be used again:

mysql -u root -p

On the MySQL shell, run the following commands:

Copyright © 2011 All Rights Reserved. HowtoForge Page 10 of 16

Page 11: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

USE exampledb;

FLUSH TABLES WITH READ LOCK;

SHOW MASTER STATUS;

The last command should show something like this (please write it down, we'll need it later on):

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>

Now don't leave the MySQL shell, because if you leave it, the database lock will be removed, and this is not what we want right now because we mustcreate a database dump now. While the MySQL shell is still open, we open a second command line window where we create the SQL dump snapshot.sql and transfer it to server2 (using scp; again, make sure that the root account is enabled on server2):

server1:

cd /tmp

mysqldump -u root -pyourrootsqlpassword --opt exampledb > snapshot.sql

scp snapshot.sql [email protected]:/tmp

Afterwards, you can close the second command line window. On the first command line window, we can now unlock the database and leave the MySQL

Copyright © 2011 All Rights Reserved. HowtoForge Page 11 of 16

Page 12: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

shell:

server1:

UNLOCK TABLES;

quit;

4 Configuring The Slave

Now we must configure the slave. Open /etc/mysql/my.cnf and make sure you have the following settings in the [mysqld] section:

server2:

vi /etc/mysql/my.cnf

[...]

server-id=2

master-connect-retry=60

replicate-do-db=exampledb

[...]

The value of server-id must be unique and thus different from the one on the master!

Restart MySQL afterwards:

/etc/init.d/mysql restart

Copyright © 2011 All Rights Reserved. HowtoForge Page 12 of 16

Page 13: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

Before we start setting up the replication, we create an empty database exampledb on server2:

mysql -u root -p

CREATE DATABASE exampledb;

quit;

On server2, we can now import the SQL dump snapshot.sql like this:

/usr/bin/mysqladmin --user=root --password=yourrootsqlpassword stop-slave

cd /tmp

mysql -u root -pyourrootsqlpassword exampledb < snapshot.sql

Now connect to MySQL again...

mysql -u root -p

... and run the following command to make server2 a slave of server1 (it is important that you replace the values in the following command with the values yougot from the SHOW MASTER STATUS; command that we ran on server1!):

CHANGE MASTER TO MASTER_HOST='192.168.0.100', MASTER_USER='slave_user', MASTER_PASSWORD='slave_password', MASTER_LOG_FILE='mysql-bin.000001',

MASTER_LOG_POS=3096424, MASTER_SSL=1, MASTER_SSL_CA = '/etc/mysql/newcerts/ca-cert.pem', MASTER_SSL_CERT =

'/etc/mysql/newcerts/client-cert.pem', MASTER_SSL_KEY = '/etc/mysql/newcerts/client-key.pem';

- MASTER_HOST is the IP address or hostname of the master (in this example it is 192.168.0.100).

Copyright © 2011 All Rights Reserved. HowtoForge Page 13 of 16

Page 14: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

- MASTER_USER is the user we granted replication privileges on the master. - MASTER_PASSWORD is the password of MASTER_USER on the master. - MASTER_LOG_FILE is the file MySQL gave back when you ran SHOW MASTER STATUS; on the master. - MASTER_LOG_POS is the position MySQL gave back when you ran SHOW MASTER STATUS; on the master. - MASTER_SSL makes the slave use an SSL connection to the master. - MASTER_SSL_CA is the path to the ca-cert.pem file on the slave. - MASTER_SSL_CERT is the path to the client-cert.pem file on the slave. - MASTER_SSL_KEY is the path to the client-key.pem file on the slave.

Finally start the slave:

START SLAVE;

Then check the slave status:

SHOW SLAVE STATUS \G

It is important that both Slave_IO_Running and Slave_SQL_Running have the value Yes in the output (otherwise something went wrong, and you shouldcheck your setup again and take a look at /var/log/syslog to find out about any errors); as you're using an SSL connection now, you should also findvalues in the fields Master_SSL_Allowed, Master_SSL_CA_File, Master_SSL_Cert, and Master_SSL_Key:

mysql> SHOW SLAVE STATUS G

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.0.100

                  Master_User: slave_user

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000001

          Read_Master_Log_Pos: 3096424

               Relay_Log_File: mysqld-relay-bin.000002

Copyright © 2011 All Rights Reserved. HowtoForge Page 14 of 16

Page 15: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

                Relay_Log_Pos: 251

        Relay_Master_Log_File: mysql-bin.000001

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

              Replicate_Do_DB: exampledb

          Replicate_Ignore_DB:

           Replicate_Do_Table:

       Replicate_Ignore_Table:

      Replicate_Wild_Do_Table:

  Replicate_Wild_Ignore_Table:

                   Last_Errno: 0

                   Last_Error:

                 Skip_Counter: 0

          Exec_Master_Log_Pos: 3096424

              Relay_Log_Space: 407

              Until_Condition: None

               Until_Log_File:

                Until_Log_Pos: 0

           Master_SSL_Allowed: Yes

           Master_SSL_CA_File: /etc/mysql/newcerts/ca-cert.pem

           Master_SSL_CA_Path:

              Master_SSL_Cert: /etc/mysql/newcerts/client-cert.pem

            Master_SSL_Cipher:

               Master_SSL_Key: /etc/mysql/newcerts/client-key.pem

        Seconds_Behind_Master: 0

Master_SSL_Verify_Server_Cert: No

                Last_IO_Errno: 0

                Last_IO_Error:

               Last_SQL_Errno: 0

               Last_SQL_Error:

1 row in set (0.00 sec)

mysql>

Copyright © 2011 All Rights Reserved. HowtoForge Page 15 of 16

Page 16: How to Set Up MySQL Database Replication With SSL Encryption on Ubuntu 9.10

How To Set Up MySQL Database Replication With SSL Encryption On Ubuntu 9.10 http://www.howtoforge.com/

Afterwards, you can leave the MySQL shell on server2:

quit;

That's it! Now whenever exampledb is updated on the master, all changes will be replicated to exampledb on the slave. Test it!

 5 Links - MySQL: http://www.mysql.com/ - Ubuntu: http://www.ubuntu.com/

Copyright © 2011 All Rights Reserved. HowtoForge Page 16 of 16