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

27

Actuellement, j'ai un ELB qui dessert à 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 envoyées au 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 qu'il iffallait éviter à tout prix dans la configuration de nginx, et ce serait pour chaque demande. 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 en tant que point de terminaison HTTPS et n'envoie que du trafic HTTP à votre serveur, vous rompre la capacité 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 la if configuration.

Jordan Reiter
la source
Bonjour, pouvez-vous me dire où mettez-vous ces codes?
YuAn Shaolin Maculelê Lai
@ YuAnShaolinMaculelêLai Bien sûr. Ce sont des fichiers de configuration pour nginx, donc je viens de mettre le code dans un fichier dans /etc/nginx/conf.d/. Je nomme généralement le fichier domainname.conf où "domainname" est le domaine du site Web en question. Vous pouvez nommer le fichier comme vous le souhaitez tant qu'il se termine par .conf.
Jordan Reiter
Merci beaucoup. J'ai essayé de créer un nouveau fichier suivi par .conf. Mais ça n'a pas marché pour moi. Ensuite, j'ai mis le code dans le fichier généré à partir d'AWS dans /etc/nginx/conf.d/. Ça fonctionne maintenant.
YuAn Shaolin Maculelê Lai

Réponses:

9

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 peuvent être utilisés . Le conseil d'utiliser d'autres directives lorsqu'elles sont disponibles s'applique toujours très bien.

ceejayoz
la source
Cette page indique également que "if a des problèmes lorsqu'il est utilisé dans un contexte de localisation". Il me semble que vous pouvez faire ce que vous devez faire à l'extérieur location {}, à la server {}place. (Mais s'il vous plaît, faites-moi savoir si c'est incorrect!)
Excalibur
15
  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.

configuration de aws elb

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;
   } 
nu everest
la source
qu'en est-il des paramètres de contrôle d'intégrité? pourriez-vous également nous en dire plus.
samkhan13
cela ne fonctionnait pas avec le contrôle de la barre de sécurité défini sur http: 80, le contrôle de santé échoue.
samkhan13
2
Le bilan de santé devrait l'être HTTP:1443. Il rejette le HTTP:80car la redirection 301.
cbron
cela a fonctionné principalement pour moi mais la ligne de réécriture ne fonctionnait pas avec mon domaine générique. Cet autre article a corrigé cette partie: serverfault.com/questions/447258/…
Ron
9

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: /programming/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 est acheminé 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;
  }
  ...
}
Jonny Mac
la source
1
il doit y avoir une façon plus élégante de le faire
Edward
0

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

Kenny Greulich
la source
malheureusement, il n'est pas encore pris en charge dans Cloudformation
Aryeh Leib Taurog