So konfigurieren Sie HAProxy für mehrere SSL-Zertifikate

8

Ich muss HAProxy mit zwei verschiedenen SSL-Zertifikaten konfigurieren

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

Jetzt habe ich aus einem Beitrag zu Serverfault ( Konfigurieren mehrerer SSL-Zertifikate in Haproxy ) gelernt, wie 2 Zertifikate verwendet werden. Der Server verwendet jedoch weiterhin das erste für beide Domänen erwähnte Zertifikat.

Konfiguration:

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 }
    ...

Wie kann ich HAProxy mitteilen, welches Zertifikat abhängig von der URL verwendet werden soll?

Vollständige Konfiguration:

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
quelle
Können Sie Ihre vollständige Konfiguration veröffentlichen?
GregL
sicher. Ich habe die Frage aktualisiert.
Merlin
In der oben abgebrochenen Konfiguration listen Sie zwei crtAnweisungen in Ihrer bindZeile auf, aber in der vollständigen Konfiguration haben Sie nur eine ... Ist das beabsichtigt? Hat dieses Zertifikat SAN-Einträge oder ist es ein Platzhalter?
GregL
Entschuldigung, ich habe die Konfiguration übernommen, nachdem ich die Zeile entfernt habe. Mein Ziel ist es, einzelne SSL-Zertifikate für einzelne Domains zuzulassen, und ich bin ziemlich neu in HAProxy. Das zweite Zertifikat in der oben aufgeführten Konfiguration wurde hinzugefügt.
Merlin
Welchen Client verwenden Sie, wenn er das falsche Zertifikat bereitstellt?
GregL

Antworten:

9

Stellen Sie sicher, dass Sie HAProxy 1.6 oder höher ausführen

Diese Frage ist etwas alt, aber ich bin auf genau dasselbe Problem mit Konfigurationen gestoßen, die dem OP ähnlich sind.

HAProxy 1.5 akzeptiert die Mehrfachsyntax crtfür eine bindOption. Bei der Beantwortung wird jedoch nur das erste Zertifikat verwendet.

HAProxy 1.6 scheint auf der Grundlage der Anfrage des Anrufers mit dem Zertifikat zu antworten. Dies scheint keine speziellen sniACLs in der Konfiguration zu erfordern .

Hier ist ein Beispiel, das unter 1.6 funktioniert, jedoch nicht verwendet wird, cert2.pemwenn auf Anfragen nach place2.com1.5 geantwortet wird:

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
quelle
2

Wie testen Sie, welches Zertifikat Haproxy präsentiert? Wenn Sie verwenden openssl s_client, -servername api.domain.combeachten Sie, dass ein zusätzlicher Parameter ( ) erforderlich ist, um die SNI-Informationen zu senden, die Haproxy benötigt, um zu entscheiden, welches Zertifikat präsentiert werden soll.

womble
quelle
Ich bin mir nicht sicher, ob ich Ihre Antwort verstehe. Das oben erwähnte Beispiel verwendet die folgende Zeile: use_backend bk_cert1 if {ssl_fc_sni my.example.com} Ich habe jedoch ein Backend für beide deaktiviert und Apache so konfiguriert, dass anhand der URL unterschieden wird, was zu tun ist. Sind mehrere SSL-Zertifikate mit einem Backend möglich?
Merlin
1
Ja, du verstehst meine Antwort nicht. Ich bezweifle Ihre Testmethode, nicht Ihre aktuelle Konfiguration.
womble
Soweit ich weiß, gibt es in der von mir vorgestellten Konfiguration nicht viele Tests. Es wird nur getestet, ob die angegebene Domain https durchlaufen hat oder nicht, und wenn nicht, wird sie zu https umgeleitet. Das ist aber nicht die Frage. Ich frage mich, wie ich bestimmte Zertifikate einer entsprechenden URL zuweisen kann.
Merlin
3
"Der Server verwendet jedoch weiterhin das erste erwähnte Zertifikat für beide Domänen" - auf welcher Grundlage wird diese Behauptung in Ihrer Frage, wenn nicht in Ihren eigenen Tests, erstellt?
Womble