Comment configurer HAProxy pour plusieurs certificats SSL

8

J'ai besoin de configurer HAProxy avec deux certificats SSL différents

  1. www.example.com
  2. api.example.com

Maintenant, j'ai appris d'un article sur serverfault ( Configurer plusieurs certificats SSL dans Haproxy ) comment utiliser 2 certificats, mais le serveur continue d'utiliser le premier certificat mentionné pour les deux domaines.

Config:

frontend apache-https
    bind 192.168.56.150:443 ssl crt /certs/crt1.pem crt /certs/cert2.pem
    reqadd X-Forwarded-Proto:\ https
    default_backend apache-http

backend apache-http
    redirect scheme https if { hdr(Host) -i www.example.com } !{ ssl_fc }
    redirect scheme https if { hdr(Host) -i api.example.com } !{ ssl_fc }
    ...

Comment dire à HAProxy quel certificat utiliser en fonction de l'URL?

Configuration complète:

global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

    # Default SSL material locations
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private

    ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
    ssl-default-bind-options no-sslv3
    tune.ssl.default-dh-param 2048 // better with 2048 but more processor intensive

defaults
        log     global
        mode    http
        option tcplog
        option  dontlognull
        timeout connect 5000
        timeout client  50000
        timeout server  50000

frontend apache-http
        bind 0.0.0.0:80
        mode http
        option http-server-close                # needed for forwardfor
        option forwardfor                       # forward IP Address of client
        reqadd X-Forwarded-Proto:\ http
        default_backend apache-http
        stats enable

frontend apache-https
        bind 0.0.0.0:443 ssl crt cer1.pem cert2.pem
        reqadd X-Forwarded-Proto:\ https
        default_backend apache-http

backend apache-http
        redirect scheme https if { hdr(Host) -i db.example.com } !{ ssl_fc }
        redirect scheme https if { hdr(Host) -i api2.example.com } !{ ssl_fc }
        balance roundrobin
        cookie SERVERID insert indirect nocache
        server www-1 10.0.0.101:80 cookie S1 check
        server www-2 10.0.0.102:80 cookie S2 check
        server www-3 10.0.0.103:80 cookie S3 check
Merlin
la source
Pouvez-vous publier votre configuration complète?
GregL
sûr. J'ai mis à jour la question.
merlin
Dans la configuration ci-dessus, vous listez deux crtdirectives sur votre bindligne, mais dans la configuration complète, vous n'en avez qu'une ... Est-ce prévu? Ce certificat a-t-il des entrées SAN ou est-ce un caractère générique?
GregL
désolé mon erreur, j'ai pris la config après avoir supprimé la ligne. Mon objectif est d'autoriser les certificats SSL individuels pour les domaines individuels et je suis assez nouveau pour HAProxy. Ajout du deuxième certificat dans la configuration listée ci-dessus.
merlin
Quel client utilisez-vous lorsqu'il fournit le mauvais certificat?
GregL

Réponses:

9

Assurez-vous que vous exécutez HAProxy 1.6 ou supérieur

Cette question est un peu ancienne, mais j'ai rencontré exactement le même problème avec des configurations similaires à l'OP.

HAProxy 1.5 accepte la crtsyntaxe multiple sur une bindoption; cependant, il utilise uniquement le premier certificat lors de la réponse.

HAProxy 1.6 semble répondre avec le certificat basé sur la demande de l'appelant. Cela ne semble pas nécessiter de snilistes de contrôle d' accès spéciales dans la configuration.

Voici un exemple qui fonctionne sur 1.6, mais ne parvient pas à utiliser cert2.pemlors de la réponse aux demandes place2.comsur 1.5:

frontend http-in
        bind *:80
        bind *:443 ssl crt cert1.pem crt cert2.pem
        mode http

        acl common_dst hdr(Host) -m str place1.com place2.com

        use_backend be_common if common_dst

backend be_common
        # nothing special here.
davidzarlengo
la source
2

Comment testez-vous le certificat présenté par haproxy? Si vous utilisez openssl s_client, -servername api.domain.comsachez qu'il nécessite un paramètre supplémentaire ( ) pour envoyer les informations SNI dont haproxy a besoin pour décider quel certificat présenter.

womble
la source
Je ne sais pas si je comprends votre réponse. L'exemple mentionné ci-dessus utilise la ligne: use_backend bk_cert1 if {ssl_fc_sni my.example.com} mais je ne décompose pas un backend pour les deux et je configure apache pour distinguer en fonction de l'URL ce qu'il faut faire. Plusieurs certificats SSL sont-ils possibles avec un seul backend?
merlin
1
Oui, vous ne comprenez pas ma réponse. Je doute de votre méthodologie de test, pas de votre configuration actuelle.
womble
Pour autant que je sache, il n'y a pas beaucoup de tests dans la configuration que j'ai présentée. La seule chose qu'il teste est de savoir si le domaine spécifié est passé par https ou non et sinon il redirige vers https. Mais ce n'est pas la question. Je me demande comment dédier des certificats spécifiques à une URL correspondante.
merlin
3
"cependant, le serveur continue d'utiliser le premier certificat mentionné pour les deux domaines" - sur quoi repose cette affirmation dans votre question, sinon vos propres tests?
womble