88 votes

Comment forcer https sur elastic beanstalk ?

Je n'arrive pas à forcer https sur le niveau d'utilisation gratuit d'elastic beanstalk.

J'ai essayé la suggestion suivante à Comment forcer https sur amazon elastic beanstalk sans échouer le contrôle de santé ?

En utilisant cette règle de réécriture Apache

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{REQUEST_URI} !^/status$ 
RewriteCond %{REQUEST_URI} !^/version$ 
RewriteCond %{REQUEST_URI} !^/_hostmanager/ 
RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

Lorsque j'essaie cela, les demandes http ne sont pas redirigées vers https comme je le voudrais. Au contraire, la page http se charge normalement. J'ai également essayé d'utiliser l'en-tête X-Forwarded-Port avec le même résultat.

J'ai également essayé la règle de réécriture suivante

RewriteCond %{SERVER_PORT} 80
RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

Et cette règle provoque une boucle de redirection. Il semblerait donc que les règles de réécriture d'Apache ne détectent pas les en-têtes X-Forwarded-Port et X-Forwarded-Proto d'Elastic Load Balancer, mais une boucle de redirection n'est pas non plus ce que je recherche.

Aidez-moi, s'il vous plaît. Je suis nouveau sur AWS, Elastic Beanstalk, et je ne suis pas très familier avec les règles Apache. Je ne sais pas trop où aller à partir de là. Merci.

193voto

Zags Points 582

Cette réponse suppose que vous avez déjà activé https dans le groupe de sécurité de l'équilibreur de charge, que vous avez ajouté le certificat SSL à l'équilibreur de charge, que les ports 80 et 443 sont transférés par l'équilibreur de charge et que vous avez pointé votre nom de domaine vers l'environnement Elastic Beanstalk avec Route 53 (ou un service DNS équivalent).

Option 1 : Faire la redirection avec Apache

Cela n'est possible que si vous êtes sur un environnement Elastic Beanstalk qui utilise Apache (les déploiements basés sur AWS Linux 2 peuvent être configurés pour utiliser Apache). Cela peut ne pas fonctionner pour un déploiement basé sur Docker.

Amazon Linux 2

La plupart des plateformes basées sur AWS Linux version 2 ont la possibilité de choisir Apache comme hôte de proxy. Cela peut être fait en allant dans "Configuration" > "Software" > "Contai". "Container Options" et en définissant le "Proxy Server" comme étant "Apache", ou en ajoutant ce qui suit à l'un de vos fichiers de configuration. .config fichiers dans .ebextensions :

option_settings:
  aws:elasticbeanstalk:environment:proxy:
    ProxyServer: apache

Une fois cela fait, ajoutez un fichier de configuration nommé .platform/httpd/conf.d/ssl_rewrite.conf à votre codebase ( Documents AWS pertinents ) avec le contenu suivant :

RewriteEngine On
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</If>

Amazon Linux 1

Tout ce que vous avez à faire est d'ajouter ce qui suit à l'une de vos pages Web .config dans le .ebextensions de votre projet :

files:
    "/etc/httpd/conf.d/ssl_rewrite.conf":
        mode: "000644"
        owner: root
        group: root
        content: |
            RewriteEngine On
            <If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
            RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
            </If>

Explication

C'est relativement simple en dehors d'Elastic Beanstalk. On ajoute généralement une règle de réécriture Apache comme la suivante :

RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

Ou, si derrière un équilibreur de charge, comme nous le sommes dans ce cas :

RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]

Toutefois, ces configurations ne fonctionnent que dans le cadre d'une <VirtualHost> bloc. La modification du RewriteCond à un <If> lui permet de fonctionner correctement en dehors d'une <VirtualHost> ce qui nous permet de le placer dans un fichier de configuration Apache autonome. Notez que la configuration standard d'Apache sur CentOS (y compris la configuration d'ElasticBeanstalk) inclut tous les fichiers correspondant à /etc/httpd/conf.d/*.conf qui correspond au chemin d'accès au fichier où nous stockons ce fichier.

En -n '%{HTTP:X-Forwarded-Proto}' une partie de la condition l'empêche de rediriger si vous n'êtes pas derrière un équilibreur de charge, ce qui vous permet d'avoir une configuration partagée entre un environnement de production avec un équilibreur de charge et https, et un environnement de préparation qui est une instance unique et n'a pas https. Cela n'est pas nécessaire si vous utilisez des équilibreurs de charge et https sur tous vos environnements, mais cela ne fait pas de mal de l'avoir.

Option 2 : Faire la redirection avec l'ALB

Cela n'est possible que si vous utilisez un équilibreur de charge d'applications. Amazon fournit des instructions sur la manière de procéder ici : https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-httpredirect.html

Tout ce que vous avez à faire est d'ajouter ce qui suit à l'une de vos pages Web .config dans le .ebextensions de votre projet pour remplacer l'écouteur http par une redirection :

Resources:
 AWSEBV2LoadBalancerListener:
  Type: AWS::ElasticLoadBalancingV2::Listener
  Properties:
    LoadBalancerArn:
      Ref: AWSEBV2LoadBalancer
    Port: 80
    Protocol: HTTP
    DefaultActions:
      - Type: redirect
        RedirectConfig:
          Host: "#{host}"
          Path: "/#{path}"
          Port: "443"
          Protocol: "HTTPS"
          Query: "#{query}"
          StatusCode: "HTTP_301"

Les mauvaises solutions que j'ai vues

J'ai vu beaucoup de mauvaises solutions à ce problème, et il vaut la peine de les passer en revue pour comprendre pourquoi cette solution est nécessaire.

  1. Utilisez Cloudfront : Certaines personnes suggèrent d'utiliser une configuration Cloudfront sans cache en amont d'Elastic Beanstalk pour effectuer la redirection HTTP vers HTTPS. Cela ajoute un tout nouveau service (et donc une complexité supplémentaire) qui n'est pas vraiment approprié (Cloudfront est un CDN ; ce n'est pas le bon outil pour forcer le HTTPS sur un contenu essentiellement dynamique). La configuration Apache est la solution normale à ce problème et Elastic Beanstalk utilise Apache, donc c'est la voie à suivre.

  2. SSH dans le serveur et... : Ceci est complètement contraire à l'objectif d'Elastic Beanstalk et pose de nombreux problèmes. Toute nouvelle instance créée par autoscaling n'aura pas la configuration modifiée. Tout environnement cloné n'aura pas la configuration. N'importe quel nombre d'un ensemble raisonnable de changements d'environnement effacera la configuration. C'est une très mauvaise idée.

  3. Ecraser la configuration d'Apache avec un nouveau fichier : Cette solution se rapproche de la solution idéale, mais elle vous laisse avec un cauchemar de maintenance si Elastic Beanstalk modifie certains aspects de la configuration du serveur (ce qui peut très bien arriver). Voir aussi les problèmes dans l'article suivant.

  4. Modifier dynamiquement le fichier de configuration d'Apache pour ajouter quelques lignes : C'est une bonne idée. Le problème est que cela ne fonctionnera pas si Elastic Beanstalk change le nom de son fichier de configuration Apache par défaut, et que ce fichier peut être écrasé au moment où vous vous y attendez le moins : https://forums.aws.amazon.com/thread.jspa?threadID=163369

16voto

Adam Link Points 2370

EDIT : Bien que j'aime cette réponse, elle est maintenant très vieux . AWS a mis en place de nouveaux services (tels que Gestionnaire de certificats ) qui rendent une partie de cette réponse obsolète. De plus, l'utilisation de la .ebextensions avec Apache est une manière plus propre de gérer cette redirection comme expliqué ci-dessus.

Si vous hébergez votre site Web sur S3, certaines parties de cette réponse peuvent encore vous être utiles.


Cela a marché pour moi :

  1. Téléchargez le certificat vers AWS en utilisant le aws commande de la console. La structure de la commande est la suivante :

    aws iam upload-server-certificate --server-certificate-name CERTIFICATE_NAME --certificate-body "file://PATH_TO_CERTIFICATE.crt" --private-key "file://YOUR_PRIVATE_KEY.pem" --certificate-chain "file://YOUR_CERTIFICATE_CHAIN.ca-bundle" --path /cloudfront/
  2. Dans votre application Elastic Beanstalk, allez à Configuration -> Niveau de réseau -> Équilibrage des charges et cliquez sur le icône de la roue dentée .

  3. Sélectionnez Port de l'écouteur sécurisé comme 443 . Sélectionnez Protocole comme HTTPS . Sélectionnez le CERTIFICATE_NAME de étape 2 pour ID du certificat SSL . Sauvegardez la configuration.

  4. Allez à votre Console . Cliquez sur Instances EC2 . Cliquez sur Équilibreurs de charge . Cliquez sur les équilibreurs de charge. Cliquez sur Instances et faites défiler vers le bas pour voir les instances EC2 assignées à cet équilibreur de charge. Si l'instance EC2 porte le même nom que l'URL de votre application (ou quelque chose d'approchant), prenez note de l'adresse de l'instance. Nom DNS pour l'équilibreur de charge. Il doit être au format awseb-e-...

  5. Retournez à votre Console . Cliquez sur CloudFront . Cliquez sur Créer une distribution . Sélectionnez un Web distribution.

  6. Mettre en place la distribution. Définissez votre Origine Nom de domaine au nom DNS de l'équilibreur de charge que vous avez trouvé dans étape 5 . Réglez le Politique de protocole de visualisation à Redirection de HTTP vers HTTPS . Set Chaînes d'interrogation en avant à Oui . Set Noms de domaine alternatifs (CNAME) à l'URL ou aux URL que vous voulez utiliser pour votre application. Définissez Certificat SSL au CERTIFICATE_NAME que vous avez téléchargé dans étape 2 . Créez votre distribution.

  7. Cliquez sur le nom de votre distribution dans CloudFront. Cliquez sur Origines sélectionnez votre origine, puis cliquez sur Modifier . Assurez-vous que votre Politique de protocole d'origine es Visionneuse de match . Retourner en arrière. Cliquez sur Comportements sélectionnez votre origine, puis cliquez sur Modifier . Modifier En-têtes avant à Liste blanche et ajouter Hôte . Economisez.

Note : J'ai aussi écrit un guide plus long .

7voto

Kristian Points 412

Avec les nouveaux équilibreurs de charge d'application, vous pouvez le faire de manière assez triviale maintenant...

Assurez-vous de configurer l'un d'entre eux au moment où vous configurez un environnement EB (par défaut, il s'agit toujours d'un équilibreur de charge classique, je crois). Vous ne pouvez pas changer le type une fois que l'environnement est créé, alors recréez-le.

Une fois que c'est fait, allez dans vos paramètres EC2 -> Load Balancers. Cliquez sur l'équilibreur de charge que vous avez créé pour votre environnement EB. Vous devez vous assurer que vous avez configuré un listener HTTPS avant cette tâche. Assurez-vous que vous écoutez sur HTTPS 443 avec un certificat SSL et que vous transférez le trafic vers vos instances avec HTTP sur 80.

Ajoutez ensuite un nouveau listener qui écoute sur HTTP et ajoutez une action par défaut de "Redirect to :". Assurez-vous de définir HTTPS comme protocole, 443 comme port, "Original host, path, query" comme option et enfin 301 comme code de réponse HTTP.

Une fois que ce listener est ajouté, assurez-vous de mettre à jour le groupe de sécurité de votre EC2 Load Balancer pour accepter les connexions HTTPS et HTTP, vous verrez un petit signe d'avertissement sur le listener pour vous le rappeler !

Chris

6voto

Marc Points 61

La directive <If> la plus votée ne fonctionne pas pour moi. La directive <If> ne fonctionne qu'avec Apache 2.4+, mais ElasticBeanstalk a la version 2.2.x.

Donc, en suivant les mêmes conseils que ci-dessus. Créez un fichier appelé .ebextensions/https_rewrite.config avec le contenu suivant

files:
    "/etc/httpd/conf.d/ssl_rewrite.conf":
        mode: "000644"
        owner: root
        group: root
        content: |
            LoadModule rewrite_module modules/mod_rewrite.so
            RewriteEngine On
            # This will enable the Rewrite capabilities
            RewriteCond %{HTTPS} !=on
            # This checks to make sure the connection is not already HTTPS
            RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]

Cela semble fonctionner pour moi.

Pour savoir comment intégrer ce fichier dans votre fichier WAR, consultez cette page. réponse

4voto

booshong Points 687

Edit : La solution Zags est plus général et plus correct. Je la recommande plutôt que la mienne (qui est spécifique à un environnement python).

Voici une solution propre et rapide que j'ai trouvée et qui évite de modifier le fichier wsgi.conf ou d'utiliser CloudFront.

Dans votre fichier .ebextensions/some_file.config :

# Redirect HTTP to HTTPS
  "/etc/httpd/conf.d/https_redirect.conf":
    mode: "000644"
    owner: root
    group: root
    content: |
      <Directory /opt/python/current/app/>
      RewriteEngine on
      RewriteCond %{HTTP:X-Forwarded-Proto} ^http$
      RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
      </Directory>

J'ai l'impression que c'est trop facile, mais ça semble bien fonctionner.

Notez également que je redirige explicitement HTTP au lieu de "pas HTTPS".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X