Force élastique de haricot magique https

12

Je rencontre des problèmes pour forcer HTTPS avec un site que je déploie via AWS Elastic Beanstalk.

Il s'agit d'une application frontale utilisant EmberJS. Je tourne en rond depuis de nombreux jours en essayant de comprendre comment rediriger le trafic http vers https. J'utilise Amazon Linux AMI sur ma machine EC2.

Je suis arrivé à la conclusion (toujours pas sûr que ce soit vrai) que ce n'est pas dans Elastic Beanstalk que je force HTTPS. J'autorise HTTP et HTTPS via mon équilibreur de charge Elastic Beanstalk, et j'essaie de rediriger sur le serveur.

C'est là que je rencontre des problèmes. Je trouve de nombreuses réponses sur les règles de réécriture sans mod_rewritelesquelles sont basées sur l'en- X-Forwarded-Prototête, mais ce fichier n'existe pas sur ma machine EC2 selon une recherche de recherche.

J'ai également essayé de créer un fichier de configuration dans le .ebextensionsrépertoire, mais cela n'a pas fonctionné non plus.

La principale chose que j'essaie de faire est de diriger les utilisateurs vers https lorsqu'ils essaient de frapper l'adresse http. Tous les pointeurs ou suggestions sont très appréciés, merci!

EDIT: j'utilise Debian jessie v1.4.1 64 bits exécutant Python 3.4 (préconfiguré - Docker)

awwester
la source
Il semble qu'Internet ne parvienne pas à s'entendre sur une solution unique, complète et opérationnelle à ce problème. J'espère que vous pourrez obtenir de l'aide ici dans mon article . J'ai dû sauter à travers des cerceaux pour arriver à cela, enfin.
ADTC

Réponses:

7

Je pense que vous devez spécifier quel environnement Elastic Beanstalk vous utilisez (voir: Plates-formes prises en charge ), car un environnement différent a une configuration différente.

Fondamentalement, vous devez personnaliser:

  • Équilibreur de charge élastique :
    • Écoutez le port 80 et procurez-le au port 80 de l'instance EC2.
    • Écoutez sur le port 443 et procurez-le au port d'instance EC2 443.
  • Serveur / proxy Web EC2 :
    • Écoutez sur le port 80 et répondez avec redirection vers HTTPS.
    • Écoutez sur le port 443 et répondez à la demande.

Pour le personnaliser, vous pouvez utiliser CLI ou .ebextensions.

Vous pouvez cocher Activer HTTPS et HTTP-Redirect sur AWS Elastic Beanstalk . Il vous explique comment configurer Elastic Beanstalk Single Docker Container pour servir HTTPS et HTTP (rediriger vers HTTPS). Vous pouvez ajuster la configuration selon vos besoins.

Edward Samuel
la source
Hé, super article, je suis en train d'essayer ça.
2015 à 15h01
des idées sur la façon de ne pas inclure les certificats dans ce fichier, préférez ne pas garder cela dans le contrôle de code source? Les certificats que nous avons chargés sont-ils déjà disponibles quelque part? Je n'arrive pas à les trouver sur le système de fichiers
awwester
Vous pouvez placer votre fichier de certificat SSL dans S3. Pour permettre à Elastic Beanstalk de télécharger un objet S3 privé, vous pouvez lire ceci .
Edward Samuel
Pour le certificat SSL ELB, vous pouvez suivre la documentation AWS: Certificats SSL pour l'équilibrage de charge élastique . Ensuite, vous pouvez obtenir la ressource de certificat SSL au arn:aws:iam::123456789012:server-certificate/YourSSLCertificateformat.
Edward Samuel
J'ai le certificat SSL configuré et j'ai l'arn qui irait dans 00-load-balancer (je fais en fait la configuration de l'équilibreur de charge via l'interface utilisateur), mais ne semble pas obtenir l'emplacement à mettre dans le serveur settings ssl_certificate /opt/ssl/default-ssl.crt;Quand j'obtiens les informations pour le cert, ça me donne un "chemin" mais c'est juste "/"
awwester
10

Il est également possible de le faire un peu plus facilement, sans toucher à l'équilibreur de charge, en utilisant l'en- X-Forwarded-Prototête défini par ELB. Voici ce que j'ai fini par faire:

files:
  "/etc/nginx/sites-available/elasticbeanstalk-nginx-docker-proxy.conf":
    mode: "00644"
    owner: root
    group: root
    content: |
      map $http_upgrade $connection_upgrade {
        default        "upgrade";
        ""            "";
      }

      server {
        listen 80;

        gzip on;
        gzip_comp_level 4;
        gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        access_log    /var/log/nginx/access.log;

        location / {
          proxy_pass            http://docker;
          proxy_http_version    1.1;

          proxy_set_header      Connection      $connection_upgrade;
          proxy_set_header      Upgrade         $http_upgrade;
          proxy_set_header      Host            $host;
          proxy_set_header      X-Real-IP       $remote_addr;
          proxy_set_header      X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        if ($http_x_forwarded_proto = 'http') {
          return 301 https://$host$request_uri;
        }
      }
FX
la source
De loin la solution la plus simple. Je ne vous remercierai jamais assez!
Chris Martin
Oui, c'est la bonne façon dans la plupart des scénarios.
jlegler
3

Elastic Beanstalk ne prend pas en charge plusieurs ports à partir d'un seul conteneur Docker, vous devez donc gérer cela au niveau du proxy comme suggéré. Cependant, votre instance EC2 n'a pas besoin de connaître votre certificat, car vous pouvez mettre fin à la connexion SSL sur l'équilibreur de charge.

Dans votre .ebextensionsrépertoire, créez une configuration pour le proxy nginx qui contient deux configurations de serveur; celui qui fait office de proxy http://docker(la configuration par défaut, le port 80) et celui qui redirige vers https (j'ai choisi le port 8080).

.ebextensions/01-nginx-proxy.config:

files:
  "/etc/nginx/sites-available/000-default.conf":
    mode: "000644"
    owner: root
    group: root
    content: |
      map $http_upgrade $connection_upgrade {
          default        "upgrade";
          ""            "";
      }

      server {
          listen 80;

          gzip on;
          gzip_comp_level 4;
          gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

          access_log    /var/log/nginx/access.log;

          location / {
              proxy_pass            http://docker;
              proxy_http_version    1.1;

              proxy_set_header    Connection            $connection_upgrade;
              proxy_set_header    Upgrade                $http_upgrade;
              proxy_set_header    Host                $host;
              proxy_set_header    X-Real-IP            $remote_addr;
              proxy_set_header    X-Forwarded-For        $proxy_add_x_forwarded_for;
          }
      }

      server {
          listen 8080;

          location / {
              return 301 https://$host$request_uri;
          }
      }

commands:
   00_enable_site:
    command: 'rm -f /etc/nginx/sites-enabled/* && ln -s /etc/nginx/sites-available/000-default.conf /etc/nginx/sites-enabled/000-default.conf'

Créez une deuxième configuration pour l'équilibreur de charge EB et les groupes de sécurité qui les définissent comme suit:

  • Instance EC2 :
    • Autoriser le trafic sur les ports 80/8080 à partir de l'équilibreur de charge
    • Autoriser le trafic sur le port 22 depuis n'importe où (pour l'accès ssh, facultatif)
  • Équilibreur de charge :
    • Transférer le port 443 HTTPS au port 80 HTTP
    • Transférer le port 80 HTTP vers le port 8080 HTTP

.ebextensions/02-load-balancer.config:

"Resources" : {
  "AWSEBSecurityGroup": {
    "Type" : "AWS::EC2::SecurityGroup",
    "Properties" : {
      "GroupDescription" : "Instance security group (22/80/8080 in)",
      "SecurityGroupIngress" : [ {
          "IpProtocol" : "tcp",
          "FromPort" : "80",
          "ToPort" : "80",
          "SourceSecurityGroupId" : { "Ref" : "AWSEBLoadBalancerSecurityGroup" }
        }, {
          "IpProtocol" : "tcp",
          "FromPort" : "8080",
          "ToPort" : "8080",
          "SourceSecurityGroupId" : { "Ref" : "AWSEBLoadBalancerSecurityGroup" }
        }, {
          "IpProtocol" : "tcp",
          "FromPort" : "22",
          "ToPort" : "22",
          "CidrIp" : "0.0.0.0/0"
        } ]
    }
  },
  "AWSEBLoadBalancerSecurityGroup": {
    "Type" : "AWS::EC2::SecurityGroup",
    "Properties" : {
      "GroupDescription" : "Load balancer security group (80/443 in, 80/8080 out)",
      "VpcId" : "<vpc_id>",
      "SecurityGroupIngress" : [ {
          "IpProtocol" : "tcp",
          "FromPort" : "80",
          "ToPort" : "80",
          "CidrIp" : "0.0.0.0/0"
        }, {
          "IpProtocol" : "tcp",
          "FromPort" : "443",
          "ToPort" : "443",
          "CidrIp" : "0.0.0.0/0"
        } ],
      "SecurityGroupEgress": [ {
          "IpProtocol" : "tcp",
          "FromPort" : "80",
          "ToPort" : "80",
          "CidrIp" : "0.0.0.0/0"
        }, {
          "IpProtocol" : "tcp",
          "FromPort" : "8080",
          "ToPort" : "8080",
          "CidrIp" : "0.0.0.0/0"
        } ]
    }
  },
  "AWSEBLoadBalancer" : {
    "Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
    "Properties" : {
      "Listeners" : [ {
          "LoadBalancerPort" : "80",
          "InstancePort" : "8080",
          "Protocol" : "HTTP"
        }, {
          "LoadBalancerPort" : "443",
          "InstancePort" : "80",
          "Protocol" : "HTTPS",
          "SSLCertificateId" : "arn:aws:iam::<certificate_id>:<certificate_path>"
        } ]
    }
  }
}

(Remarque: n'oubliez pas de remplacer SSLCertificateId et VpcId par vos valeurs).

Tout trafic sur le port 80 de l'équilibreur de charge (HTTP) atteindra le port 8080 sur l'instance EC2, qui redirige vers HTTPS. Le trafic sur le port 443 sur l'équilibreur de charge (HTTPS) finira par être servi par le port 80 sur l'instance EC2, qui est le proxy de docker.

Michael de Hoog
la source
0

J'utilise Terraform pour activer la redirection HTTP vers HTTPS sur ElasticBeanstalk,

Je viens d'ajouter une règle d'écoute supplémentaire

data "aws_alb_listener" "http" { //Get ARN of Listener on Port-80
  load_balancer_arn = aws_elastic_beanstalk_environment.myapp.load_balancers[0]
  port              = 80
}


resource "aws_alb_listener_rule" "redirect_http_to_https" {
  listener_arn = data.aws_alb_listener.http.arn
  action {
    type = "redirect"
    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
  condition {
    host_header {
      values = ["*.*"]
    }
  }
}
Denis Astahov
la source