web-dev-qa-db-fra.com

Redirigez toutes les demandes http derrière Amazon ELB vers https sans utiliser if

Actuellement, j'ai un ELB qui sert à la fois http://www.example.org et https://www.example.org .

Je voudrais le configurer pour que toute demande pointant vers http://www.example.org soit redirigée vers https://www.example.org .

L'ELB envoie les requêtes https en tant que requêtes http, donc en utilisant:

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

ne fonctionnera pas, car les demandes adressées à https://www.example.org seront toujours effectuées sur le port 80 sur nginx.

Je sais qu'il est possible de le réécrire comme

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

Mais tout ce que j'ai lu disait que if devrait être évité à tout prix dans la configuration de nginx, et ce serait pour chaque requête. En outre, cela signifie que je dois configurer une configuration distincte spéciale pour le contrôle de santé ( comme décrit ici : "… lorsque vous êtes derrière un ELB, où l'ELB agit comme point de terminaison HTTPS et n'envoie que Trafic HTTP vers votre serveur, vous rompez la possibilité de répondre avec une réponse HTTP 200 OK pour le contrôle de santé dont ELB a besoin ").

J'envisage de mettre la connexion dans le code de l'application Web plutôt que dans la configuration nginx (et pour les besoins de cette question, supposons que c'est une application basée sur Django), mais je ne suis pas certain que ce serait plus de surcharge que le if dans la configuration.

27
Jordan Reiter

Si cela fonctionne correctement, n'ayez pas peur. http://wiki.nginx.org/IfIsEvil

Il est important de noter que le comportement de if n'est pas incohérent, étant donné deux requêtes identiques, il n'échouera pas au hasard sur l'une et ne fonctionnera pas sur l'autre, avec des tests appropriés et une compréhension des ifs pouvant être utilisés . Le conseil d'utiliser d'autres directives lorsqu'elles sont disponibles reste cependant très valable.

9
ceejayoz
  1. Configurez votre mappage AWS ELB ELB: 80 en instance: 80 et ELB: 443 en instance: 1443.
  2. Liez nginx pour écouter sur les ports 80 et 1443.
  3. Transférer les demandes arrivant au port 80 au port 443.
  4. Le contrôle d'intégrité doit être HTTP: 1443. Il rejette le HTTP: 80 car la redirection 301.

aws elb setup

Configuration de NGINX

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

    server {
       listen         1443;
       server_name    www.example.org;
   } 
15
nu everest

Cette solution utilise une logique conditionnelle, mais comme le suggère la réponse acceptée, je pense également que c'est correct. Réf: https://stackoverflow.com/questions/4833238/nginx-conf-redirect-multiple-conditions

En outre, cela ne nécessite pas d'ouvrir de ports supplémentaires dans les paramètres de sécurité aws pour l'image. Vous pouvez terminer ssl dans AWS LB et acheminer le trafic https vers le port http 80 sur votre instance.

Dans cet exemple, le contrôle d'intégrité LB atteint/health sur le port 80 qui achemine vers le serveur d'applications, de sorte que le contrôle d'intégrité valide à la fois nginx et votre application respirent.

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;
  }
  ...
}
9
Jonny Mac

Vous pouvez maintenant créer un nouvel écouteur dans les paramètres de l'équilibreur de charge AWS qui redirige le port HTTP 80 vers le port HTTPS 443. Vous n'avez donc plus besoin de toucher la configuration nginx/Apache.

0
Kenny Greulich