Nginx. Wie lehne ich eine Anfrage an einen nicht aufgelisteten virtuellen SSL-Server ab?

12

Ich habe ein Wildcard-SSL-Zertifikat und mehrere Subdomains auf derselben IP. Jetzt möchte ich, dass mein Nginx nur die genannten Servernamen verarbeitet und die Verbindung für andere beendet, sodass es so aussieht, als würde nginxes nicht für nicht aufgeführte Servernamen ausgeführt (nicht antworten, ablehnen, tot sein, kein einziges Byte als Antwort). Ich mache folgendes

ssl_certificate         tls/domain.crt;
ssl_certificate_key     tls/domain.key;

server {
  listen 1.2.3.4:443 ssl;
  server_name validname.domain.com;
  //
}

server {
  listen 1.2.3.4:443 ssl;
  server_name _;
  // deny all;
  // return 444;
  // return 404;
  //location {
  //  deny all;
  //}
}

Ich habe im letzten Serverblock fast alles ausprobiert, aber keinen Erfolg. Ich erhalte entweder eine gültige Antwort vom bekannten virtuellen Server oder einen Fehlercode. Bitte helfen Sie.

falscher Zeiger
quelle

Antworten:

7

Das funktioniert nicht so: Der SSL-Handshake findet vor HTTP statt, sodass der Name auf dem Zertifikat im Browser ausgewertet wird, bevor Sie in der nginx-Konfiguration etwas anderes umleiten oder tun können.

cjc
quelle
das ist schlecht, muss aber zugeben) Danke.
Fehlanzeige
3
Dies ist nicht der Fall: Sie können auf einer niedrigeren Ebene etwas anderes tun, z. B. die Verbindung ohne Antwort trennen, wie in den anderen Antworten erläutert.
Collimarco
12

Die Antwort von cjc wies bereits korrekt auf das Problem hin, dass bei aktiviertem SSL versucht wird, Hostnamen abzugleichen. Es ist jedoch möglich, wie folgt vorzugehen:

server {
    ...

    if ($host !~* ^validname\.domain\.com$ ) {
        return 444;
    }
    ...
}

Hinweis: Ja, es stimmt, dass es im Allgemeinen ifböse ist , aber ifin diesem Fall ist es sicher . (Lesen Sie die verlinkte Seite, wenn Sie sich selbst überzeugen müssen.)

Im Gegensatz zu dem, was vorgeschlagen wurde, wird das Hinzufügen des folgenden Blocks nicht funktionieren:

server {
    listen 80;
    listen 443 ssl;
    return 444;
}

weil ein validname.domain.compassendes SSL-Zertifikat keinem zufälligen Domainnamen entspricht. Ich habe es versucht, und Nginx tat so, als ob der Block überhaupt nicht vorhanden wäre.

Das geht auch nicht:

server {
    listen       443;
    server_name    _;
    return 444; 
}

weil dadurch jede einzelne HTTPS-Verbindung an Port 443 ausfällt, auch die, die durchlaufen sollten. Ich habe es auch versucht. wgethat einen SSL-Handshake-Fehler gemeldet.

Louis
quelle
4

Die meisten Antworten hier beziehen sich darauf, warum es nicht funktioniert und nicht, wie es funktioniert.

Hier ist, wie - Sie müssen einen solchen Catch-All-Server zu einem "Standardserver" machen und Pfade zu cert / key bereitstellen, damit er eingehende SSL-Anforderungen entschlüsseln und mit dem Host-Header übereinstimmen kann:

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

Beachten Sie dort den ssl_certificate / ssl_certificate_key. Wenn sie nicht angegeben werden, versucht nginx immer noch, einen solchen Standardserver zu verwenden, und schlägt fehl, da er keine SSL-Verbindung ohne Zertifikat / Schlüssel akzeptieren kann. Man kann jedes Zertifikat / jeden Schlüssel verwenden, zB selbst signiert. ...

So generieren Sie ein selbstsigniertes Zertifikat:

openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365 

Siehe auch /server//a/841643/87439

andreycpp
quelle
1
Hast du das versucht? Wie erstellen Sie ein SSL-Zertifikat, das dem Servernamen "_" entspricht?
Tim
Ja, diese Lösung funktioniert bei mir. Ich hatte genau das gleiche Problem und ging aus der Dokumentation hervor, dass Nginx ein Zertifikat / einen Schlüssel benötigt, da es sich nicht um TLS SNI handelt. Sie können jedes Zertifikat / jeden Schlüssel verwenden, z. B. selbstsigniert.
andreycpp
1

Ich habe die obige Lösung heute implementiert und sie hat reibungslos funktioniert. Alle nicht angegebenen URLs werden jetzt gelöscht. Das Platzieren dieses Servercodes vor dem eigentlichen Eintrag für den virtuellen Server war der Schlüssel - alle fehlerhaften URLs werden jetzt an diesen "Standard" -Server gesendet.

... 
server {
     listen       443;
     server_name    _;
     return 444; }

server {
     listen       443;
     server_name  [URL]
David Küster
quelle
0

Sie sollten dazu in der Lage sein, indem Sie den Server, der die nicht aufgelisteten Elemente verarbeitet, zum ersten Serverblock in Ihrer Konfiguration machen.

http {
    ...

    server {
        listen 80;
        listen 443 ssl;
        return 444;
    }

    server {
        server_name validname.domain.com;
        ...
    }
}

Alle nicht spezifisch identifizierten Domains werden von diesem Serverblock behandelt.

Dayo
quelle
1
Es funktioniert nicht
AmirHossein