reescribir http a https con ngnix detrás del equilibrador de carga

13

Estoy usando un equilibrador de carga Rackspace que me permite configurar mi clave / pem ssl dentro del panel de administración. Todo funciona bien, puedo usar los protocolos http y https. Pero si trato de redirigir http a https usando:

server{
  listen *:80;
  server_name mydomain.com www.mydomain.com; 
  rewrite ^ https://mydomain.com$request_uri? permanent;

... obtengo un bucle de redireccionamiento. Me doy cuenta de que no estoy escuchando el puerto 443, pero eso es porque el equilibrador de carga lo manejó por mí. También intenté envolver la reescritura en if ($scheme ~* http){vano.

La otra parte de mi pregunta es que me gustaría eliminar www de la url, ¿puedo hacer esto con una sola reescritura? ¿No debería la reescritura anterior ocuparse de esto también?

¡Gracias por tu ayuda!

jwerre
fuente
El equilibrador de carga debería enviarle alguna indicación de si la conexión era HTTPS. Pregúntale a Rackspace. (Ah, y probablemente no quieras deshacerte de www ...)
Michael Hampton
Interesante, lo investigaré. ¿Por qué crees que no debería deshacerme de www?
jwerre

Respuestas:

14

sciurus es correcto en que los Balanceadores de carga en la nube de Rackspace establecen X-Fordered-Proto en https cuando SSL se descarga en el equilibrador de carga. Para evitar un bucle de redireccionamiento en nginx, debe poder agregar lo siguiente a la locationsección en la configuración de vhost:

if ($http_x_forwarded_proto = "http") {
            rewrite  ^/(.*)$  https://mydomain.com/$1 permanent;
}

Esto debería evitar el bucle de redireccionamiento infinito mientras redirige las solicitudes que no son https a https.

Slade
fuente
18

Mediante el uso de Nginx incorporado en las variables del servidor $request_uriy $server_namese puede hacer esto sin el uso de expresiones regulares en absoluto. Agregue lo siguiente al locationbloque de su servidor y listo:

if ($http_x_forwarded_proto = "http") {
    return 301 https://$server_name$request_uri;
}

Esto supone que su equilibrador de carga está enviando el $http_x_forwarded_protoencabezado junto con la solicitud a su (s) instancia (s) de fondo. Otros encabezados comunes incluyen $http_x_forwarded_schemey también just $scheme.

Puede encontrar más información en la documentación de nginx Pitfalls and Common Mistakes : https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#taxing-rewrites

Luke Peterson
fuente
55
Definitivamente debería usar return over rewrite. Votado
designermonkey
1
Puede usar en $hostlugar de$server_name
Yossi
no funciona con nombre_servidor _; entonces uno debe usar la variable $ host como sugirió @Yossi.
Razvan Grigore
1

El equilibrador de carga siempre te habla a través de http. Lo que está pasando es

  1. El navegador realiza una solicitud al puerto 80 en el equilibrador de carga
  2. El equilibrador de carga realiza una solicitud al puerto 80 en su servidor web
  3. Su servidor web envía una redirección al usuario.
  4. El usuario realiza una solicitud al puerto 443 en el equilibrador de carga

Los pasos 2-4 siguen repitiéndose hasta que el navegador detecta el bucle de redireccionamiento y se da por vencido.

EDITAR: Para resolver esto, solo realice la reescritura cuando el encabezado X-Fordered-Proto esté configurado en http. Ese encabezado es cómo el equilibrador de carga de Rackspace le dice a su servidor web el protocolo a través del cual recibió la solicitud.

Sciurus
fuente
Supongo que eso explicaría por qué $ server_protocol siempre devuelve HTTP
jwerre
Entonces respondiste por qué sucede esto ... ¿Alguna sugerencia sobre cómo solucionarlo?
jwerre