Réplication MySQL avec un tunnel SSH

La réplication MySQL (maître-esclave ou maître-maître) peut être très utile pour l’utilisation de loadbalancing sur un service web. Par contre, l’utiliser via un tunnel SSH est bien plus sécurisé.

Dans la suite de l’article, on parlera de maître avec l’adresse ip 1.1.1.1 et d’esclave avec l’adresse 2.2.2.2.

On va d’abord créer sur le maître un utilisateur qui permettra de lier les 2 serveurs entre eux.

useradd -d /home/tunnel -m tunnel
passwd tunnel

On ajoute ensuite cet utilisateur à se connecter uniquement depuis l’esclave

nano /etc/ssh/sshd_config

Ajouter l’utilisateur à la directive AllowUsers (ou créez là si elle n’existe pas).

AllowUsers tunnel@2.2.2.2

Redémarrez le service ssh

service ssh restart

Sur l’esclave, nous allons générer une clé qui sera le lien sécurisé entre nos serveurs. N’entrez pas de passphrase pour cette clé.

ssh-keygen

On va maintenant copier cette clé vers le serveur maître. On tape donc, dans la console de l’esclave

ssh-copy-id tunnel@1.1.1.1

Tapez yes pour la mémorisation de la clé du maître puis tapez le mot de passe de l’utilisateur. C’est pas mal de vérifier que la connexion est bonne avec la commande ssh suivante depuis l’esclave :

ssh tunnel@1.1.1.1

Normalement vous devriez être dans le shell de l’utilisateur tunnel (donc sur le serveur maître).

On va maintenant supprimer le shell de l’utilisateur ainsi que son mot de passe sur le maître

usermod -s /usr/sbin/nologin tunnel
passwd -d tunnel

On va maintenant créer le tunnel sur la console esclave via la commande

ssh -L 33061:localhost:3306 tunnel@1.1.1.1 -f -N

On créé sur l’esclave le port 33601 qui est l’image du port 3306 du maître. Le « -f » sert à mettre le tunnel en background et le « -N » interdit l’exécution de commande via le tunnel.

Dans PHPMyadmin, sur le maître, allez dans l’onglet « réplication ».

Configurez le maître, indiquez quelle table répliquer.

Ouvrez le fichier de configuration de MySQL

nano /etc/mysql/my.cnf

Rajoutez les quelques lignes indiquées par PHPMyadmin. Dans mon cas, il s’agit de :

server-id=40835
log-bin=mysql-bin
log-error=mysql-bin.err
binlog_do_db=test

Veillez à intégrer ces lignes dans la directive [mysqld]. Vous noterez également que le bind est fait sur 127.0.0.1 et non l’adresse ip publique du serveur (ni l’utilisation de localhost).

[mysqld]
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
...
bind-address = 127.0.0.1
server-id=40835
log-bin=mysql-bin
log-error=mysql-bin.err
binlog_do_db=test

Redémarrez MySQL

service mysql restart

Vous pouvez ensuite aller dans PHPMyadmin et exécuter la commande.

La page se recharge et vous avez le message : « Ce serveur est un serveur maître dans le processus de réplication. »

Maintenant, il faut créer un compte MySQL pour la réplication. Toujours dans PHPMyadmin côté maître, cliquer sur « Ajouter un utilisateur pour la réplication vers l’esclave » puis entrez les informations :

Nom d'utilisateur: slave
Client: 127.0.0.1
Mot de passe: le_mot_de_passe

Exportez également votre base à répliquer, nous allons la recharger dans l’esclave.

Dans l’esclave, nous allons commencer par importer la base du maître. Une fois la table importée, allez dans l’onglet « Réplication ».

Sélectionnez « Réplication esclave ».

Récupérez l’id donné par PHPMyadmin puis modifiez le fichier my.cnf en conséquence (toujours dans la partie [mysqld]) :

nano /etc/mysql/my.cnf 

N’oubliez pas de redémarrer le service

service mysql restart

Rafraichissez la page puis configurez l’esclave

Nom d'utilisateur: slave
Mot de passe : le_mot_de_passe
Client : 127.0.0.1
Port: 33601

Une fois cette partie configurée, vous devriez avoir 2 erreurs :

Le fil d'exécution SQL ne tourne pas sur le serveur esclave !
Le fil d'exécution IO ne tourne pas sur le serveur esclave !

En gros la configuration est faite mais la réplication n’est pas démarrée. Pour se faire, sélectionnez « Contrôler le serveur esclave > Démarrer complètement ».

Sur le maître, vous pouvez voir les esclaves connectés via « Réplication maître > Montrer les esclaves connectés ». Vous devriez voir l’id de votre serveur esclave.

Sur l’esclave, dans « Réplication esclave > Montrer l’état de l’esclave », la variable « Slave_IO_State » devrait indiquer : « Queueing master event to the relay log ».

Si vous ajoutez une ligne dans votre serveur maître, le serveur esclave devrait l’afficher.

Voilà, vous avez réalisé une réplication maître -> esclave. Notez que vous pouvez avoir autant d’esclaves que vous souhaitez.

Maintenant, on peut corser un peu les choses en faisant une réplication maître <-> maître.

Pour cela, on va créer un utilisateur tunnel sur le serveur esclave :

useradd -d /home/tunnel -m tunnel
passwd tunnel

On ajoute ensuite cet utilisateur à se connecter uniquement depuis le maître

nano /etc/ssh/sshd_config

Ajouter l’utilisateur à la directive AllowUsers (ou créez là si elle n’existe pas).

AllowUsers tunnel@1.1.1.1

Redémarrez le service ssh

service ssh restart

On va maintenant copier cette clé vers le serveur esclave. On tape donc, dans la console du maître

ssh-copy-id tunnel@2.2.2.2

Tapez yes pour la mémorisation de la clé du maître puis tapez le mot de passe de l’utilisateur. Comme précédemment, on va tester la connexion depuis le maître :

ssh tunnel@2.2.2.2

Normalement vous devriez être dans le shell de l’utilisateur tunnel. On va maintenant supprimer le shell de l’utilisateur ainsi que son mot de passe sur l’esclave

usermod -s /usr/sbin/nologin tunnel
passwd -d tunnel

On va maintenant créer le tunnel sur la console maître via la commande

ssh -L 33061:localhost:3306 tunnel@2.2.2.2 -f -N

On a maintenant 2 tunnels SSH :

  • Le premier tunnel copie le port 3306 du maître sur le port 33061 sur l’esclave.
  • Le second tunnel copie le port 3306 de l’esclave sur le port 33601 du maître.

Ouvrez le fichier de configuration de MySQL de l’esclave

nano /etc/mysql/my.cnf

Rajoutez les quelques lignes indiquées par PHPMyadmin lors de la première configuration SANS le server-id. Dans mon cas, il s’agit des lignes suivantes à rajouter dans la section [mysqld] :

log-bin=mysql-bin
log-error=mysql-bin.err
binlog_do_db=test

Enregistrez et redémarrez MySQL

service mysql restart

Maintenant, il faut créer un compte MySQL pour la réplication. Toujours dans PHPMyadmin côté esclave, cliquer sur « Ajouter un utilisateur pour la réplication vers l’esclave » puis entrez les informations :

Nom d'utilisateur: slave
Client: 127.0.0.1
Mot de passe: le_mot_de_passe

L’utilisateur peut être le même que la réplication maître -> esclave.

Allez ensuite dans la partie Réplication du serveur maître puis renseignez les information de Réplication esclave

Nom d'utilisateur: slave
Mot de passe : le_mot_de_passe
Client : 127.0.0.1
Port: 33601

Vous pouvez exécuter la commande.

Normalement votre installation est configurée :

  • si vous rajoutez une ligne sur le maître, l’esclave rajoute seul la ligne
  • si vous rajoutez une ligne sur l’esclave, le maître rajoute la ligne