Forza elastica del fagiolo magico https


12

Ho problemi a forzare HTTPS con un sito che sto implementando tramite AWS Elastic Beanstalk.

È un'applicazione frontend che utilizza EmberJS. Ho girato in tondo per molti giorni cercando di capire come reindirizzare il traffico http su https. Sto usando Amazon Linux AMI sulla mia macchina EC2.

Sono giunto alla conclusione (ancora non sono sicuro che sia giusto) che non è all'interno dell'Elastic Beanstalk che forzo HTTPS. Sto consentendo sia HTTP che HTTPS tramite il mio bilanciamento del carico del bean di bean elastico e sto tentando di reindirizzare sul server.

Questo è dove sto incontrando problemi. Sto trovando molte risposte sulle regole di riscrittura senza le mod_rewritequali sono basate X-Forwarded-Protosull'intestazione, ma quel file non esiste sul mio computer EC2 secondo una ricerca di ricerca.

Ho anche provato a creare un file di configurazione all'interno della .ebextensionsdirectory, ma non ha funzionato neanche.

La cosa principale che sto cercando di fare è avere gli utenti indirizzati a HTTPS quando provano a colpire l'indirizzo http. Eventuali suggerimenti o suggerimenti sono molto apprezzati, grazie!

EDIT: sto usando Debian jessie v1.4.1 a 64 bit con Python 3.4 (preconfigurato - Docker)


Sembra che Internet non possa essere d'accordo su un'unica soluzione completa e funzionante a questo problema. Spero che tu possa ottenere aiuto qui nel mio post . Ho dovuto saltare attraverso i cerchi per trovare questo, finalmente.
ADTC,

Risposte:


7

Penso che sia necessario specificare quale ambiente Elastic Beanstalk si utilizza (consultare: Piattaforme supportate ), poiché un ambiente diverso ha una configurazione diversa.

Fondamentalmente, è necessario personalizzare:

  • Bilanciamento del carico elastico :
    • Ascolta sulla porta 80 e esegui il proxy sulla porta 80 dell'istanza EC2.
    • Ascolta sulla porta 443 e esegui il proxy sulla porta 443 di istanza EC2.
  • Server Web / proxy EC2 :
    • Ascolta sulla porta 80 e rispondi con reindirizzamento a HTTPS.
    • Ascolta sulla porta 443 e servi la richiesta.

Per personalizzarlo, è possibile utilizzare CLI o .ebextensions.

Puoi selezionare Abilita HTTPS e HTTP-Redirect su AWS Elastic Beanstalk . Spiega come configurare Elastic Beanstalk Single Docker Container per servire HTTPS e HTTP (reindirizzamento a HTTPS). È possibile regolare la configurazione in base alle proprie esigenze.


ehi, ottimo articolo, sto provando questo.
awwester,

qualche idea su come non includere i certificati all'interno di quel file, preferirebbe non tenerlo nel controllo del codice sorgente? I certificati che abbiamo caricato sono già disponibili da qualche parte? Non riesco a trovarli sul filesystem
awwester,

È possibile inserire il file del certificato SSL in S3. Per consentire a Elastic Beanstalk di scaricare l'oggetto S3 privato, puoi leggere questo .
Edward Samuel,

Per il certificato SSL ELB, puoi seguire la documentazione AWS: certificati SSL per il bilanciamento del carico elastico . È quindi possibile ottenere la risorsa del certificato SSL in arn:aws:iam::123456789012:server-certificate/YourSSLCertificateformato.
Edward Samuel,

Ho impostato il certificato SSL e ho l'arn che andrebbe in 00-load-balancer (sto effettivamente eseguendo la configurazione del bilanciamento del carico attraverso l'interfaccia utente), ma non riesco a trovare la posizione da inserire nel server settings ssl_certificate /opt/ssl/default-ssl.crt;Quando ottengo le informazioni per il certificato, mi dà un "percorso" ma è solo "/"
awwester

10

È anche possibile farlo un po 'più facilmente, senza toccare il bilanciamento del carico, usando l' X-Forwarded-Protointestazione impostata da ELB. Ecco cosa ho finito per fare:

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;
        }
      }

Di gran lunga la soluzione più semplice. Non posso ringraziarti abbastanza!
Chris Martin,

Sì, questo è il modo giusto nella maggior parte degli scenari.
jlegler,

3

Elastic Beanstalk non supporta più porte da un singolo contenitore Docker, quindi è necessario gestirlo a livello proxy come suggerito. Tuttavia, l'istanza EC2 non deve conoscere il certificato, poiché è possibile interrompere la connessione SSL dal bilanciamento del carico.

Nella tua .ebextensionsdirectory, crea una configurazione per il proxy nginx che contiene due configurazioni del server; uno che esegue http://dockeril proxy (la configurazione predefinita, porta 80) e uno che reindirizza a https (ho scelto la porta 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'

Creare una seconda configurazione per il bilanciamento del carico EB e i gruppi di sicurezza che li imposta come segue:

  • Istanza EC2 :
    • Consentire il traffico sulle porte 80/8080 dal bilanciamento del carico
    • Consenti traffico sulla porta 22 da qualsiasi luogo (per accesso ssh, opzionale)
  • Bilanciamento del carico :
    • Inoltra la porta 443 HTTPS alla porta 80 HTTP
    • Inoltra la porta 80 HTTP alla porta 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>"
        } ]
    }
  }
}

(Nota: non dimenticare di sostituire SSLCertificateId e VpcId con i tuoi valori).

Qualsiasi traffico sulla porta 80 del bilanciamento del carico (HTTP) raggiungerà la porta 8080 sull'istanza EC2, che reindirizza a HTTPS. Il traffico sulla porta 443 sul bilanciamento del carico (HTTPS) finirà per essere servito dalla porta 80 sull'istanza EC2, che è il proxy docker.


0

Sto usando Terraform per abilitare il reindirizzamento da HTTP a HTTPS su ElasticBeanstalk,

Ho appena aggiunto Regola ascoltatore aggiuntiva

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 = ["*.*"]
    }
  }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.