2012-01-07 8 views
84

Sto eseguendo un'applicazione Sinatra dietro a passenger/nginx. Sto cercando di farlo rispondere a entrambe le chiamate http e https. Il problema è che, quando entrambi sono definiti nel blocco del server, le chiamate https sono normalmente soddisfatte, ma l'HTTP restituisce un errore 400 "La richiesta HTTP semplice è stata inviata alla porta HTTPS". Questo è per una pagina statica quindi immagino che Sinatra non abbia nulla a che fare con questo. Qualche idea su come risolvere questo problema?Gestione di nginx 400 "La semplice richiesta HTTP è stata inviata alla porta HTTPS" Errore

Ecco il blocco del server:

server { 
     listen 80; 
     listen 443 ssl; 
     server_name localhost; 
     root /home/myhome/app/public; 
     passenger_enabled on; 

     ssl on; 
     ssl_certificate  /opt/nginx/ssl_keys/ssl.crt; 
     ssl_certificate_key /opt/nginx/ssl_keys/ssl.key; 
     ssl_protocols  SSLv3 TLSv1; 
     ssl_ciphers   HIGH:!aNULL:!MD5; 

     location /static { 
      root /home/myhome/app/public; 
      index index.html index.htm index.php; 
     } 

     error_page 404 /404.html; 

     # redirect server error pages to the static page /50x.html 
     error_page 500 /500.html; 

     access_log /home/myhome/app/logs/access.log; 
     error_log /home/myhome/app/logs/error.log; 
} 
+0

Ti suggerisco di accettare la risposta data da @bobojam –

+0

Nel mio caso l'url nel browser: "my.example.com: 443' non ha funzionato. Cambiando quello invece su 'https: // my.example.com' funzionava. Strano, non ha mai avuto questo problema con Apache. – Sebastian

+0

'ssl on;' dice NGINX al server ** QUALSIASI ** contenuto tramite SSL. Usa il flag "ssl" alla fine del tuo 'listen 443; 'e.g' ascolta 443 ssl; 'se il tuo server eroga sia il traffico http e https, e rimuove la direttiva' ssl on; '. – Stphane

risposta

169

Mi sono imbattuto in un problema simile. Funziona su un server e non su un altro server con la stessa configurazione Nginx. Trovato la soluzione a cui risponde Igor qui http://forum.nginx.org/read.php?2,1612,1627#msg-1627

Sì. Oppure si può combinare i server SSL/non SSL in un server:

server { 
    listen 80; 
    listen 443 default ssl; 

    # ssl on - remember to comment this out 

} 
+0

Per quale rapam iosif dice, assicurati di includere anche 'ssl off;' – aceofspades

+18

Hai solo bisogno di rimuovere la riga 'ssl on;' (non è necessario aggiungere ssl off). Inoltre, poiché non ricordo quale versione di Nginx, non c'è più bisogno di usare 'default' sulla riga' listen 443'. Quindi la configurazione dell'OP era OK, basta rimuovere 'ssl on' e dovrebbe funzionare. – laurent

+0

@bobojam sentiti libero di includere la spiegazione dalla mia risposta, in modo che il tuo sia più completo. Ho chiesto all'autore OP di accettare la tua risposta. –

16

L'errore dice tutto in realtà. La tua configurazione dice a Nginx di ascoltare sulla porta 80 (HTTP) e usare SSL. Quando punti il ​​tuo browser su http://localhost, prova a connettersi tramite HTTP. Poiché Nginx si aspetta SSL, si lamenta dell'errore.

La soluzione è molto semplice. Sono necessarie due sezioni server:

server { 
    listen 80; 

    // other directives... 
} 

server { 
    listen 443; 

    ssl on; 
    // SSL directives... 

    // other directives... 
} 
+7

In realtà non sono necessarie due sezioni del server. Rimuovi la riga "ssl on" e modifica le linee di ascolto come da risposta di @ bobojam. – toxaq

3

In realtà si può fare questo con:

ssl off; 

Questo risolto il problema nell'uso nginxvhosts; ora sono in grado di utilizzare sia SSL che HTTP semplice. Funziona anche con porte combinate.

+0

Funziona per me su nginx/1.6.3 :) – djthoms

4

se utilizzare phpmyadmin aggiungere: fastcgi_param HTTPS su;

20

Le risposte sopra riportate non sono corrette in quanto il test "HTTPS di connessione" è più frequente e consente di servire le pagine su http indipendentemente dalla sicurezza della connessione.

La risposta sicura utilizzando una pagina di errore su un codice di errore http 4xx specifico NGINX per reindirizzare il client per riprovare la stessa richiesta a https. (Come descritto qui https://serverfault.com/questions/338700/redirect-http-mydomain-com12345-to-https-mydomain-com12345-in-nginx)

Il PO dovrebbe usare:

server { 
    listen  12345; 
    server_name php.myadmin.com; 

    root   /var/www/php; 

    ssl   on; 

    # If they come here using HTTP, bounce them to the correct scheme 
    error_page 497 https://$host:$server_port$request_uri; 

    [....] 
} 
+1

Probabilmente vuoi $ nome_servizio invece di $ host, il nome_server presumibilmente è impostato sul CN che il certificato SSL autentica. In questo modo, l'utente non otterrà una schermata di allarme se sono entrati tramite un IP o localhost. – George

+0

@ michael-j-evans Hai salvato la mia settimana, ero frustrato perché non ho trovato una soluzione, th: D – rderoldan1

+0

stavo cercando di implementarlo nella mia installazione locale di [GitLab] (https://gitlab.com /), ma ha utilizzato [Inserimento di impostazioni NGINX personalizzate nel blocco del server GitLab] (https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/nginx.md#inserting-custom- metodo nginx-settings-in-the-gitlab-server-block) quindi 'nginx ['custom_gitlab_server_config'] =" pagina_errore 497 https: // $ host: $ server_port $ request_uri; "' ha fatto il trucco –

12

Ho avuto lo stesso problema esatto, ho tipo della stessa configurazione come exemple e ho capito di lavoro rimuovendo la linea:

ssl on;

Per citare il documento:

Se server HTTP e HTTPS sono uguali, un singolo server che gestisce sia HTTP e HTTPS richieste possono essere configurate eliminando la direttiva “ssl on” e aggiungendo il parametro ssl per *: 443 porta

+0

Ogni volta che hai il link a doc? –

10

Secondo wikipedia article on status codes.Nginx ha un codice di errore personalizzato quando il traffico http viene inviato alla porta https (codice di errore 497)

E in base a nginx docs on error_page, è possibile definire un URI che verrà visualizzato per un errore specifico.
Così possiamo creare un uri a cui verranno inviati i client quando viene generato il codice di errore 497.

nginx.conf

#lets assume your IP address is 89.89.89.89 and also 
#that you want nginx to listen on port 7000 and your app is running on port 3000 

server { 
    listen 7000 ssl; 

    ssl_certificate /path/to/ssl_certificate.cer; 
    ssl_certificate_key /path/to/ssl_certificate_key.key; 
    ssl_client_certificate /path/to/ssl_client_certificate.cer; 

    error_page 497 301 =307 https://89.89.89.89:7000$request_uri; 

    location/{ 
     proxy_pass http://89.89.89.89:3000/; 

     proxy_pass_header Server; 
     proxy_set_header Host $http_host; 
     proxy_redirect off; 
     proxy_set_header X-Real-IP $remote_addr; 
     proxy_set_header X-Forwarded-Protocol $scheme; 
    } 
} 

Tuttavia, se un client effettua una richiesta tramite qualsiasi altro metodo, tranne un GET, tale richiesta verrà trasformato in un GET. Quindi per preservare il metodo di richiesta che il cliente è arrivato via; utilizziamo i reindirizzamenti dell'elaborazione degli errori come mostrato in nginx docs on error_page

E questo è il motivo per cui utilizziamo il reindirizzamento 301 =307.

Utilizzando il file nginx.conf mostrato qui, siamo in grado di avere HTTP e HTTPS ascoltiamo in sulla stessa porta

+0

questo funziona per me - error_page 497 301 = 307 https://89.89.89.89:7000$request_uri; –

5

Ecco un esempio di config HTTP e HTTPS in stesso blocco di configurazione con supporto per ipv6. La configurazione è stata verificata in Ubuntu Server e NGINX/1.4.6 ma questo dovrebbe funzionare con tutti i server.

server { 
    # support http and ipv6 
    listen 80 default_server; 
    listen [::]:80 default_server ipv6only=on; 

    # support https and ipv6 
    listen 443 default_server ssl; 
    listen [::]:443 ipv6only=on default_server ssl; 

    # path to web directory 
    root /path/to/example.com; 
    index index.html index.htm; 

    # domain or subdomain 
    server_name example.com www.example.com; 

    # ssl certificate 
    ssl_certificate /path/to/certs/example_com-bundle.crt; 
    ssl_certificate_key /path/to/certs/example_com.key; 

    ssl_session_timeout 5m; 

    ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; 
    ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; 
    ssl_prefer_server_ciphers on; 
} 

Non includere ssl on che può causare 400 errore. La configurazione di cui sopra dovrebbe funzionare per

http://example.com

http://www.example.com

https://example.com

https://www.example.com

Spero che questo aiuti!

Problemi correlati