Redireccionar todas las solicitudes http detrás de Amazon ELB a https sin usar if

27

Actualmente tengo un ELB que sirve tanto a http://www.example.org como a https://www.example.org .

Me gustaría configurarlo para que cualquier solicitud que apunte a http://www.example.org se redirija a https://www.example.org .

El ELB envía las solicitudes https como solicitudes http, por lo que utiliza:

server {
      listen         80;
       server_name    www.example.org;
       rewrite        ^ https://$server_name$request_uri? permanent;
}

no funcionará porque las solicitudes realizadas a https://www.example.org aún se realizarán en el puerto 80 en nginx.

Sé que es posible reescribirlo como

server {
      listen         80;
      server_name    www.example.org;
      if ($http_x_forwarded_proto != "https") {
          rewrite ^(.*)$ https://$server_name$1 permanent;
      }
}

Pero todo lo que he leído dice que ifdebe evitarse a toda costa dentro de la configuración de nginx, y esto sería para cada solicitud. Además, significa que tengo que configurar una configuración especial especial para la comprobación de estado ( como se describe aquí : "... cuando está detrás de un ELB, donde el ELB actúa como el punto final HTTPS y solo envía tráfico HTTP a su servidor, usted romper la capacidad de responder con una respuesta HTTP 200 OK para la comprobación de estado que necesita el ELB ").

Estoy considerando poner el inicio de sesión en el código de la aplicación web en lugar de la configuración nginx (y para los fines de esta pregunta, supongamos que es una aplicación basada en Django), pero no estoy seguro de si eso sería más costoso que En la if configuración.

Jordan Reiter
fuente
Hola, ¿puedes decirme dónde pones este código?
YuAn Shaolin Maculelê Lai
@ YuAnShaolinMaculelêLai Claro. Estos son archivos de configuración para nginx, así que acabo de poner el código en un archivo en /etc/nginx/conf.d/. Normalmente llamo al archivo domainname.conf donde "domainname" es el dominio del sitio web en cuestión. Puede nombrar el archivo como desee siempre que termine con .conf.
Jordan Reiter
Muchas gracias. Intenté crear un nuevo archivo seguido de .conf. Pero no funcionó para mí. Luego puse el código en el archivo que generó de AWS en /etc/nginx/conf.d/. Ahora funciona.
YuAn Shaolin Maculelê Lai

Respuestas:

9

Si funciona correctamente así, no tengas miedo. http://wiki.nginx.org/IfIsEvil

Es importante tener en cuenta que el comportamiento de if no es inconsistente, dadas dos solicitudes idénticas, no fallará aleatoriamente en una y funcionará en la otra, con las pruebas adecuadas y la comprensión de si se puede usar . Sin embargo, el consejo de usar otras directivas donde esté disponible todavía se aplica mucho.

ceejayoz
fuente
Esta página también dice que "si tiene problemas cuando se usa en contexto de ubicación". Me parece que puedes hacer lo que necesitas hacer fuera location {}, en su server {}lugar. (¡Pero avíseme si esto es incorrecto!)
Excalibur
15
  1. Configure su asignación de AWS ELB ELB: 80 a instancia: 80 y ELB: 443 a instancia: 1443.
  2. Enlace nginx para escuchar en los puertos 80 y 1443.
  3. Reenviar solicitudes que llegan al puerto 80 al puerto 443.
  4. La comprobación de estado debe ser HTTP: 1443. Rechaza el HTTP: 80 porque el 301 redirige.

configuración de aws elb

Configuración NGINX

    server {
       listen         80;
       server_name    www.example.org;
       rewrite        ^ https://$server_name$request_uri? permanent;
    }

    server {
       listen         1443;
       server_name    www.example.org;
   } 
nu everest
fuente
¿Qué pasa con la configuración de verificación de salud? ¿Podría por favor explicar eso también?
samkhan13
esto no funcionó con la comprobación de helth establecida en http: 80, la comprobación de estado falla.
samkhan13
2
Verificación de salud debe ser HTTP:1443. Rechaza el HTTP:80porque la redirección 301.
cbron
esto funcionó principalmente para mí, pero la línea de reescritura no funcionó con mi dominio comodín. Esta otra publicación corrigió esa parte: serverfault.com/questions/447258/…
Ron
9

Esta solución usa lógica condicional, pero como sugiere la respuesta aceptada, también creo que esto está bien. Ref: /programming/4833238/nginx-conf-redirect-multiple-conditions

Además, esto no requiere abrir ningún puerto adicional en la configuración de seguridad de aws para la imagen. Puede terminar ssl en AWS LB y enrutar el tráfico https al puerto http 80 en su instancia.

En este ejemplo, la comprobación de estado de LB coincide con el estado en el puerto 80 que se dirige al servidor de aplicaciones, por lo que la comprobación de estado valida tanto nginx como su aplicación están respirando.

server {
  listen 80 default deferred;

  set $redirect_to_https 0;
  if ($http_x_forwarded_proto != 'https') {
    set $redirect_to_https 1;
  }
  if ($request_uri = '/health') {
    set $redirect_to_https 0;
  }
  if ($redirect_to_https = 1) {
    rewrite ^ https://www.example.com$request_uri? permanent;
  }
  ...
}
Jonny Mac
fuente
1
debe haber una manera más elegante de hacerlo
Edward
0

Ahora puede crear un nuevo oyente en la configuración de AWS Load Balancer que redirige el puerto HTTP 80 al puerto 443. HTTPS. Por lo tanto, ya no necesita tocar la configuración nginx / apache.

Kenny Greulich
fuente
desafortunadamente, aún no es compatible con Cloudformation
Aryeh Leib Taurog el