Frage Richtiges Einrichten eines "Standard" nginx-Servers für https


Ich habe mehrere Server auf dem gleichen Computer, einige nur mit http, einige mit http und https. Es gibt mehrere Serverblöcke, die in separaten Dateien definiert sind, die in der Hauptkonfigurationsdatei enthalten sind.

Ich habe einen "Standard" -Server für http eingerichtet, der eine allgemeine "Wartungsseite" für Anfragen bereitstellt, die nicht mit den anderen Servernamen in den anderen Konfigurationsdateien übereinstimmen. Der HTTP-Standardserver funktioniert wie erwartet, er verwendet den Servernamen "_" und er erscheint zuerst in der Liste der Includes (weil ich beobachtet habe, dass im Fall von doppelten Servernamen auf Servern der erste Server verwendet wird). Das funktioniert großartig.

Ich würde den gleichen exakten Serverblock erwarten (nur "life 80 default_server" auf "listen 443 default_server" umschalten und auch statt Seite "return 444" bedienen), tut es aber nicht. Stattdessen scheint der neue Standard-HTTPS-Server tatsächlich alle eingehenden HTTPS-Verbindungen zu erfassen und zu veranlassen, dass sie fehlschlagen, obwohl die anderen Serverblöcke passendere Servernamen für die eingehenden Anfragen haben. Wenn Sie den neuen Standard-https-Server entfernen, wird das halbwegs korrekte Verhalten wieder aufgenommen: Die Websites mit https werden alle korrekt geladen. aber die Websites ohne https werden alle an den ersten https-Server in den Include-Dateien weitergeleitet (was gemäß der Dokumentation, wenn kein "default_server" erscheint, dann ist der erste Serverblock, der angezeigt wird, "default").

Also meine Frage ist, was ist der richtige Weg, um einen "Standard-Server" in Nginx für SSL-Verbindungen zu definieren? Warum, wenn ich explizit einen "Default_Server" setze, wird es gierig und ergreift alle Verbindungen. Wenn ich implizit nginx den "Default Server" entscheide, funktioniert es wie ich es erwarte (mit dem falschen Server als Standard und den anderen realen Servern) verhält sich richtig)?

Hier sind meine "Standardserver". Http funktioniert, ohne andere Server zu brechen. Https bricht andere Server und verbraucht alles.

server {
    listen 443 ssl default_server;
    server_name _;

    access_log /var/log/nginx/maintenance.access.log;
    error_log /var/log/nginx/maintenance.error.log error;

    return 444;
}

server {
    listen *:80 default_server;
    server_name _;
    charset utf-8;

    access_log /var/log/nginx/maintenance.access.log;
    error_log /var/log/nginx/maintenance.error.log error;

    root /home/path/to/templates;

    location / {
        return 503;
    }

    error_page 503 @maintenance;

    location @maintenance {
        rewrite ^(.*)$ /maintenance.html break;
    }
}

Jeder von euch sieht, was hier falsch sein könnte?


56
2018-02-26 22:29


Ursprung




Antworten:


Sie haben kein ssl_certificate oder ssl_certificate_key in Ihrem "Standard" https-Block definiert. Obwohl Sie keinen echten Schlüssel für dieses Standardszenario haben oder wollen, müssen Sie dennoch einen oder einen anderen konfigurieren, da nginx das von Ihnen beschriebene unerwünschte Verhalten aufweist.

Erstellen Sie ein selbstsigniertes Zertifikat mit dem allgemeinen Namen "*" und schließen Sie es an Ihre Konfiguration an, damit es wie gewünscht funktioniert.

Das "Standard" -Verhalten bei dieser Einrichtung wäre, dass ein Browser eine Warnung erhalten würde, dass das Zertifikat nicht vertrauenswürdig ist. Wenn der Benutzer das Zertifikat als Ausnahme hinzufügt, wird die Verbindung durch nginx unterbrochen und der Standard ihres Browsers angezeigt Fehlermeldung "konnte nicht verbunden werden".


19
2018-02-27 16:27



Ich habe es versucht, aber es funktioniert immer noch nicht: Alle SSL-Anfragen an die IP gehen zu meinem anderen SSL-Host. Kann ich noch etwas anderes versuchen? - Michael Härtl


Wir wollen im Grunde um jeden Preis vermeiden, dass die erste Serverdefinition in unserer Konfigurationsdatei als Catch-All-Server für SSL-Verbindungen dient. Wir alle wissen, dass es das tut (im Gegensatz zu http und Verwendung von default_server config, die gut funktioniert).

Dies kann (noch) nicht deklarativ für SSL erreicht werden, also müssen wir es mit einem IF kodieren ...

Die Variable $host ist der Hostname aus der Anforderungszeile oder dem http-Header. Die Variable $server_name ist der Name des Serverblocks, in dem wir uns gerade befinden.

Wenn diese beiden nicht gleich sind, dann haben Sie diesen SSL-Server-Block für einen anderen Host gedient, so dass dieser blockiert werden sollte.

Der Code enthält keine spezifischen Verweise auf die IP-Adressen Ihres Servers, sodass er problemlos für andere Serverkonfigurationen ohne Änderung wiederverwendet werden kann.

Beispiel:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    ###
    ### Section: SSL

    #
    ## Check if this certificate is really served for this server_name
    ##   http://serverfault.com/questions/578648/properly-setting-up-a-default-nginx-server-for-https
    if ($host != $server_name) {
        #return 404 "this is an invalid request";
        return       444;
    }

    ...

13
2017-07-02 00:12



Könntest du erklären was das ist? listen [::]:443 ssl http2; tut das? Ich habe Probleme, Dokumentation dafür zu finden. - Andrew Brown
Ich glaube, ich habe es gefunden, ich musste nur wissen, wonach ich suchen muss. IPV4 und IPV6 Direktiven. - Andrew Brown


Ich habe es geschafft, mit nginx ein gemeinsames dediziertes Hosting auf einer einzigen IP zu konfigurieren. Standard-HTTP und HTTPS, die einen 404 für unbekannte eingehende Domänen bereitstellen.

1 - Erstellen Sie eine Standardzone

Da nginx vhosts in ascii-Reihenfolge lädt, sollten Sie einen erstellen 00-default Datei / symbolische Verbindung in Ihre /etc/nginx/sites-enabled.

2 - Füllen Sie die Standardzone

Füllen Sie Ihre 00-default mit Standardvhosts. Hier ist die Zone, die ich benutze:

server {
    server_name _;
    listen       80  default_server;
    return       404;
}


server {
    listen 443 ssl;
    server_name _;
    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;
    return       404;
}

3 - Erstellen Sie ein selbstsigniertes Zertifikat, testen und erneut laden

Sie müssen ein selbstsigniertes Zertifikat erstellen /etc/nginx/ssl/nginx.crt.

Erstellen Sie ein selbstsigniertes Standardzertifikat:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt

Nur eine Erinnerung:

  • Testen Sie die nginx-Konfiguration vor dem erneuten Laden / Neustart: nginx -t
  • Umladen Sie einen Genuss: sudo service nginx reload

Ich hoffe es hilft.


12
2018-04-24 11:52



Löst nicht die Warnung des Browsers, eine unsichere Site zu besuchen. - gdbj
Kann nicht aufgelöst werden, da ein Catch-all mit allen Domains übereinstimmen muss. Kein SSL kann alle Domänen mit einem Platzhalter versehen. Stellen Sie sich vor, wenn Sie google.fr auf Ihrem Server spoofen, können Sie Ihren Server als google.fr authentifizieren. Es wäre ein ernstes Sicherheitsproblem :( - Ifnot
Ja, ich denke, das macht Sinn. Leider wird Ihnen in Chrome eine gruselige Warnung angezeigt, bevor Sie die 404-Seite sehen, die schlimmer ist, als wenn der Server den Datenverkehr einfach ablehnt. Es sieht so aus, als wäre der Server falsch konfiguriert. - gdbj


Um mehr über die Antwort von Radmilla Mustafa zu erfahren:

Nginx verwendet den Header 'Host' für den Abgleich von servername. Es verwendet TLS SNI nicht. Dies bedeutet, dass für einen SSL-Server nginx eine SSL-Verbindung akzeptieren kann, was auf ein Zertifikat / einen Schlüssel hinausläuft. Der Zertifikatschlüssel kann ein beliebiger sein, z. selbstsigniert.

Sehen Dokumentation

Daher ist die Lösung:

server {
    server_name _;
    listen 80 default_server;
    listen 443 ssl default_server;
    ssl_certificate <path to cert>;
    ssl_certificate_key <path to key>;
    return 404; # or whatever
}

3
2018-03-30 21:17



Ich denke, das sollte die akzeptierte Antwort sein. Danke vielmals. - aggregate1166877


Wenn Sie absolut sicher sein wollen, dann verwenden Sie separate IP-Adressen für Hosts, die nicht auf HTTPS antworten sollten und Hosts, die dies tun sollten. Dies behebt auch das Browserwarnungsproblem "ungültiges Zertifikat".


1
2018-02-27 13:19