nginx sinatra thin

Cómo arreglar Sinatra redirigiendo https a http bajo nginx



thin (2)

Tengo una aplicación Sinatra ejecutándose en nginx (usando thin como un proxy de respaldo) y estoy usando declaraciones de redirect ''/<path>'' en Sinatra. Sin embargo, cuando accedo al sitio en https, esos redireccionamientos me envían a http://localhost/<path> lugar de a https://localhost/<path> como deberían.

Actualmente, nginx pasa el control a thin con este comando proxy_pass http://thin _cluster , donde thin_cluster es

upstream thin_cluster { server unix:/tmp/thin.cct.0.sock; }

¿Cómo puedo arreglar esto?


Para que Sinatra ensamble correctamente la url utilizada para los redireccionamientos, necesita poder determinar si la solicitud usa ssl, de modo que la redirección se pueda hacer usando http o https según corresponda.

Obviamente, la llamada real a thin no está utilizando ssl, ya que está siendo manejado por el servidor web front-end, y la solicitud proxy está en claro. Por lo tanto, necesitamos una forma de decirle a Sinatra que debe tratar la solicitud como segura, incluso si no está realmente usando SSL.

En última instancia, el código que determina si la solicitud debe tratarse como segura se encuentra en Rack::Request#ssl? y Rack::Request#scheme methods. Los métodos de scheme examinan el hash de env para ver si hay una o varias entradas presentes. Uno de estos es HTTP_X_FORWARDED_PROTO que corresponde al HTTP_X_FORWARDED_PROTO X-Forwarded-Proto HTTP. Si esto está establecido, entonces el valor se usa como el esquema de protocolo ( http o https ).

Entonces, si agregamos este encabezado HTTP a la solicitud cuando se envía un proxy desde nginx al servidor, Sinatra podrá determinar correctamente cuándo redirigir a https . En nginx podemos agregar encabezados a las solicitudes de proxy con proxy_set_header , y el esquema está disponible en la variable $scheme .

Entonces agregando la línea

proxy_set_header X-Forwarded-Proto $scheme;

a la configuración nginx después de que la línea proxy_pass debería hacer que funcione.


Puede obligar a todos los enlaces a ir a https en la capa nginx. en nginx.conf:

server{ listen 80; server_name example.com; rewrite ^(.*) https://$server_name$1 redirect; }

También es bueno tener esto para asegurar que sus solicitudes sean siempre https