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.