Защита репликации MySQL при помощи SSH

При репликации данных MySQL порт 3306 остаётся открытым и передаваемые по нему данные не шифруются. При помощи SSH-туннелирования репликация MySQL может выполняться по соединению SSH. Этот метод не требует открывать в брандмауэре дополнительных портов.

Примечание: Весь код, выделенный красным, нужно отредактировать или ввести самостоятельно. Остальное можно просто скопировать и вставить.

В руководстве используются следующие условные данные:

  • IP-адрес ведущего сервера (master): 1.1.1.1
  • IP-адрес ведомого сервера (slave): 2.2.2.2

Команды, предназначенные для ведущего сервера, отмечены в руководстве словом master, для ведомого сервера – slave.

Прежде чем приступить к выполнению руководства, рекомендуется ознакомиться со статьёй  «Репликация баз данных MySQL по типу Master/Slave»

1: Настройка SSH-туннелирования

Создайте нового пользователя и установите для него пароль. При помощи этого пользователя будет создан SSH-туннель:

(master)
root@mysql-master:~# useradd -d /home/tunneluser -m tunneluser
root@mysql-master:~# passwd tunneluser

Пользователь tunneluser должен иметь доступ только с сервера slave, потому его нужно добавить в файл /etc/ssh/sshd_config

(master)
root@mysql-master:~# nano /etc/ssh/sshd_config

Пользователи, не включенные в этот файл, не буду иметь доступа SSH. Потому в него нужно внести администраторов сервера:

(master)
AllowUsers root alice bob tunneluser@2.2.2.2

Перезапустите SSH:

root@mysql-master:~# service ssh restart

После этого нужно создать SSH-ключ.

Примечание: Подробнее об этом можно прочесть в этом руководстве.

(slave)
[root@mysql-slave ~]# ssh-keygen

Команда вернёт:

[root@mysql-slave ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
5d:db:9c:50:e8:b2:88:18:de:78:5f:ed:83:14:47:d7 root@mysql-slave
The key's randomart image is:
+--[ RSA 2048]----+
|             ... |
|            o.. E|
|           oo.   |
|    .    .o.o= . |
|   . = .S..*. +  |
|    + + . + .    |
|     . . o o     |
|        . . o    |
|             .   |
+-----------------+

НЕ устанавливайте пароль для ключа: в при его наличии невозможно установить SSH-туннель автоматически.

Скопируйте открытый ключ на master:

(slave)
[root@mysql-slave ~]# ssh-copy-id tunneluser@1.1.1.1

Команда вернет:

[root@mysql-slave ~]# ssh-copy-id tunneluser@1.1.1.1
The authenticity of host '1.1.1.1 (1.1.1.1)' can't be established.
RSA key fingerprint is 3f:33:0c:73:bd:da:51:b9:45:2e:d7:2e:00:47:33:17.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '1.1.1.1' (RSA) to the list of known hosts.
tunneluser@1.1.1.1's password:
Now try logging into the machine, with "ssh 'tunneluser@1.1.1.1'", and check in:
~/.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.

Пользователь tunneluser используется только для туннелирования; он не используется для управления сервером. Потому рекомендуется настроить оболочку nologin и удалить пароль:

(master)
usermod -s /sbin/nologin tunneluser
passwd -d tunneluser

Примечание: Пользователи Debian и Ubuntu должны заменить /sbin/nologin в вышеприведённой команде каталогом /usr/sbin/nologin.

Создайте SSH-туннель:

(slave)
ssh -L 33061:localhost:3306 tunneluser@1.1.1.1 -f -N

После создания туннеля порт 33061 на локальном хосте соединит серверы slave и master по SSH. Флаг –f запускает команду в фоновом режиме, параметр -N значит «Не  выполнять команду» (поскольку пользователь tunneluser использует оболочку nologin).

2: Настройка MySQL

Примечание: Данный раздел содержит только изменения настроек, описанных в руководстве по репликации данных MySQL. Все изменения выделены оранжевым.

Если файл my.cnf был отредактирован для прослушивания внешнего IP, верните прежнюю настройку (localhost).

(master и slave)
root@mysql-master:~# nano /etc/mysql/my.cnf

Отредактируйте строку:

bind-address     = 1.1.1.1

указав IP-адрес локального хоста.

bind-address     = 127.0.0.1

Измените привилегии пользователя сервера slave, разрешив входить только через локальный хост.

(master)
root@mysql-master:~# mysql -u root -p
mysql>GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'localhost'

Запрос CHANGE MASTER указал на открытый IP-адрес сервера master и не сообщил порт. Создайте новый запрос:

(slave)
root@mysql-slave:~# mysql -u root -p
mysql>STOP SLAVE;
mysql>CHANGE MASTER TO MASTER_HOST='127.0.0.1',MASTER_USER='slave_user', MASTER_PASSWORD='password', MASTER_PORT=33061, MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=107;
mysql>START SLAVE;

Подключение может быть проверено при помощи следующей команды:

(slave)
mysql -h 127.0.0.1 -u slave_user -P 33061 -p

Примечание: Не используйте локальный хост с параметром –h, поскольку в результате MySQL создаст локальное подключение через стандартный порт.

Tags: ,

1 комментарий

  • Fidel Kastroff says:

    Не выдержал, извините:
    Во-первых, юзверь не админ, соответственно при подключении нужно явно прописать путь к ключу иначе будем получать permission denied постоянно.
    Во-вторых, данная настройка указана для серверов со стандартным портом, что бывает крайне редко, ибо не секьюрно, соответственно нужно еще указать порт, основная часть серверов живут за nat.
    В-третьих, нужно создать задание в кроне, которое будет проверять состояние подключения и восстанавливать его, при падении.
    Соответственно, шлюз:
    ssh -L 33061:localhost:3306 -i ‘/home/tunneluser/.ssh/id_rsa’ -p ‘53022’ ‘tunneluser@1.1.1.1’ -f -N
    задание в cron
    * * * * * nc -z localhost 3306 || ssh -f -i ‘/home/tunneluser/.ssh/id_rsa’ -p ‘53022’ ‘tunneluser@1.1.1.1’ -L 33061:localhost:3306 -N
    проверить состояние подключения, наличие туннеля, можно
    netstat -anp | grep :3306

Добавить комментарий