- Modifié
Salut a tous,
Pour faire suite a ma question d'ici et apres avoir mis ca en place, je me suis dit pourquoi ne pas en faire un tuto. Je ne vais pas rentrer ici dans les details en ce qui concerne l'obtention du certificat, la configuration d'apache pour le https ou la configuration d'autres logiciels mais juste presenter le concept et comment mettre ca en place (par contre il faudra que vous fassiez d'autres recherches pour la configuration complete des logiciels). Je ne presente ici que le concept et les etapes strictement necessaires, a vous de regarder plus en detail les parametrages de chaque logiciel utilise.
Je presente ici la methode que moi j'ai trouve la plus logique et la plus simple a mettre en place (ce ne sera peut etre pas le cas pour vous), et meme si ce n'est peut etre pas la meilleure methode, d'apres les quelques tests que j'ai fais, ca marche (mon certificat a ete auto-renouvelle il y a quelques jours sans meme que je ne m'en apercoive)
Comme je l'ai mentionne dans ma question l'idee est d'avoir plusieurs serveurs qui hebergent le meme nom de domaine, c'est a dire que l'on va avoir dans la definition du DNS :
domaine.fr IN A 1.1.1.1
domaine.fr IN A 1.1.1.2
serv1.domaine.fr IN A 1.1.1.1
serv2.domaine.fr IN A 1.1.1.2
letsencrypt.domaine.fr IN A 1.1.1.1
Ce qui veux dire que sur serv1 et serv2 tourne un serveur web (Apache2 dans mon cas) et le serveur DNS va rediriger les clients souhaitant se connecter a domaine.fr soit vers serv1 soit vers serv2 et tout les 2 doivent pouvoir repondre en HTTPS (ici dans l'exemple il n'y a que 2 serveurs, mais c'est realisable egalement avec plus de 2 serveurs). Le sous-domaine letsencrypt.domaine.fr est redirige vers serv1 (ce sera le serveur « maitre » pour le renouvellement du certificat).
INSTALLATION DE CERTBOT (aussi connu sous le nom de letsencrypt)
Cette operation est a faire uniquement sur un des serveurs (qui sera considere comme « maitre », alors que les autres seront consideres comme « esclaves »), dans mon cas c'est sur serv1. Personnellement j'ai installe certbot depuis les depots backports de Debian Jessie.
On rajoute le depot backports au fichier sources.list :
# vim /etc/apt/sources.list
#jessie-backports
deb http://ftp.fr.debian.org/debian jessie-backports main
On fait un update et on install le paquet certbot depuis le depot backports :
# apt-get update && apt-get install certbot -t jessie-backports
CONFIGURATION DU SERVEUR WEB (apache2 dans mon cas)
Je ne vais pas presenter ici l'installation et la configuration d'apache, mais uniquement la partie qui nous interesse, notamment celle liee a l'obtention et le renouvellement du certificat.
Sur serv1 (le « maitre ») :
On cree les dossiers necessaires :
# mkdir -p /var/www/domaine.fr/www
# mkdir -p /var/www/domaine.fr/letsencrypt/.well-known/acme-challenge
On modifie le fichier de configuration d'apache :
# vim /etc/apache2/sites-available/000-default.conf
<VirtualHost 1.1.1.1:80>
ServerName domaine.fr
ServerAlias www.domaine.fr
ServerAlias serv1.domaine.fr
ServerAdmin webmaster@domaine.fr
DocumentRoot /var/www/domaine.fr/www
ProxyPass "/.well-known/acme-challenge/" "http://letsencrypt.domaine.fr/.well-known/acme-challenge/"
ErrorLog ${APACHE_LOG_DIR}/domaine.fr/www/error.log
CustomLog ${APACHE_LOG_DIR}/domaine.fr/www/access.log combined
</VirtualHost>
<VirtualHost 1.1.1.1:80>
ServerName letsencrypt.domaine.fr
ServerAdmin webmaster@domaine.fr
DocumentRoot /var/www/domaine.fr/letsencrypt
<Directory />
Order Deny,Allow
Deny from all
Allow from 1.1.1.1 # on autorise uniquement serv1 et
Allow from 1.1.1.2 # serv2 a acceder a letsencrypt.domaine.fr
</Directory>
<Directory "/var/www/domaine.fr/letsencrypt/.well-known/acme-challenge/">
Options +MultiViews +Indexes +SymLinksIfOwnerMatch +IncludesNoExec
Require method GET POST OPTIONS
</Directory>
ErrorLog ${APACHE_LOG_DIR}/domaine.fr/letsencrypt/error.log
CustomLog ${APACHE_LOG_DIR}/domaine.fr/letsencrypt/access.log combined
</VirtualHost>
A present sur serv2 :
On modifie le fichier /etc/apache2/sites-available/000-default.conf :
# vim /etc/apache2/sites-available/000-default.conf
<VirtualHost 1.1.1.2:80>
ServerName domaine.fr
ServerAlias www.domaine.fr
ServerAlias serv2.domaine.fr
ServerAdmin webmaster@domaine.fr
DocumentRoot /var/www/domaine.fr/www
ProxyPass "/.well-known/acme-challenge/" "http://letsencrypt.domaine.fr/.well-known/acme-challenge/"
ErrorLog ${APACHE_LOG_DIR}/domaine.fr/www/error.log
CustomLog ${APACHE_LOG_DIR}/domaine.fr/www/access.log combined
</VirtualHost>
Donc ce qu'on a fait la c'est : lorsqu'un client solicite http://domaine.fr/.well-known/acme-challenge (ce que Let's Encrypt fait lors de l'obtention ou du renouvellement du certificat) ou ses equivalents (www.domaine.fr, serv1.domaine.fr, serv2.domaine.fr) il sera redirige vers http://letsencrypt.domaine.fr/.well-known/acme-challenge, la ou se trouveront les fichiers de verification de certbot au moment de l'obtention ou du renouvellement du certificat.
OBTENTION DU CERTIFICAT
Maintenant que le serveur web est configure et que le paquet certbot est installe sur serv1 on peut executer la commande d'obtention du certificat (a nouveau uniquement sur serv1) :
# certbot certonly --rsa-key-size 4096 --webroot -w /var/www/domaine.fr/letsencrypt/ -d domaine.fr -d www.domaine.fr -d serv1.domaine.fr -d serv2.domaine.fr --email moi@domaine.fr –agree-tos
Normalement si tout c'est bien passe vous devrier avoir vos certificats dans /etc/letsencrypt/live/domaine.fr/ (qui en realite sont des liens symboliques vers /etc/letsencrypt/archive/domaine.fr/
Le soucis a present est que le certificat ne se trouve que sur serv1, il faut donc trouver un moyen de l'envoyer sur serv2. A noter que l'idee ici est que le certificat doit se trouver sur serv1 ET sur serv2 ; il ne faut pas uniquement donner acces a serv2 au certificat sur serv1. En plus clair, ca veut dire qu'il faut trouver un moyen de copier les certificats sur serv2, car si on ne fait que lui donner acces au certificats sur serv1, si serv1 est HS, serv2 ne pourra pas acceder aux certificats et ne pourra donc pas servir le site en HTTPS.
La solution que j'ai trouve dans ce cas est de faire un rsync entre serv1 et serv2 pour synchroniser le dossier /etc/letsencrypt.
MISE EN PLACE DE LA SYNCHRONISATION
Sur serv2 il faut installer rsync et le configurer (a vous de regarder comment lancer le demon au lancement du systeme) :
# apt-get install rsync
# vim /etc/rsyncd.conf
log file = /var/log/rsyncd/rsyncd
pid file = /var/run/rsyncd.pid
secrets file = /etc/rsyncd.secrets
[letsencrypt]
comment = Letsencrypt
path = /etc/letsencrypt
read only = no
list = no
auth users = root
max connections = 4
lock file = /var/run/rsyncd.letsencrypt.lock
uid = root
gid = root
transfer logging = yes
Rajouter l'utilisateur root et un mot de passe :
# vim /etc/rsyncd.secrets
root:p4$$wd
Je vous laisse regarder du cote de rsync et rsyncd pour plus de parametres.
Il faut egalement créer le dossier /etc/letsencrypt sur serv2 :
# mkdir /etc/letsencrypt
Sur serv1 on va installer rsync et creer quelques fichiers.
Installation de rsync
# apt-get install rsync
Le script qui fera la synchronisation a proprement parler (modifier la valeur SERVER avec l'ip de serv2 dans le script) :
# vim /root/.certbot/rsync
#!/bin/bash
SERVER="1.1.1.2"
TMP_FILE="/var/log/letsencrypt/rsync"
PING="`/bin/ping -q -c 1 $SERVER | grep received | awk '{print $4}'`"
PID="/tmp/rsync-letsencrypt.pid"
if [ -f $PID ]; then
exit
fi
touch $PID
while [ "$PING" != "1" ]; do
sleep 10
PING="`/bin/ping -q -c 1 $SERVER | grep received | awk '{print $4}'`"
done
RSYNC="`which rsync`"
if [ -z $RSYNC ]; then
echo "rsync non installe" > $TMP_FILE
if [ -f $PID ]; then
rm -f $PID
fi
exit
fi
$RSYNC -n -r -t -p -o -g -v --progress --delete -l -H --password-file=/root/.certbot/rsync_passwd --exclude-from="/root/.certbot/rsync_exclude" --bwlimit=20000 /etc/letsencrypt/ root@$SERVER::letsencrypt >> $TMP_FILE
if [ "$?" != "0" ]; then
echo "Probleme lors de l'execution de rsync letsencrypt" >> $TMP_FILE
fi
if [ -f $PID ]; then
rm -f $PID
fi
Et on le rend executable :
# chmod +x /root/.certbot/rsync
On cree ensuite le fichier de mot de passe pour rsync et on y met le mot de passe defini sur serv2 (uniquement le mot de passe, pas l'utilisateur) :
# vim /root/.certbot/rsync_passwd
p4$$wd
Et le fichier d'exclusion (se sont des dossiers qui se trouvent sur serv1 et dont serv2 n'a pas besoin) :
# vim /root/.certbot/rsync_exclude
accounts
csr
keys
renewal
Donc pour resumer, on a cree l'acces rsync pour que serv1 puisse synchroniser /etc/letsencrypt avec celui de serv2. Maintenant il faut trouver un moyen pour executer le script /root/.certbot/rsync lorsque le certificat est renouvele (si vous avez installe certbot depuis le depot backports, le renouvelement se fait automatiquement, vous n'avez rien a parametrer, a vous de voir si c'est le cas chez vous). Et la solution dans ce cas est inotify-tools et notamment inotifywait qui permet de surveiller un dossier et executer une commande lors d'une activite sur ce dossier (creation, suppression, etc). Il faut donc installer ce paquet :
# apt-get install inotify-tools
Et creer le script /root/.certbot/certbot qui permet de lancer la surveillance du dossier /etc/letsencrypt et lancer les commandes /root/.certbot/services et /root/.certbot/rsync
# vim /root/.certbot/certbot
#!/bin/bash
sleep 60
while true
do
inotifywait -qr -o /var/log/letsencrypt/inotifywait -e modify,move,create,delete /etc/letsencrypt && sleep 60 && /root/.certbot/services && /root/.certbot/rsync
done
Ainsi que le script /root/.certbot/services qui recharge la configuration des logiciels utilisant le certificat une fois le renouvellement realise :
# vim /root/.certbot/services
#!/bin/bash
systemctl reload apache2 &
Dans mon cas je recharge apache2 pour qu'il prenne en compte le nouveau certificat (si vous configurez d'autres services pour qu'ils utilisent le certificat letsencrypt, n'oubliez pas de les rajouter ici).
On rend les 2 scripts executables :
# chmod +x /root/.certbot/services
# chmod +x /root/.certbot/rsync
Et enfin en tant que root on fait un :
# crontab -e
@reboot /bin/bash /root/.certbot/certbot &
Pour lancer le script /root/.certbot/certbot au demmarage du serveur.
Sur serv2 il faut refaire a peu pres les memes etapes :
Le script /root/.certbot/services qui permettra de recharger la configuration des logiciels utilisant le certificat :
# vim /root/.certbot/services
#!/bin/bash
systemctl reload apache2 &
Installation de inotify-tools
# apt-get install inotify-tools
Creation du script certbot qui permet de surveiller /etc/letsencrypt pour lancer le script /root/.certbot/services lorsque serv1 aura synchronise son dossier /etc/letsencrypt avec celui de serv2
# vim /root/.certbot/certbot
#!/bin/bash
sleep 60
while true
do
inotifywait -qr -o /var/log/letsencrypt/inotifywait -e modify,move,create,delete /etc/letsencrypt && sleep 60 && /root/.certbot/services
done
On les rends executables :
# chmod +x /root/.certbot/services
# chmod +x /root/.certbot/rsync
Et on rajoute le script /root/.certbot/certbot a crontab pour qu'il se lance au demarrage du serveur :
# crontab -e
@reboot /bin/bash /root/.certbot/certbot &
Il ne reste plus qu'a redemmarer les 2 serveurs.
CONCLUSION
La logique a suivre ici est :
Les serveurs serv1 et serv2 demarrent, et grace au crontab @reboot lance le script /root/.certbot/certbot sur chacune des machines (a chaque redemarrage)
Le moment venu, le certificat est renouvelle par certbot sur serv1 et le nouveau certificat se retrouve dans /etc/letsencrypt/ sur serv1
Les scripts /root/.certbot/services et /root/.certbot/rsync sur serv1 sont lances car il y a eu une modification dans le dossier /etc/letsencrypt sur serv1 ; le premier script recharge la configuration des logiciels utilisant le certificat et le second lance la synchronisation vers serv2
Une fois ces etapes franchi, tout est en place sur serv1, il ne reste maintenant que serv2
Lorsque la synchronisation a ete effectuee sur serv2, le script /root/.certbot/services est lance (au travers de inotifywait) pour recharger les services qui utilisent le certificat
Le nouveau certificat se trouve a present sur les 2 serveurs et les services utilisant ce certificat peuvent a present offrir un acces securise
Dans ce tuto je ne suis pas rentre dans les details, a vous donc de paramtrer apache2 ou nginx pour l'utilisation du https (et peut etre utiliser un vpn entre les 2 serveurs afin que le rsync ne se fasse pas en clair mais au travers du vpn).
Comme je l'ai dit au debut du tuto, mon certificat a ete renouvelle automatiquement sur les 2 serveurs il y a quelques jours, donc on peut dire que ca marche ; si ca ne marche pas pour vous regardez les differents logs (apache, rsync, scripts…), soit vous n'avez pas suivis toutes les etapes, soit vous etes tombez sur une situation que je n'ai pas prevu.
J'espere avoir ete clair dans mes explications (?) et que mon barratin est comprehensible
Pour toute question, remarque, amelioration a apporter, direction le topic initial.