การเปลี่ยนเส้นทาง EC2 Elastic Load Balancer จาก HTTP เป็น HTTPS


107

ฉันต้องการที่จะเปลี่ยนเส้นทางทั้งหมดที่ร้องขอ HTTP การร้องขอ https บนELB ฉันมีอินสแตนซ์ EC2 สองรายการ ฉันใช้ nginx สำหรับเซิร์ฟเวอร์ ฉันได้ลองเขียนไฟล์ nginx conf ใหม่โดยไม่ประสบความสำเร็จ ฉันชอบคำแนะนำบางอย่างเกี่ยวกับเรื่องนี้


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

1
ans นี้มีโซลูชันล่าสุดไม่ใช่คำตอบที่ยอมรับ
AsifM

คำตอบ:


93

ขณะนี้ AWS Application Load Balancers รองรับการเปลี่ยนเส้นทาง HTTP เป็น HTTPS

ในการเปิดใช้งานสิ่งนี้ในคอนโซลให้ทำดังต่อไปนี้:

  1. ไปที่ตัวจัดสรรภาระงานใน EC2 และแท็บ "Listeners"
  2. เลือก "ดู / แก้ไขกฎ" ในตัวฟัง HTTP ของคุณ
  3. ลบกฎทั้งหมดยกเว้นกฎเริ่มต้น (ด้านล่าง)
  4. แก้ไขกฎเริ่มต้น: เลือก "เปลี่ยนเส้นทางไปที่" เป็นการดำเนินการปล่อยให้ทุกอย่างเป็นค่าเริ่มต้นและป้อน "443" เป็นพอร์ต

กฎตัวฟังการเปลี่ยนเส้นทางดั้งเดิม

เดียวกันสามารถทำได้โดยการใช้ CLI ตามที่อธิบายไว้ที่นี่

นอกจากนี้ยังสามารถทำได้ใน Cloudformation ซึ่งคุณต้องตั้งค่าวัตถุ Listener ดังนี้:

  HttpListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      LoadBalancerArn: !Ref LoadBalancer
      Port: 80
      Protocol: HTTP
      DefaultActions:
      - Type: redirect 
        RedirectConfig:
          Protocol: HTTPS
          StatusCode: HTTP_301
          Port: 443

หากคุณยังคงใช้ Classic Load Balancers อยู่ให้ใช้หนึ่งในการกำหนดค่า NGINX ที่อธิบายโดยคนอื่น ๆ


1
มีประโยชน์มากที่จะรู้ว่ามันง่ายขึ้นแล้ว แต่นี่จะเป็นคำตอบที่ดีกว่าพร้อมข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่ต้องกำหนดค่าแทนที่จะเป็นเพียงลิงก์
John Rees

1
@JohnRees แก้ไขคำตอบตามนั้นหวังว่านี่จะช่วยได้
Ulli

ดี. ฉันเพิ่มคะแนนให้คุณเพื่อให้คุณเป็นศูนย์ คุณสมควรได้รับมากกว่านี้
John Rees

2
@florian ดูเหมือนคุณจะใช้ Classic Load Balancer เปลี่ยนไปใช้ Application Load Balancer เพื่อรับตัวเลือกนั้น
Ulli

ฉันจะกำหนด Application Load Balancer ให้กับอินสแตนซ์ของฉันได้อย่างไร (เนื่องจากไม่มีinstancesแท็บ)
Florian

107

ELB ตั้งค่าX-Forwarded-Protoส่วนหัวคุณสามารถใช้เพื่อตรวจสอบว่าคำขอดั้งเดิมเป็น HTTP และเปลี่ยนเส้นทางไปยัง HTTPS หรือไม่

คุณสามารถลองสิ่งนี้ได้ในserverคอนฟิกของคุณ:

if ($http_x_forwarded_proto = 'http') {
    return 301 https://yourdomain.com$request_uri;
}

ลองดูที่เอกสาร ELB


3
ใครทำโครงแบบนี้
ericpeters0 น.

2
@ ericpeters0n ตัวอย่างข้อมูลในคำตอบมีไว้สำหรับnginxconfig แต่หลักการนี้ใช้ได้กับเว็บเซิร์ฟเวอร์ใด ๆ
Dmitry Mukhin

1
หากคุณใช้ฝักถั่วกับผู้โดยสารแบบสแตนด์อโลนให้ไปที่ลิงค์นี้เพื่อดูวิธีการเปลี่ยนการกำหนดค่า nginx qiita.com/tak_nishida/items/cf30a2d373744943b943
Yeonho

3
ตรวจสอบว่าคุณมีผู้ฟัง HTTP และ HTTPS บนตัวจัดสรรภาระงาน
Gavin Palmer

1
@Ronald โดยเซิร์ฟเวอร์ conf ในการตอบสนองฉันหมายถึงเซิร์ฟเวอร์ nginx บนอินสแตนซ์ ec2 ที่ทำงานหลัง ELB
Dmitry Mukhin

34

ฉันมีปัญหาเดียวกันในสถานการณ์ของฉัน HTTPS ถูกจัดการโดย ELB ทั้งหมดและฉันไม่รู้จักโดเมนต้นทางของฉันล่วงหน้าดังนั้นฉันจึงทำสิ่งต่างๆเช่น:

server {
  listen 81;
  return 301 https://$host$request_uri;
}

server {
  listen 80;
  # regular server rules ...
}

จากนั้นให้ชี้ ELB 'https' ไปที่พอร์ตอินสแตนซ์ 80 จากนั้นกำหนดเส้นทาง 'http' ไปยังพอร์ตอินสแตนซ์ 81


3
นี่คืออัจฉริยะ
Andy Hayden

2
@CodyBugstein นี่คือการกำหนดค่า nginx ถ้าคุณมี
timurso

@timurso ถ้าคุณมีอะไร
CodyBugstein

@CodyBugstein หากคุณมี nginx อยู่หน้าแอปพลิเคชันของคุณ (เช่นฉันไม่ - มันถูกส่งตรงไปยังคอนเทนเนอร์ที่ใช้ ExpressJS)
timurso

nginx จะไปไหน? ภายใน ELB? ภายใน EC2? มีการกำหนดค่านี้ใน Elastic Beanstalk ที่ไหนสักแห่งหรือไม่?
CodyBugstein

16

Amazon Elastic Load Balancer (ELB) รองรับส่วนหัว HTTP ที่เรียกว่า X-FORWARDED-PROTO คำขอ HTTPS ทั้งหมดที่ดำเนินการผ่าน ELB จะมีค่า X-FORWARDED-PROTO เท่ากับ "HTTPS" สำหรับคำขอ HTTP คุณสามารถบังคับ HTTPS ได้โดยเพิ่มกฎการเขียนซ้ำอย่างง่ายต่อไปนี้ สำหรับฉันมันใช้งานได้ดี!

Apache

คุณสามารถเพิ่มบรรทัดต่อไปนี้ในไฟล์. htaccess ของคุณ:

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}

หรือถ้าคุณใช้ vhost.conf เพื่อจัดการหลายโดเมนในเว็บเซิร์ฟเวอร์ EC2 เดียวกันคุณสามารถเพิ่มสิ่งต่อไปนี้ใน vhost.conf (เพิ่มในโดเมนที่คุณต้องการใช้ https):

<VirtualHost *:80>
...
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}
...
</VirtualHost>

IIS

ติดตั้งโมดูล IIS Url-Rewrite โดยใช้การกำหนดค่า GUI เพิ่มการตั้งค่าเหล่านี้:

<rewrite xdt:Transform="Insert">
<rules>
<rule name="HTTPS rewrite behind ELB rule" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions>
<add input="{HTTP_X_FORWARDED_PROTO}" pattern="^http$" ignoreCase="false" />
</conditions>
<action type="Redirect" redirectType="Found" url="https://{SERVER_NAME}{URL}" />
</rule>
</rules>
</rewrite>

อ่านเพิ่มเติมที่นี่


เราประสบปัญหาในการที่อินสแตนซ์ของเราเปลี่ยนเส้นทางการรับส่งข้อมูล http ปกติเนื่องจากไม่มีส่วนหัว ฉันแก้ปัญหาโดยสร้างเงื่อนไข:RewriteCond %{HTTP:X-Forwarded-Proto} !(https|^$)
natronite

สิ่งนี้ทำให้เกิดการเปลี่ยนเส้นทางที่ไม่สิ้นสุด ฉันใช้ IIS กับเซิร์ฟเวอร์ windows
เป็นกับดัก

@ itatrap: สำหรับ IIS หากไม่ได้ผลให้ลองใช้สคริปต์ใน URL นี้: stephen.genoprime.com/2012/01/01/aws-elb-ssl-with-iis.html
Iman Sedighi

5

โซลูชัน htaccess ข้างต้นทำให้การตรวจสุขภาพ ELB ล้มเหลว ฉันมีปัญหาในการหาวิธีแก้ปัญหาจนกระทั่งพบบทความออนไลน์ที่มีคนพบปัญหาเดียวกันกับฉัน วิธีแก้ปัญหาของเขาคือเพิ่มสิ่งนี้ที่จุดเริ่มต้นของไฟล์ htaccess แทน:

RewriteEngine on 
RewriteCond %{HTTP:X-Forwarded-Proto} ^http$
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

หากต้องการอนุญาตสิ่งนี้และคำขอภายในเครื่องอื่น ๆ ผ่าน HTTP ในขณะที่เปลี่ยนเส้นทางคำขอภายนอกผ่าน ELB ไปยัง HTTPS ให้ปรับเงื่อนไขการเขียนซ้ำให้ตรงกับ http แทนที่จะเป็นการจับคู่เชิงลบบน https

ที่มา: การเปลี่ยนเส้นทาง HTTP เป็น HTTPS ด้วย AWS และ ELB


"ปรับเงื่อนไขการเขียนซ้ำให้ตรงกับ http แทนที่จะเป็นการจับคู่เชิงลบบน https" นั่นคือส่วนที่ฉันพยายามแก้ไข ขอบคุณ!
Merricat

4

อาจไม่ใช่โซลูชันที่คุณกำลังมองหา แต่อีกทางเลือกหนึ่งคือการใช้ AWS CloudFront นอกเหนือจาก ELB CloudFront มีตัวเลือกในการเปลี่ยนเส้นทางการรับส่งข้อมูล HTTP ขาเข้าทั้งหมดไปยัง HTTPS



3

ฉันมีปัญหาแปลก ๆ กับการกำหนดค่า nginx และ ELB การตั้งค่าของฉันรวมบริการที่แตกต่างกัน 3 อย่างไว้ใน nginx เดียวที่อยู่เบื้องหลัง ELB และฉันมีปัญหาเกี่ยวกับเนื้อหาที่หลากหลาย: เมื่อคำขอของคุณไปยัง ELB เป็น https แต่ภายใน ELB http เท่านั้นและเซิร์ฟเวอร์สร้างเส้นทางสัมพัทธ์เป็นแบบคงที่โดยใช้ http ดังนั้นเบราว์เซอร์จึงล้มเหลวด้วยปัญหา "เนื้อหาผสม" และฉันต้องสร้างโซลูชันสำหรับทั้ง http / https ทำงานโดยไม่มีการเปลี่ยนเส้นทางใด ๆ

นี่คือ config ที่อยู่ในnginx/conf.d/โฟลเดอร์:

# Required for http/https switching
map $http_x_forwarded_port $switch {
  default   off;
  "80"    off;
  "443"   on;
}

นั่นหมายความว่าเราจะมีความรู้ว่าโปรโตคอลไคลเอนต์ที่แท้จริงคืออะไร อย่างที่คุณเห็นเราจะมีใน$switchvar. และในขณะนี้คุณใช้สิ่งนี้ในทุกสถานที่ที่คุณต้องการ:

location ~ /softwareapi/index.php {
  fastcgi_param HTTPS $switch;
  .. other settings here ..
}

ด้วยแอปพลิเคชัน php การตั้งค่า HTTPS จะตรวจจับโปรโตคอลที่ถูกต้องโดยอัตโนมัติและสร้างเส้นทางสัมพัทธ์อย่างระมัดระวังเพื่อป้องกันปัญหาเนื้อหาผสม

ขอแสดงความนับถืออย่างสูง.


3

จากคำตอบของ @ Ulli หากคุณต้องการกำหนดค่าโดยใช้Terraformนี่คือตัวอย่าง>

resource "aws_alb_listener" "web" {
  load_balancer_arn = "${aws_alb.web.arn}"

  port              = "80"
  protocol          = "HTTP"

  default_action {
    type = "redirect"

    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}

ที่มา


-2

สร้างไฟล์ที่.ebextensions/00_forward_http_to_https.configมีเนื้อหาต่อไปนี้:

files: 
  /tmp/deployment/http_redirect.sh:
    mode: "000755"
    content: |
      APP_URL=`/opt/elasticbeanstalk/bin/get-config environment --output yaml | grep -oP 'APP_URL: \K([^\s)\"](?!ttp:))+'`
      sed -ie 's@$proxy_add_x_forwarded_for;@$proxy_add_x_forwarded_for;\n        if ($http_x_forwarded_proto = 'http') { return 301 https://'"$APP_URL"'$request_uri; }@' /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf

container_commands:
  http_redirect:
    command: "/tmp/deployment/http_redirect.sh"

ตรวจสอบให้แน่ใจว่าได้ตั้งค่าตัวแปรสภาพแวดล้อม APP_URL จากคอนโซลการจัดการ AWS ไว้ล่วงหน้า


ฉันจะทำสิ่งนี้ได้อย่างไรเมื่อสร้างสมดุลการเชื่อมต่อ TCP กับ ELB
บูม

1
ฉันไม่เห็นว่าคำตอบของคุณตรงกับคำถามตรงไหน ... คุณกำลังพูดถึงก้านถั่วแบบยืดหยุ่นและคำถามเกี่ยวกับ nginx ภายใน EC2
jvarandas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.