
Ich habe eine statische App auf Amazon S3, die über einen NGINX-Proxy bereitgestellt wird. Ich verwende einen Proxy, um Benutzern zu ermöglichen, ihre Domänen auf meine Amazon EC2-Instanz zu verweisen (über einen CNAME-Eintrag, der auf verweist custom-domain.myproduct.com
), damit sie über ihre eigene benutzerdefinierte URL wie diese auf meine App zugreifen können: myproduct.happyclient.com
.
Um dies zu erreichen, habe ich die folgende Nginx-Konfiguration (Teile 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 Client-Geheimnis, nur HTML und JavaScript), möchten einige meiner Clients über SSL darauf zugreifen. Wie kann ich basierend auf dem Host-Header dynamisch auswählen, welches Zertifikat für die SSL-Verbindung verwendet werden soll? Beachten Sie, dass ich den Zertifikatspfad nicht einfach fest codieren 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
}
Antwort1
Wie kann ich basierend auf dem Host-Header dynamisch auswählen, welches Zertifikat für die SSL-Verbindung verwendet werden soll?
Der Host-Header ist Teil des HTTP-Protokolls, aber HTTPS ist in eine SSL-Verbindung eingebettetes HTTP. Das bedeutet, dass Sie zuerst die SSL-Verbindung herstellen müssen (wofür das Zertifikat erforderlich ist), bevor Sie auf den Host-Header zugreifen können.
Wenn der Client SNI unterstützt (alle modernen Browser tun das, aber IE/XP nicht), sendet er den Zielnamen bereits im SSL-Handshake. Die Bereitstellung unterschiedlicher Zertifikate basierend auf dem Zielnamen erfolgt in nginx normalerweise über unterschiedliche Serverabschnitte. Sie könnten versuchen, dies $ssl_server_name
im Standardabschnitt zu verwenden, aber ich bin nicht sicher, ob das funktioniert, und selbst wenn es funktioniert, könnte es Optimierungen wie das Session-Caching negativ beeinflussen.