ฉันต้องการที่จะเปลี่ยนเส้นทางทั้งหมดที่ร้องขอ HTTP การร้องขอ https บนELB ฉันมีอินสแตนซ์ EC2 สองรายการ ฉันใช้ nginx สำหรับเซิร์ฟเวอร์ ฉันได้ลองเขียนไฟล์ nginx conf ใหม่โดยไม่ประสบความสำเร็จ ฉันชอบคำแนะนำบางอย่างเกี่ยวกับเรื่องนี้
คำตอบ:
ขณะนี้ AWS Application Load Balancers รองรับการเปลี่ยนเส้นทาง HTTP เป็น HTTPS
ในการเปิดใช้งานสิ่งนี้ในคอนโซลให้ทำดังต่อไปนี้:
เดียวกันสามารถทำได้โดยการใช้ 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 ที่อธิบายโดยคนอื่น ๆ
instances
แท็บ)
ELB ตั้งค่าX-Forwarded-Proto
ส่วนหัวคุณสามารถใช้เพื่อตรวจสอบว่าคำขอดั้งเดิมเป็น HTTP และเปลี่ยนเส้นทางไปยัง HTTPS หรือไม่
คุณสามารถลองสิ่งนี้ได้ในserver
คอนฟิกของคุณ:
if ($http_x_forwarded_proto = 'http') {
return 301 https://yourdomain.com$request_uri;
}
ลองดูที่เอกสาร ELB
nginx
config แต่หลักการนี้ใช้ได้กับเว็บเซิร์ฟเวอร์ใด ๆ
ฉันมีปัญหาเดียวกันในสถานการณ์ของฉัน HTTPS ถูกจัดการโดย ELB ทั้งหมดและฉันไม่รู้จักโดเมนต้นทางของฉันล่วงหน้าดังนั้นฉันจึงทำสิ่งต่างๆเช่น:
server {
listen 81;
return 301 https://$host$request_uri;
}
server {
listen 80;
# regular server rules ...
}
จากนั้นให้ชี้ ELB 'https' ไปที่พอร์ตอินสแตนซ์ 80 จากนั้นกำหนดเส้นทาง 'http' ไปยังพอร์ตอินสแตนซ์ 81
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>
อ่านเพิ่มเติมที่นี่
RewriteCond %{HTTP:X-Forwarded-Proto} !(https|^$)
โซลูชัน 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
อาจไม่ใช่โซลูชันที่คุณกำลังมองหา แต่อีกทางเลือกหนึ่งคือการใช้ AWS CloudFront นอกเหนือจาก ELB CloudFront มีตัวเลือกในการเปลี่ยนเส้นทางการรับส่งข้อมูล HTTP ขาเข้าทั้งหมดไปยัง HTTPS
ฉันมีปัญหาแปลก ๆ กับการกำหนดค่า 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;
}
นั่นหมายความว่าเราจะมีความรู้ว่าโปรโตคอลไคลเอนต์ที่แท้จริงคืออะไร อย่างที่คุณเห็นเราจะมีใน$switch
var. และในขณะนี้คุณใช้สิ่งนี้ในทุกสถานที่ที่คุณต้องการ:
location ~ /softwareapi/index.php {
fastcgi_param HTTPS $switch;
.. other settings here ..
}
ด้วยแอปพลิเคชัน php การตั้งค่า HTTPS จะตรวจจับโปรโตคอลที่ถูกต้องโดยอัตโนมัติและสร้างเส้นทางสัมพัทธ์อย่างระมัดระวังเพื่อป้องกันปัญหาเนื้อหาผสม
ขอแสดงความนับถืออย่างสูง.
จากคำตอบของ @ 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"
}
}
}
สร้างไฟล์ที่.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 ไว้ล่วงหน้า