Elastic Beanstalk บังคับให้ https


12

ฉันมีปัญหาในการบังคับใช้ HTTPS กับเว็บไซต์ที่ฉันใช้งานผ่าน AWS Elastic Beanstalk

มันเป็นแอพพลิเคชั่นส่วนหน้าโดยใช้ EmberJS ฉันอยู่ในแวดวงเป็นเวลาหลายวันเพื่อหาวิธีเปลี่ยนเส้นทางการรับส่งข้อมูล http ไปยัง https ฉันใช้ Amazon Linux AMI บนเครื่อง EC2 ของฉัน

ฉันมาถึงข้อสรุป (ยังไม่แน่ใจว่าถูกต้องหรือไม่) ว่าไม่อยู่ใน Elastic Beanstalk ที่ฉันบังคับ HTTPS ฉันอนุญาตให้ทั้ง HTTP และ HTTPS ผ่าน Elastic Beanstalk Load Balancer ของฉันและพยายามเปลี่ยนเส้นทางบนเซิร์ฟเวอร์

ที่นี่ฉันกำลังเจอปัญหา ฉันค้นหาคำตอบมากมายเกี่ยวกับการเขียนกฎใหม่โดยไม่ต้องmod_rewriteอาศัยX-Forwarded-ProtoHeader แต่ไฟล์นั้นไม่มีอยู่ในเครื่อง EC2 ของฉันตามการค้นหาค้นหา

ฉันพยายามสร้างไฟล์ปรับแต่งภายใน.ebextensionsไดเรกทอรีด้วย แต่ก็ไม่ได้ผลเหมือนกัน

สิ่งสำคัญที่ฉันพยายามทำคือให้ผู้ใช้ไปที่ https เมื่อพยายามกดที่อยู่ http คำแนะนำหรือข้อเสนอแนะใด ๆ ขอบคุณมาก!

แก้ไข: ฉันใช้ 64 บิต Debian jessie v1.4.1 ใช้ Python 3.4 (กำหนดค่าล่วงหน้า - Docker)


ดูเหมือนว่าอินเทอร์เน็ตจะไม่สามารถเห็นด้วยกับวิธีแก้ปัญหาเดียวที่สมบูรณ์และทำงานได้กับปัญหานี้ หวังว่าคุณจะได้รับความช่วยเหลือบางส่วนที่นี่ในการโพสต์ของฉัน ฉันต้องกระโดดผ่านห่วงเพื่อมากับสิ่งนี้ในที่สุด
— ADTC

คำตอบ:


7

ฉันคิดว่าคุณต้องระบุสภาพแวดล้อม Elastic Beanstalk ที่คุณใช้ (ดู: แพลตฟอร์มที่รองรับ ) เนื่องจากสภาพแวดล้อมที่แตกต่างกันมีการกำหนดค่าที่แตกต่างกัน

โดยทั่วไปคุณจะต้องปรับแต่ง:

  • โหลดบาลานซ์บาลานเซอร์ :
    • ฟังพอร์ต 80 และเชื่อมต่อกับพอร์ตอินสแตนซ์ EC2 80
    • ฟังพอร์ต 443 และเชื่อมต่อกับพอร์ตอินสแตนซ์ของ EC2 443
  • เว็บเซิร์ฟเวอร์ / พร็อกซี EC2 :
    • ฟังพอร์ต 80 และตอบกลับโดยเปลี่ยนเส้นทางไปที่ HTTPS
    • ฟังพอร์ต 443 และตอบสนองคำขอ

การปรับแต่งมันคุณสามารถใช้ CLI .ebextensionsหรือ

คุณสามารถตรวจสอบการเปิดใช้งาน HTTPS และใช้ HTTP เปลี่ยนเส้นทางบน AWS ยืดหยุ่นฝักถั่ว มันบอกวิธีการกำหนดค่า Elastic Beanstalk Single Docker Container ให้บริการ HTTPS และ HTTP (เปลี่ยนเส้นทางไปยัง HTTPS) คุณสามารถปรับการตั้งค่าตามที่คุณต้องการ


เฮ้เป็นบทความที่ดีฉันกำลังพยายามทำสิ่งนี้อยู่
— awwester

แนวคิดใดบ้างที่จะไม่รวม certs ไว้ในไฟล์นั้นจะไม่เก็บไว้ในการควบคุมซอร์สหรือไม่? certs ที่เราโหลดมีอยู่แล้วบ้างไหม? ฉันดูเหมือนจะไม่พบพวกเขาในระบบไฟล์
— awwester

คุณสามารถวางไฟล์ใบรับรอง SSL ของคุณใน S3 ในการอนุญาตให้ยืดหยุ่นฝักถั่วดาวน์โหลดส่วนตัววัตถุ S3 คุณสามารถอ่านนี้
— Edward Samuel

สำหรับใบรับรอง SSL ELB คุณสามารถทำตามเอกสาร AWS: ใบรับรอง SSL สำหรับ Elastic Load Balancing จากนั้นคุณสามารถรับทรัพยากรใบรับรอง SSL ในarn:aws:iam::123456789012:server-certificate/YourSSLCertificateรูปแบบ
— Edward Samuel

ฉันมีการตั้งค่าใบรับรอง SSL และฉันมี arn ที่จะไปใน 00-load-balancer (ฉันจริง ๆ แล้วทำการตั้งค่า load balancer ผ่าน UI) แต่ดูเหมือนจะไม่ได้ตำแหน่งที่จะใส่ในเซิร์ฟเวอร์ ตั้งค่าssl_certificate /opt/ssl/default-ssl.crt;เมื่อฉันได้รับข้อมูลสำหรับใบรับรองมันทำให้ฉัน "เส้นทาง" แต่มันเป็นเพียงแค่ "/"
— awwester

10

นอกจากนี้ยังเป็นไปได้ที่จะทำเช่นนั้นได้ง่ายขึ้นโดยไม่ต้องสัมผัสตัวโหลดบาลานซ์โดยใช้X-Forwarded-Protoส่วนหัวที่กำหนดโดย ELB นี่คือสิ่งที่ฉันทำลงไป:

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

โดยวิธีที่ง่ายที่สุด ขอบคุณมากพอ!
— Chris Martin

ใช่นี่เป็นวิธีที่เหมาะสมในสถานการณ์ส่วนใหญ่
— jlegler

3

Elastic Beanstalk ไม่รองรับพอร์ตหลายพอร์ตจาก Single Docker Container ดังนั้นคุณต้องจัดการสิ่งนี้ในระดับพร็อกซีตามที่แนะนำ อย่างไรก็ตามอินสแตนซ์ EC2 ของคุณไม่จำเป็นต้องรู้เกี่ยวกับใบรับรองของคุณเนื่องจากคุณสามารถยุติการเชื่อมต่อ SSL ที่ load balancer

ใน.ebextensionsไดเรกทอรีของคุณสร้างการกำหนดค่าสำหรับพร็อกซี nginx ที่มีการกำหนดค่าเซิร์ฟเวอร์สองรายการ อันที่หนึ่งพร็อกซี่http://docker(การกำหนดค่าเริ่มต้นพอร์ต 80) และอีกอันที่เปลี่ยนเส้นทางไปยัง https (ฉันเลือกพอร์ต 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'

สร้างการกำหนดค่าที่สองสำหรับตัวโหลดบาลานซ์ EB และกลุ่มความปลอดภัยที่ตั้งค่าดังต่อไปนี้:

  • อินสแตนซ์ EC2 :
    • อนุญาตการรับส่งข้อมูลบนพอร์ต 80/8080 จากตัวโหลดบาลานซ์
    • อนุญาตการรับส่งข้อมูลบนพอร์ต 22 ได้จากทุกที่ (สำหรับการเข้าถึง ssh หรือไม่ก็ได้)
  • เครื่องถ่วงโหลด :
    • ส่งต่อพอร์ต 443 HTTPS ไปที่พอร์ต 80 HTTP
    • ส่งต่อพอร์ต 80 HTTP ไปยังพอร์ต 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>"
        } ]
    }
  }
}

(หมายเหตุ: อย่าลืมแทนที่ SSLCertificateId และ VpcId ด้วยค่าของคุณ)

ทราฟฟิกใด ๆ บนพอร์ต 80 ของ load balancer (HTTP) จะกดพอร์ต 8080 บนอินสแตนซ์ EC2 ซึ่งเปลี่ยนเส้นทางไปยัง HTTPS การรับส่งข้อมูลบนพอร์ต 443 บนตัวโหลดบาลานซ์ (HTTPS) จะจบลงด้วยการให้บริการโดยพอร์ต 80 บนอินสแตนซ์ EC2 ซึ่งเป็นพร็อกซีของนักเทียบท่า


0

Iam ใช้ Terraform เพื่อเปิดใช้งานการเปลี่ยนเส้นทาง HTTP เป็น HTTPS บน ElasticBeanstalk

ฉันเพิ่งเพิ่มกฎการฟังเพิ่มเติม

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 = ["*.*"]
    }
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.