Nginx. Come rifiuto la richiesta al server virtuale ssl non elencato?


13

Ho un certificato SSL jolly e diversi sottodomini sullo stesso IP. Ora voglio che il mio nginx gestisca solo i nomi dei server menzionati e rilasci la connessione per gli altri in modo che sembrerebbe nginxnon essere in esecuzione per i nomi dei server non elencati (non rispondendo, rifiutando, morto, non un singolo byte in risposta). Faccio quanto segue

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

Ho provato quasi tutto nell'ultimo blocco del server, ma senza successo. Ricevo una risposta valida dal server virtuale noto o un codice di errore. Per favore aiuto.

Risposte:


7

Non funziona in questo modo: l'handshake SSL avviene prima di HTTP, quindi il nome sul certificato verrà valutato nel browser prima che tu possa reindirizzare o fare qualsiasi altra cosa all'interno della configurazione di nginx.


questo è male, ma devo ammetterlo) Grazie.
andbi,

3
Questo non è vero: puoi fare qualcos'altro a un livello inferiore, come abbandonare la connessione senza alcuna risposta, come spiegato in altre risposte.
Collimarco,

13

La risposta di cjc ha già correttamente evidenziato il problema nel tentativo di abbinare i nomi host quando SSL è abilitato. Tuttavia, è possibile farlo, in questo modo:

server {
    ...

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

Nota: sì, è vero che generalmente ifè malvagio , ma ifin questo caso è sicuro da usare . (Leggi la pagina collegata se hai bisogno di convincerti.)

Contrariamente a quanto è stato suggerito, l'aggiunta del seguente blocco non funzionerà:

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

perché un certificato SSL corrispondente validname.domain.comnon corrisponde a un nome di dominio casuale. L'ho provato e nginx si è comportato come se il blocco non fosse presente affatto.

Anche questo non funzionerà:

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

perché farà fallire ogni singola connessione HTTPS sulla porta 443, anche quelle che dovrebbero passare. Ho provato anche questo. wgetsegnalato un errore di handshake SSL.


5

La maggior parte delle risposte qui riguarda il motivo per cui non funziona, non come farlo funzionare.

Ecco come - devi rendere tale server universale un "server_predefinito" e devi fornire percorsi per cert / key in modo che possa decrittografare la richiesta ssl in arrivo e abbinare l'intestazione 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;
}

Nota lì la chiave ssl_certificate / ssl_certificate_key. Se non vengono specificati, nginx tenta comunque di utilizzare tale server_predefinito e non riesce in quanto non può accettare la connessione SSL senza chiave cert /. È possibile utilizzare qualsiasi certificato / chiave, ad esempio autofirmato. ...

Per generare un certificato autofirmato:

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

Vedi anche /server//a/841643/87439


1
Hai provato questo? Come si crea un certificato SSL che corrisponde al nome di un server "_"?
Tim

Sì, questa soluzione funziona per me. Ho avuto lo stesso problema esatto e ho capito dalla documentazione che nginx ha bisogno di una chiave / certificato in quanto non guarda a TLS SNI. È possibile utilizzare qualsiasi certificato / chiave, ad esempio autofirmato.
andreycpp,

1

Oggi ho implementato la soluzione di cui sopra e ha funzionato a meraviglia. Tutti gli URL non specificati vengono eliminati, ora. Inserire questo codice server prima che la voce effettiva del server virtuale fosse la chiave - tutti gli URL mal formati ora passano a questo server "predefinito".

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

server {
     listen       443;
     server_name  [URL]

0

Dovresti essere in grado di gestirlo facendo del server che gestisce gli elementi non elencati il ​​primo blocco del server nella tua configurazione.

http {
    ...

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

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

Tutti i domini non specificamente identificati saranno gestiti da questo blocco di server.


1
Non funziona
AmirHossein
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.