Ich habe einen Webserver mit vielen virtuellen Servern. Nur 1 davon ist SSL. Das Problem ist, dass kein Catchall-Serverblock auf SSL wartet und jede https-Anfrage an die anderen Sites vom 1 SSL-Block bearbeitet wird.
Meine Konfiguration sieht im Wesentlichen so aus:
# the catch all
server {
listen 80 default;
# I could add this, but since I have no default cert, I cannot enable SSL,
# and this listen ends up doing nothing (apparently).
# listen 443;
server_name _;
# ...
}
# some server
server {
listen 80;
server_name server1.com;
# ...
}
# some other server ...
server {
listen 80;
server_name server2.com;
# ...
}
# ... and it's https equivalent
server {
listen 443;
ssl on;
server_name server2.com;
# ...
}
Da es für 443 keinen Standard-Listener gibt, wird eine Anfrage wie https://server1.com
diese vom server2.com
https-Block bedient. Dies folgt der Logik server_name
in den Dokumenten.
Wenn es keine Übereinstimmung gibt, wird ein Serverblock {...} in der Konfigurationsdatei in der folgenden Reihenfolge verwendet:
- der Server-Block mit einer passenden Listen-Direktive, die als [default | default_server] markiert ist
- der erste Serverblock mit einer passenden Listen-Direktive (oder implizit listen 80;)
Was ist die bevorzugte Lösung für dieses Problem? Muss ich ein Dummy-Zertifikat für meinen Catch-All-Server-Block einrichten, damit ich 443 abhören und die schlechten Anforderungen verarbeiten kann? Gibt es einen Parameter, von dem ich nichts weiß, der eine genaue Übereinstimmung mit dem Hostnamen erzwingt server
?
Antworten:
Beides ist nicht möglich. Die Verbindung von einem Client zu https://foo.example.com/ kann nur von einem SSL-Zertifikat mit dem Namen "foo.example.com" akzeptiert werden. Es besteht keine Möglichkeit zur Umleitung, bis die SSL-Verbindung akzeptiert wird.
Wenn Sie jeden Standort für SSL konfigurieren, erhält ein Benutzer, der auf den Zertifikatfehler klickt, den von ihm angeforderten Standort. Wenn Sie eine "Alle abfangen" -Site für SSL konfigurieren, die nur eine Fehlerseite bereitstellt, und das namensbasierte virtuelle Hosting für die eine Site konfigurieren, die SSL unterstützen soll, können Sie Clients eine Fehlerseite bereitstellen.
Virtuelles Hosting mit SSL und HTTP passt einfach nicht zusammen.
quelle
Die einzige Möglichkeit besteht darin, ein selbstsigniertes SSL-Zertifikat zu erstellen und damit die Kontrolle über eingehende https-Anforderungen zu erlangen. Sie können Ihr selbstsigniertes SSL-Zertifikat in wenigen einfachen Schritten erstellen, die in diesem Beitrag beschrieben werden .
Angenommen, Sie erstellen ein selbstsigniertes Zertifikat mit dem Dateinamen server.crt. In Ihrer Nginx-Konfiguration würden Sie dann Folgendes anhängen:
Sie erhalten weiterhin die SSL-Warnmeldung des Browsers, haben aber zumindest die Kontrolle darüber, was als Nächstes passiert.
quelle
Fügen Sie einen Catch-All-Serverblock hinzu und geben Sie den Statuscode 444 zurück. Er weist nginx an, die Verbindung zu schließen, bevor Daten gesendet werden.
quelle
In diesen Tagen können Sie die TLS Server Name Indication-Erweiterung (SNI, RFC 6066) verwenden. Der HTTPS-Listener kann den Domänennamen erkennen, bevor er das entsprechende Zertifikat ausstellt.
Dies bedeutet, dass Sie Zertifikate für ALLE Ihre Domänen benötigen. Wenn SNI zum Erkennen einer der anderen Domänen verwendet wird, können Sie einfach die HTTP 301-Umleitung zur unverschlüsselten HTTP-Version verwenden, es sei denn, der Servername stimmt mit dem Namen überein, der benötigt wird Verschlüsselung.
Weitere Informationen zu SNI finden Sie in der Nginx-Dokumentation unter http://nginx.org/en/docs/http/configuring_https_servers.html
quelle
Ordnen Sie den angeforderten Hostnamen gültigen Hostnamen im
http {}
Block zu:Und dann im
server {}
Block Verbindungen mit dem falschen Hostnamen beenden:Verwenden Sie bei Bedarf mehrere Zuordnungen für mehrere Serverblöcke. Die Verbindung wird weiterhin mit einem Ihrer Zertifikate hergestellt. Wenn jedoch dieser letzte Block in jedem Serverblock vorhanden ist, der SSL bereitstellt, werden Verbindungen mit ungültigen Hostnamen effektiv "blockiert". Es ist möglicherweise nur im ersten Serverblock erforderlich, aber das Hinzufügen zu jedem Serverblock stellt sicher, dass die Reihenfolge keine Rolle spielt.
Die
$ssl_server_name
Variable ist in Nginx 1.7 oder höher vorhanden.quelle
So habe ich das Problem gelöst:
openssl req -nodes -x509 -newkey rsa:4096 -keyout self_key.pem -out self_cert.pem -days 3650
cp self*.pem /etc/nginx/ssl/
Das führt dazu, dass Sie auf jedem Server, der kein eigenes Zertifikat hat, eine Warnung erhalten (und nicht umgangen werden kann), in der Warnung wird jedoch nicht der falsche Zertifikatname angegeben. Wenn der Benutzer auf "Trotzdem besuchen" klickt, wird er zur Nicht-SSL-Version der von ihm eingegebenen Site weitergeleitet.
Einschränkung :
Wenn Ihre SLL-fähige Site nur definiert
www.example.com
(und nichtexample.com
), wird Ihre Catch-All-Routehttps://example.com
mit dem selbstsignierten Zertifikat und der entsprechenden Warnung geliefert.quelle
Weiterleiten an http:
Rückkehr 404 :
quelle