fragen stichworte

Wie können mehrere SSL-Zertifikate für den virtuellen Standardhost auf NGINX bereitgestellt werden?

Ich habe eine statische App für Amazon S3, die über einen NGINX-Proxy bereitgestellt wird. Ich benutze einen Proxy, um Benutzern zu ermöglichen, ihre Domains auf meine Amazon EC2-Instanz (über einen CNAME-Datensatz, der auf custom-domain.myproduct.com zeigt) zu verweisen, sodass sie über ihre eigene benutzerdefinierte URL auf meine App zugreifen können:

Um dies zu erreichen, habe ich die folgende Nginx-Konfiguration (Teile wurden der Kürze halber entfernt):

http {
    server {
    # This is my default route. References:
    # http://stackoverflow.com/a/15799883/91403
    # http://nginx.org/en/docs/http/request_processing.html

    listen 80 default_server;
    server_name custom-domain.myproduct.com;
    location/{
        proxy_pass http://static.myproduct.com; # points to Amazon S3
        proxy_set_header Host myproduct.com;
    }
}

Obwohl meine statische App zu 100% öffentlich ist (kein Clientgeheimnis, nur HTML und Javascript), möchten einige meiner Kunden über SSL darauf zugreifen. Wie kann ich basierend auf dem Hostheader dynamisch auswählen, welches Zertifikat für die SSL-Verbindung verwendet werden soll? Beachten Sie, dass ich den Zertifizierungspfad nicht einfach hardcodieren kann.

PS: Kunden können ihre Zertifikate in meine Instanz
hochladen PS2: Dieses Setup funktioniert bereits einwandfrei nur mit HTTP.

Was ich versucht habe

Ich habe so etwas versucht, ohne Erfolg:

server {
    listen 443 default_server;
    server_name custom-domain.myproduct.com;
    ssl on;
    ssl_certificate/etc/nginx/ssl/$http_host/server.crt; # note the http_host variable
    ssl_certificate_key/etc/nginx/ssl/$http_host/server.key; # also here
}

antworten

How can I dynamically choose which certificate to use for the SSL connection based on the Host header?

Der Host-Header ist Teil des HTTP-Protokolls, aber HTTPS ist HTTP, das in eine SSL-Verbindung eingebettet ist. Das bedeutet, dass Sie zuerst die SSL-Verbindung herstellen müssen (die das Zertifikat benötigt), bevor Sie auf den Host-Header zugreifen können.

Wenn der Client SNI unterstützt (alle modernen Browser tun dies, aber IE/XP nicht), wird der Zielname bereits innerhalb des SSL-Handshakes gesendet. Die Bereitstellung verschiedener Zertifikate basierend auf dem Zielnamen erfolgt normalerweise mit unterschiedlichen Serverabschnitten in nginx. Sie könnten versuchen, das $ssl_server_name innerhalb des Standardbereichs zu verwenden, aber ich bin mir nicht sicher, ob das funktioniert und selbst wenn dies funktioniert, könnte dies negative Auswirkungen auf Optimierungen wie Session-Caching haben.