Nginx. Comment rejeter la demande au serveur virtuel SSL non répertorié?

13

J'ai un certificat SSL générique et plusieurs sous-domaines sur la même IP. Maintenant, je veux que mon nginx gère uniquement les noms de serveur mentionnés et supprime la connexion pour les autres afin qu'il ne semble nginxpas fonctionner pour les noms de serveur non répertoriés (ne répond pas, rejette, mort, pas un seul octet en réponse). Je fais ce qui suit

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;
  //}
}

J'ai essayé presque tout dans le dernier bloc serveur, mais sans succès. J'obtiens une réponse valide du serveur virtuel connu ou un code d'erreur. Veuillez aider.

andbi
la source

Réponses:

7

Cela ne fonctionne pas de cette façon: la prise de contact SSL a lieu avant HTTP, donc le nom sur le certificat sera évalué dans le navigateur avant de pouvoir rediriger ou faire autre chose dans la configuration nginx.

cjc
la source
c'est mauvais, mais je dois admettre) Merci.
andbi
3
Ce n'est pas vrai: vous pouvez faire autre chose à un niveau inférieur, comme interrompre la connexion sans aucune réponse, comme expliqué dans d'autres réponses.
collimarco
13

La réponse de cjc a déjà correctement signalé le problème avec la tentative de correspondance des noms d'hôte lorsque SSL est activé. Cependant, il est possible de le faire, comme ceci:

server {
    ...

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

Remarque: oui, il est vrai que généralement ifc'est mal , mais il est sûr à utiliser ifdans ce cas. (Lisez la page liée si vous devez vous convaincre.)

Contrairement à ce qui a été suggéré, l'ajout du bloc suivant ne fonctionnera pas:

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

car un certificat SSL qui correspond validname.domain.comne correspondra pas à un nom de domaine aléatoire. Je l'ai essayé et nginx a agi comme si le bloc n'était pas présent du tout.

Cela ne fonctionnera pas non plus:

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

car cela entraînera l' échec de chaque connexion HTTPS sur le port 443, même celles qui devraient passer. J'ai essayé celui-ci aussi. wgeta signalé une erreur de négociation SSL.

Louis
la source
5

La plupart des réponses ici expliquent pourquoi cela ne fonctionne pas, pas comment le faire fonctionner.

Voici comment - vous devez faire de ce serveur fourre-tout un 'serveur_par défaut' et devez fournir des chemins vers cert / key afin qu'il puisse décrypter la requête SSL entrante et correspondre à l'en-tête Host:

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;
}

Notez la clé ssl_certificate / ssl_certificate_key. S'ils ne sont pas spécifiés, nginx essaie toujours d'utiliser un tel serveur par défaut et échoue car il ne peut pas accepter la connexion SSL sans certificat / clé. On peut utiliser n'importe quel certificat / clé, par exemple auto-signé. ...

Pour générer un certificat auto-signé:

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

Voir également /server//a/841643/87439

andreycpp
la source
1
Avez-vous essayé cela? Comment créez-vous un certificat SSL qui correspond à un nom de serveur "_"?
Tim
Oui, cette solution fonctionne pour moi. J'ai eu le même problème exact et j'ai pensé à partir de la documentation que nginx a besoin d'un certificat / clé car il ne regarde pas TLS SNI. Vous pouvez utiliser n'importe quel certificat / clé, par exemple auto-signé.
andreycpp
1

J'ai implémenté la solution ci-dessus aujourd'hui, et cela a fonctionné à merveille. Toutes les URL non spécifiées sont supprimées, maintenant. Placer ce code de serveur avant l'entrée réelle du serveur virtuel était la clé - toutes les URL mal formées vont maintenant à ce serveur «par défaut».

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

server {
     listen       443;
     server_name  [URL]
David Sexton
la source
0

Vous devriez pouvoir gérer cela en faisant du serveur qui gère les éléments non répertoriés le premier bloc serveur de votre configuration.

http {
    ...

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

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

Tous les domaines non spécifiquement identifiés seront gérés par ce bloc serveur.

Dayo
la source
1
Cela ne fonctionne pas
AmirHossein