Il y a 389 articles et 19 utilisateurs inscrits (ce bandeau est défini dans MediaWiki:Sitenotice)

Ajouter un nouveau domaine HTTPS dans HAProxy

De AJLSM
Aller à la navigation Aller à la recherche

Ajouter un nouveau domaine HTTPS dans HAProxy

Cette procédure décrit l'ajout complet d'un nouveau domaine HTTPS dans les deux reverse proxy HAProxy AJLSM. Voir aussi : WAF_2026 Exemple utilisé dans cette documentation :

new-earchives.le64.fr

Backend Apache :

10.0.0.41

La procédure couvre :

  • l'ajout du domaine dans la configuration Ansible HAProxy ;
  • la prise en compte du SNI vers le serveur Apache ;
  • la vérification et le déploiement de la configuration HAProxy ;
  • la vérification du challenge ACME ;
  • la création du certificat Let's Encrypt sur les deux HAProxy ;
  • le déploiement du certificat dans /etc/haproxy/certs ;
  • le test HTTPS final.

Important :

Le DNS doit déjà pointer vers l'IP publique qui aboutit sur l'IP virtuelle HAProxy 10.0.0.32.

Le serveur Apache backend doit également disposer d'un VirtualHost correspondant au domaine sur le port 443.

Dans l'exemple :

<VirtualHost *:443>
    ServerName new-earchives.le64.fr
    ...
</VirtualHost>

1. Ajouter le domaine dans haproxy.yml

La configuration HAProxy est gérée par Ansible.

Le fichier source est :

inventory/group_vars/ajlsm_loadbalancer/haproxy.yml

Ne pas modifier directement /etc/haproxy/haproxy.cfg sur les HAProxy : ce fichier est généré par Ansible.

ACL et sélection du backend

Dans le bloc frontend front_web, ajouter les ACL correspondant au nouveau domaine.

Exemple :

acl host_ssl_new_earchives_ad64 hdr(host) -i new-earchives.le64.fr
use_backend back_ssl_new_earchives_ad64 if host_ssl_new_earchives_ad64

Si le HTTP doit être redirigé vers HTTPS, ajouter également la règle prévue dans la configuration :

http-request redirect scheme https if { hdr(Host) -i new-earchives.le64.fr } !{ ssl_fc }

Les éventuelles restrictions d'accès par IP doivent être ajoutées ici selon les besoins du domaine.

2. Créer le backend HTTPS

Ajouter le backend correspondant :

backend back_ssl_new_earchives_ad64
        server SSLNEWEARCHIVESAD64 10.0.0.41:443 check ssl verify none sni str(new-earchives.le64.fr)

Attention au paramètre SNI.

Le paramètre :

sni str(new-earchives.le64.fr)

est nécessaire lorsque le serveur Apache backend héberge plusieurs VirtualHost HTTPS sur la même adresse IP.

Sans SNI, HAProxy ouvre bien une connexion TLS vers 10.0.0.41:443, mais Apache peut sélectionner son VirtualHost SSL par défaut.

Lors de la mise en place d'AD64, l'absence de SNI a provoqué :

HTTP 421 Misdirected Request

Un test direct avait montré qu'une requête vers l'IP du backend sans SNI présentait le certificat du VirtualHost Apache par défaut.

En revanche :

curl -vkI \
  --resolve new-earchives.le64.fr:443:10.0.0.41 \
  https://new-earchives.le64.fr/

force le bon nom lors de la négociation TLS et permet de vérifier que le bon VirtualHost Apache répond.

3. Vérifier la configuration avec Ansible

Depuis le poste disposant du projet Ansible, se placer à la racine du projet.

Faire d'abord une simulation avec affichage des différences :

ansible-playbook ./plays/deploy.haproxy.yml \
  -l ajlsm_loadbalancer \
  --check --diff

Vérifier attentivement le diff.

Aucune modification n'est effectuée sur les HAProxy avec --check.

4. Déployer la configuration

Si le diff est correct :

ansible-playbook ./plays/deploy.haproxy.yml \
  -l ajlsm_loadbalancer

Le playbook déploie la configuration sur les deux HAProxy et la valide avant son activation.

On peut effectuer une validation supplémentaire :

ansible ajlsm_loadbalancer -b -m shell -a \
'haproxy -c -f /etc/haproxy/haproxy.cfg'

Le résultat attendu sur les deux machines est :

Configuration file is valid

Remarque :

Une validation lancée directement avec l'utilisateur non privilégié peut produire une erreur lors de la lecture de :

/etc/haproxy/certs/

Cela ne signifie pas nécessairement que la configuration HAProxy est incorrecte.

Pour cette raison, la validation ci-dessus est exécutée avec -b (become/root).

5. Vérifier le challenge ACME

HAProxy traite directement les challenges ACME HTTP-01 en mode stateless.

Avant de demander le certificat, vérifier que le domaine arrive bien jusqu'au HAProxy :

curl -s \
  http://new-earchives.le64.fr/.well-known/acme-challenge/test123

Une réponse de la forme suivante doit être obtenue :

test123.<ACCOUNT_THUMBPRINT>

Si cette réponse n'est pas obtenue, ne pas lancer la génération du certificat.

Il faut d'abord vérifier le DNS, le NAT et l'arrivée du trafic HTTP sur HAProxy.

6. Générer le certificat Let's Encrypt

Important : cette opération doit être réalisée séquentiellement sur HAPROXY-01 puis HAPROXY-02.

Les certificats HAProxy sont gérés avec acme.sh sous l'utilisateur acme.

Sur le premier HAProxy :

sudo -u acme /usr/local/share/acme.sh/acme.sh \
  --home /var/lib/acme/.acme.sh \
  --issue \
  --stateless \
  --server letsencrypt \
  --keylength ec-256 \
  -d new-earchives.le64.fr

Attendre que l'émission du certificat soit terminée.

7. Déployer le certificat dans HAProxy

Une fois le certificat obtenu :

sudo -u acme env \
  DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy/certs \
  DEPLOY_HAPROXY_HOT_UPDATE=yes \
  /usr/local/share/acme.sh/acme.sh \
  --home /var/lib/acme/.acme.sh \
  --deploy \
  --ecc \
  -d new-earchives.le64.fr \
  --deploy-hook haproxy

Le certificat HAProxy doit alors exister sous :

/etc/haproxy/certs/new-earchives.le64.fr.pem

Vérification :

ls -l /etc/haproxy/certs/new-earchives.le64.fr.pem

Erreur rencontrée : mauvais répertoire de déploiement

Lors de la première mise en place, le hook HAProxy a essayé de créer le certificat directement sous :

/etc/haproxy/new-earchives.le64.fr.pem

au lieu de :

/etc/haproxy/certs/new-earchives.le64.fr.pem

Le déploiement a alors échoué avec une erreur de permission.

La solution consiste à fournir explicitement au hook :

DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy/certs
DEPLOY_HAPROXY_HOT_UPDATE=yes

d'où la commande complète utilisée ci-dessus.

Lors du premier déploiement réussi, ces paramètres sont enregistrés par acme.sh pour le domaine et peuvent ensuite être réutilisés lors des renouvellements automatiques.

8. Répéter sur le deuxième HAProxy

Répéter les deux opérations sur HAPROXY-02 :

sudo -u acme /usr/local/share/acme.sh/acme.sh \
  --home /var/lib/acme/.acme.sh \
  --issue \
  --stateless \
  --server letsencrypt \
  --keylength ec-256 \
  -d new-earchives.le64.fr

puis :

sudo -u acme env \
  DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy/certs \
  DEPLOY_HAPROXY_HOT_UPDATE=yes \
  /usr/local/share/acme.sh/acme.sh \
  --home /var/lib/acme/.acme.sh \
  --deploy \
  --ecc \
  -d new-earchives.le64.fr \
  --deploy-hook haproxy

Vérifier :

ls -l /etc/haproxy/certs/new-earchives.le64.fr.pem

Le certificat doit impérativement être présent sur les deux HAProxy afin que le service continue à fonctionner correctement lors d'une bascule entre les deux nœuds.

9. Tester le domaine en HTTPS

Depuis un poste extérieur ou le poste d'administration :

curl -I https://new-earchives.le64.fr/

Le résultat attendu est une réponse HTTP normale de l'application, par exemple :

HTTP/2 200

Le chemin complet testé est alors :

Internet
   |
   v
IP publique / NAT
   |
   v
HAProxy 10.0.0.32
   |
   | TLS public : certificat Let's Encrypt HAProxy
   v
backend SSL + SNI new-earchives.le64.fr
   |
   v
Apache 10.0.0.41:443
   |
   v
VirtualHost new-earchives.le64.fr

10. Diagnostic rapide

Si le challenge ACME ne répond pas :

  • vérifier que le DNS pointe vers la bonne IP publique ;
  • vérifier le NAT vers 10.0.0.32 ;
  • vérifier que le port 80 arrive sur HAProxy.

Si Let's Encrypt fonctionne mais que HAProxy ne trouve pas le certificat :

  • vérifier /etc/haproxy/certs/new-earchives.le64.fr.pem ;
  • vérifier DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy/certs.

Si HTTPS répond avec :

421 Misdirected Request

vérifier en priorité le SNI du backend :

sni str(new-earchives.le64.fr)

et vérifier directement le VirtualHost Apache :

curl -vkI \
  --resolve new-earchives.le64.fr:443:10.0.0.41 \
  https://new-earchives.le64.fr/

Si le test direct fonctionne mais pas le test public, rechercher le problème entre HAProxy et le backend.

Si le test final fonctionne :

curl -I https://new-earchives.le64.fr/

et retourne la réponse attendue, la publication HTTPS du nouveau domaine via HAProxy est opérationnelle.