Perché un ascolto 443 default_server; La regola nginx ha la precedenza sulla regola già configurata (le regole http funzionano normalmente)?


9

Ho un nginx e diversi sottodomini:

a.mydomain.com
b.mydomain.com
c.mydomain.com

Nginx ha 4 regole:

1) regola di riscrittura:

server {
  listen 80
  server_name gl.udesk.org;

  root /nowhere;
  rewrite ^ https://a.mydomain.com$request_uri permanent;
}

2) regola https:

server {

  listen 443;
  server_name a.mydomain.com;

  root /home/a/a/public;

  ssl on;
  ssl_certificate conf.d/ssl/a.crt;
  ssl_certificate_key conf.d/ssl/a.key;
  ssl_protocols ...
  ssl_ciphers ...
  ssl_prefer_server_ciphers on;

  location ...
}

3) regola predefinita http:

server {
  listen 80 default_server;
  return 444;
}

4) regola predefinita https:

server {
  listen 443 default_server;
  return 444;
}

Quindi, se inizio nginx e:

  • se vado nel browser a http://a.mydomain.com reindirizza a https://a.mydomain.com e quindi restituisce un errore 107 (net :: ERR_SSL_PROTOCOL_ERROR): errore del protocollo SSL.
  • se vado nel browser a https://b.mydomain.com mi aspetto che restituisca l'errore 444 indietro. Ma invece restituisce lo stesso errore 107 (net :: ERR_SSL_PROTOCOL_ERROR): errore protocollo SSL.
  • e così per tutti registrati dal CNAME dei provider DNS (ovvero a, b, c)
  • tutte le versioni http (es. regola 3 -) funzionano come previsto:

Quindi perché le regole https in nginx sono così difficili da configurare e come devo configurarle correttamente per ottenere lo stesso comportamento della versione http?

Aggiornare:

Creazione di un nuovo certificato e aggiunta:

ssl on;
ssl_certificate conf.d/ssl/default.crt;
ssl_certificate_key conf.d/ssl/default.key;

funziona ora, ma avrei una soluzione senza alcun certificato SSL necessario. Ripristina tutte le connessioni per tutti i sottodomini https (porta 443) tranne https://a.mydomain.com senza fornire un certificato.


2
Non puoi. SSL richiede un certificato prima che il web server sappia quale dominio vuoi . Deve avere un certificato da inviare o non può stabilire la connessione per parlare con il client.
Darth Android il

2
@DarthAndroid: la magia si chiama SNI - en.wikipedia.org/wiki/Server_Name_Indication .
Shi,

@Shi Sono a conoscenza di SNI - Ciò consente al server web di scegliere quale certificato inviare, ma deve comunque scegliere un certificato. nginxnon è abbastanza intelligente da capire che non ha bisogno di un certificato per ciò che l'utente vuole fare.
Darth Android

Risposte:


3

Non mescolare Port 443 con ssl! Nginx è completamente agnostico. Puoi offrire anche https tramite la porta 80. Le versioni moderne di nginx lo consentono

listen 1234 ssl;

e non hai bisogno della ssl on;linea allora.

Ma se vuoi servire https devi specificare un certificato. Il tuo server inserisce https quando riscrive la richiesta http in una richiesta https.

Ottieni il PROTOCOL ERROR, poiché l'handshake SSL viene eseguito prima di ogni altra cosa. Quindi return 444non è stato raggiunto. E qualsiasi stretta di mano SSL avrà bisogno di un certificato e di una chiave privata, per alimentare gli algoritmi di crittografia con la coppia certificato / chiave privata.


3

La returndirettiva fa parte del modulo di riscrittura. Se si controlla la documentazione , è possibile che funzioni con le richieste. In HTTPS le richieste possono essere effettuate solo al termine dell'handshake.

C'è una richiesta di funzionalità: https://trac.nginx.org/nginx/ticket/195 e viene fornita una soluzione alternativa.

server {
    listen 443 ssl;
    server_name bbb.example.com;
    ssl_ciphers aNULL;
    ssl_certificate /path/to/dummy.crt;
    ssl_certificate_key /path/to/dummy.key;
    return 444;
}

Nota questo si romperà i client HTTPS non SNI-capaci (come nginx propria proxy_pass, a meno che non si imposta proxy_ssl_server_name on;) di raggiungere qualsiasi altro server_names(in modo sostanzialmente rompere le legittime server_names che non vuole lasciar passare). Vedi trac.nginx.org/nginx/ticket/195#comment:11 per i dettagli.
nh2
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.