2012-01-07 23 views
84

Estoy ejecutando una aplicación Sinatra detrás de passenger/nginx. Estoy intentando que responda tanto a llamadas http como a https. El problema es que cuando ambos se definen en el bloque del servidor, las llamadas a https se responden normalmente, pero el resultado es un error de 400 "Se envió la solicitud HTTP simple al puerto HTTPS". Esto es para una página estática así que supongo que Sinatra no tiene nada que ver con esto. ¿Alguna idea sobre cómo solucionar este problema?Tratando con nginx 400 "La solicitud HTTP simple fue enviada al puerto HTTPS" error

Aquí está el bloque de servidor:

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

sugiero que acepte la respuesta dada por @bobojam –

+0

En mi caso fue que la URL en el navegador: 'my.example.com: 443' no funcionaba. Cambiando eso en cambio a 'https: // my.example.com' funcionó. Extraño, nunca tuve este problema con apache. – Sebastian

+0

'ssl on;' le dice a NGINX al servidor ** CUALQUIER ** contenido a través de SSL. Use el indicador "ssl" al final de su 'listen 443;' por ejemplo 'listen 443 ssl;' si su servidor ofrece tráfico tanto http como https, y quite la directiva 'ssl on;'. – Stphane

Respuesta

169

Me encontré con un problema similar. Funciona en un servidor y no en otro servidor con la misma configuración de Nginx. Encontrado la solución que es respondida por Igor aquí http://forum.nginx.org/read.php?2,1612,1627#msg-1627

Sí. O puede combinar servidores SSL/no SSL en un servidor:

server { 
    listen 80; 
    listen 443 default ssl; 

    # ssl on - remember to comment this out 

} 
+0

RAPAM dice Iosif, asegúrese de que también incluyen 'ssl fuera;' – aceofspades

+18

Sólo tiene que quitar la línea 'SSL en; '(sin necesidad de añadir SSL apagado). Además, dado que no recuerdo qué versión de Nginx, ya no es necesario utilizar 'default' en la línea' listen 443'. Entonces, la configuración de OP era correcta, solo tenía que eliminar 'ssl on' y debería funcionar. – laurent

+0

@bobojam no dudes en incluir la explicación de mi respuesta, para que la tuya sea más completa. Le pedí al autor de OP que aceptara tu respuesta. –

16

El error dice todo realmente. Su configuración le dice a Nginx que escuche en el puerto 80 (HTTP) y use SSL. Cuando dirige su navegador al http://localhost, intenta conectarse a través de HTTP. Como Nginx espera SSL, se queja con el error.

La solución es muy simple. Necesita dos secciones server:

server { 
    listen 80; 

    // other directives... 
} 

server { 
    listen 443; 

    ssl on; 
    // SSL directives... 

    // other directives... 
} 
+7

Realmente no necesita dos secciones de servidor. Elimine la línea "ssl on" y cambie las líneas de escucha según la respuesta de @bobojam. Por lo – toxaq

3

En realidad se puede hacer esto con:

ssl off; 

Esto resolvió mi problema en el uso de nginxvhosts; ahora puedo usar tanto SSL como HTTP simple. Funciona incluso con puertos combinados.

+0

Funciona para mí en nginx/1.6.3 :) – djthoms

4

if use phpmyadmin add: fastcgi_param HTTPS on;

20

Las respuestas anteriores son incorrectas porque se sobrepasa la prueba de "es esta conexión HTTPS" para permitir el servicio de las páginas en http independientemente de la seguridad de la conexión.

La respuesta segura utilizando una página de error en un código de error http 4xx específico de NGINX para redirigir al cliente a que vuelva a intentar la misma solicitud a https. (Como se describe aquí https://serverfault.com/questions/338700/redirect-http-mydomain-com12345-to-https-mydomain-com12345-in-nginx)

La OP debe utilizar:

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

Probablemente quiera $ nombre_servidor en lugar de $ host, el nombre_servidor presumiblemente se establece en el CN ​​que autentica el certificado SSL. De esta forma, el usuario no obtendrá una pantalla de miedo si entró a través de una IP o localhost. – George

+0

@ michael-j-evans Usted ahorró mi semana, estaba frustrado porque no se encontró una solución, thks: D – rderoldan1

+0

Estaba tratando de implementar esto en mi instalación local de [GitLab] (https://gitlab.com /), pero usó el [Insertar configuraciones personalizadas de NGINX en el bloque de servidores de GitLab] (https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/nginx.md#inserting-custom- nginx-settings-en-el-gitlab-server-bloque) por lo tanto, el método '[ 'nginx custom_gitlab_server_config'] = "error_page 497 https: // $ host: $ server_port $ request_uri;"' hizo el truco –

12

que tenían el mismo problema exacto, tengo clase de la misma configuración que el exemple y yo tengo trabajo mediante la eliminación de la línea:

ssl on;

citar el documento:

Si los servidores HTTP y HTTPS son iguales, un único servidor que se encarga tanto de peticiones HTTP y HTTPS se pueden configurar mediante la supresión de la directiva “SSL en” y añadiendo el parámetro SSL para *: 443 puerto

+0

Cualquier oportunidad que tiene la enlace a doc? –

10

Según wikipedia article on status codes.Nginx tiene un código de error personalizado cuando el tráfico http se envía al puerto https (código de error 497)

Y de acuerdo con nginx docs on error_page, puede definir un URI que se mostrará para un error específico.
Por lo tanto, podemos crear un uri al que se enviarán los clientes cuando se genere el código de error 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; 
    } 
} 

Sin embargo, si un cliente realiza una solicitud a través de cualquier otro método que no sea un GET, esa solicitud se convirtió en un GET. Por lo tanto, para preservar el método de solicitud al que ingresó el cliente; utilizamos los redireccionamientos de procesamiento de errores como se muestra en nginx docs on error_page

Y es por eso que utilizamos el redireccionamiento 301 =307.

Uso del archivo nginx.conf se muestra aquí, somos capaces de tener http y https escuchar en el mismo puerto

+0

esto funciona para mí - error_page 497 301 = 307 https://89.89.89.89:7000$request_uri; –

5

Aquí se muestra un ejemplo en las configuraciones HTTP y HTTPS en mismo bloque de configuración con soporte de ipv6. La configuración se prueba en Ubuntu Server y Nginx/1.4.6 pero esto debería funcionar con todos los servidores.

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

No incluya ssl on que puede causar 400 error. La configuración anterior debería funcionar para

http://example.com

http://www.example.com

https://example.com

https://www.example.com

Espero que esto ayude!

Cuestiones relacionadas