Kekuatan Pohon Kacang elastis https

12

Saya mengalami masalah memaksa HTTPS dengan situs yang saya gunakan melalui AWS Elastic Beanstalk.

Ini adalah aplikasi frontend menggunakan EmberJS. Saya telah berputar-putar selama berhari-hari mencoba mencari cara untuk mengarahkan lalu lintas http ke https. Saya menggunakan Amazon Linux AMI di mesin EC2 saya.

Saya sampai pada kesimpulan (masih tidak yakin apakah ini benar) bahwa tidak dalam Elastic Beanstalk saya memaksakan HTTPS. Saya mengizinkan HTTP dan HTTPS melalui Elastic Beanstalk Load Balancer saya, dan saya mencoba untuk mengarahkan ulang di server.

Di sinilah saya mengalami masalah. Saya menemukan banyak jawaban tentang aturan penulisan ulang yang tanpanya mod_rewriteberbasis di sekitar X-Forwarded-ProtoHeader, tetapi file itu tidak ada di mesin EC2 saya menurut pencarian pencarian.

Saya juga mencoba membuat file config di dalam .ebextensionsdirektori, tetapi tidak berhasil.

Hal utama yang saya coba lakukan adalah meminta pengguna diarahkan ke https ketika mencoba menekan alamat http. Setiap petunjuk atau saran sangat dihargai, terima kasih!

EDIT: Saya menggunakan 64bit Debian jessie v1.4.1 menjalankan Python 3.4 (Pra-konfigurasi - Docker)

orang barat
sumber
Tampaknya Internet tidak dapat menyetujui solusi tunggal, lengkap dan berfungsi untuk masalah ini. Semoga Anda bisa mendapatkan bantuan di sini di posting saya . Saya harus melompat melalui lingkaran untuk mendapatkan ini, akhirnya.
ADTC

Jawaban:

7

Saya pikir Anda perlu menentukan lingkungan Elastic Beanstalk apa yang Anda gunakan (lihat: Platform yang Didukung ), karena lingkungan yang berbeda memiliki konfigurasi yang berbeda.

Pada dasarnya, Anda perlu menyesuaikan:

  • Penyeimbang Beban Elastis :
    • Dengarkan pada port 80 dan proksi ke port instance EC2 80.
    • Dengarkan pada port 443 dan proksi ke port instance EC2 443.
  • Server Web EC2 / Proxy :
    • Dengarkan pada port 80 dan respons dengan redirect ke HTTPS.
    • Dengarkan pada port 443 dan melayani permintaan.

Untuk menyesuaikannya, Anda dapat menggunakan CLI atau .ebextensions.

Anda dapat memeriksa Aktifkan HTTPS dan HTTP-Redirect di AWS Elastic Beanstalk . Ini memberitahu Anda cara mengkonfigurasi Container Beanstalk Single Docker melayani HTTPS dan HTTP (redirect ke HTTPS). Anda dapat menyesuaikan konfigurasi sesuai kebutuhan.

Edward Samuel
sumber
hei, artikel bagus, saya sedang dalam proses mencoba ini.
awwester
ada ide bagaimana untuk tidak menyertakan sertifikat di dalam file itu, lebih suka tidak menyimpannya dalam kendali sumber? Apakah sertifikat yang kami muat sudah tersedia di suatu tempat? Sepertinya saya tidak dapat menemukannya di sistem file
awwester
Anda dapat meletakkan file sertifikat SSL Anda di S3. Untuk mengizinkan Elastic Beanstalk mengunduh objek S3 pribadi, Anda dapat membaca ini .
Edward Samuel
Untuk sertifikat SSL ELB, Anda dapat mengikuti dokumentasi AWS: Sertifikat SSL untuk Penyeimbangan Beban Elastis . Kemudian Anda bisa mendapatkan sumber daya sertifikat SSL dalam arn:aws:iam::123456789012:server-certificate/YourSSLCertificateformat.
Edward Samuel
Saya memiliki sertifikat SSL yang diatur dan saya memiliki arn yang akan masuk dalam 00-load-balancer (saya sebenarnya sedang melakukan konfigurasi load balancer melalui UI), tetapi sepertinya tidak bisa mendapatkan lokasi untuk dimasukkan ke dalam server pengaturan ssl_certificate /opt/ssl/default-ssl.crt;Ketika saya mendapatkan informasi untuk sertifikat, itu memberi saya "jalan" tetapi itu hanya "/"
awwester
10

Dimungkinkan juga untuk melakukan itu dengan lebih mudah, tanpa menyentuh penyeimbang beban, dengan menggunakan X-Forwarded-Protoheader yang ditetapkan oleh ELB. Inilah yang akhirnya saya lakukan:

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
sumber
Sejauh ini solusi termudah. Tidak cukup terima kasih!
Chris Martin
Yap, ini adalah cara yang benar di sebagian besar skenario.
jlegler
3

Elastic Beanstalk tidak mendukung banyak port dari Container Docker Tunggal, jadi Anda perlu menanganinya di level proxy seperti yang disarankan. Namun, instance EC2 Anda tidak perlu tahu tentang sertifikat Anda, karena Anda dapat mengakhiri koneksi SSL di load balancer.

Di .ebextensionsdirektori Anda , buat konfigurasi untuk proksi nginx yang berisi dua konfigurasi server; yang proksi http://docker(konfigurasi default, port 80), dan yang mengarahkan ke https (saya memilih 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'

Buat konfigurasi kedua untuk penyeimbang beban dan grup keamanan EB yang mengaturnya sebagai berikut:

  • Contoh EC2 :
    • Izinkan lalu lintas pada port 80/8080 dari load balancer
    • Izinkan lalu lintas di port 22 dari mana saja (untuk akses ssh, opsional)
  • Load balancer :
    • Teruskan port 443 HTTPS ke port 80 HTTP
    • Meneruskan port 80 HTTP ke 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>"
        } ]
    }
  }
}

(Catatan: jangan lupa untuk mengganti SSLCertificateId dan VpcId dengan nilai Anda).

Setiap lalu lintas pada port 80 dari load balancer (HTTP) akan mencapai port 8080 pada instance EC2, yang dialihkan ke HTTPS. Lalu lintas pada port 443 pada load balancer (HTTPS) akan berakhir dilayani oleh port 80 pada instance EC2, yang merupakan proxy buruh pelabuhan.

Michael de Hoog
sumber
0

Saya menggunakan Terraform untuk mengaktifkan pengalihan HTTP ke HTTPS di ElasticBeanstalk,

Saya baru saja menambahkan Aturan Pendengar tambahan

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
sumber