Tôi muốn chuyển hướng tất cả yêu cầu HTTP sang yêu cầu https trên ELB . Tôi có hai phiên bản EC2. Tôi đang sử dụng nginx cho máy chủ. Tôi đã thử viết lại các tệp nginx conf mà không thành công. Tôi rất thích một số lời khuyên về nó.
Tôi muốn chuyển hướng tất cả yêu cầu HTTP sang yêu cầu https trên ELB . Tôi có hai phiên bản EC2. Tôi đang sử dụng nginx cho máy chủ. Tôi đã thử viết lại các tệp nginx conf mà không thành công. Tôi rất thích một số lời khuyên về nó.
Câu trả lời:
Bộ cân bằng tải ứng dụng AWS hiện hỗ trợ chuyển hướng HTTP sang HTTPS gốc.
Để bật tính năng này trong bảng điều khiển, hãy làm như sau:
Điều tương tự cũng có thể đạt được bằng cách sử dụng CLI như được mô tả ở đây .
Cũng có thể thực hiện việc này trong Cloudformation, nơi bạn cần thiết lập một đối tượng Listener như sau:
HttpListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn: !Ref LoadBalancer
Port: 80
Protocol: HTTP
DefaultActions:
- Type: redirect
RedirectConfig:
Protocol: HTTPS
StatusCode: HTTP_301
Port: 443
Nếu bạn vẫn sử dụng Bộ cân bằng tải cổ điển, hãy sử dụng một trong các cấu hình NGINX được mô tả bởi các cấu hình khác.
instances
tab)
ELB đặt X-Forwarded-Proto
tiêu đề, bạn có thể sử dụng nó để phát hiện xem yêu cầu ban đầu có phải là HTTP hay không và sau đó chuyển hướng đến HTTPS.
Bạn có thể thử điều này trong tâm sự của mình server
:
if ($http_x_forwarded_proto = 'http') {
return 301 https://yourdomain.com$request_uri;
}
Hãy xem tài liệu ELB .
nginx
cấu hình, nhưng nguyên tắc này có thể áp dụng cho bất kỳ máy chủ web nào.
Tôi đã gặp vấn đề tương tự, trong tình huống của tôi, HTTPS đã được xử lý hoàn toàn bởi ELB và tôi không biết miền nguồn của mình trước thời hạn nên cuối cùng tôi đã làm điều gì đó như:
server {
listen 81;
return 301 https://$host$request_uri;
}
server {
listen 80;
# regular server rules ...
}
Và tất nhiên sau đó trỏ ELB 'https' đến cổng cá thể 80 và sau đó là tuyến 'http' đến cổng cá thể 81.
Amazon Elastic Load Balancer (ELB) hỗ trợ tiêu đề HTTP được gọi là X-FORWARDED-PROTO. Tất cả các yêu cầu HTTPS đi qua ELB sẽ có giá trị X-FORWARDED-PROTO bằng “HTTPS”. Đối với các yêu cầu HTTP, bạn có thể ép buộc HTTPS bằng cách thêm quy tắc ghi lại đơn giản sau. Đối với tôi, nó hoạt động tốt!
Apache
Bạn có thể thêm các dòng sau vào tệp .htaccess của mình:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}
Hoặc nếu bạn sử dụng vhost.conf để quản lý nhiều miền trong cùng một máy chủ web EC2 thì bạn có thể thêm phần sau vào vhost.conf (thêm nó vào miền bạn muốn sử dụng https cho nó):
<VirtualHost *:80>
...
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}
...
</VirtualHost>
IIS
Cài đặt mô-đun IIS Url-Rewrite, sử dụng GUI cấu hình, thêm các cài đặt sau:
<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>
Đọc thêm tại đây
RewriteCond %{HTTP:X-Forwarded-Proto} !(https|^$)
Các giải pháp htaccess ở trên khiến kiểm tra tình trạng ELB không thành công. Tôi đã gặp một số khó khăn khi tìm ra giải pháp cho đến khi tôi phát hiện ra một bài báo trực tuyến trong đó ai đó có cùng vấn đề với tôi. Giải pháp của anh ấy là thêm cái này vào đầu tệp htaccess thay thế:
RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} ^http$
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Để cho phép yêu cầu này và các yêu cầu cục bộ khác qua HTTP trong khi chuyển hướng các yêu cầu bên ngoài qua ELB đến HTTPS, hãy điều chỉnh điều kiện ghi lại để khớp trên http thay vì khớp phủ định trên https.
Nó có thể không phải là giải pháp bạn có thể đang tìm kiếm, nhưng một tùy chọn khác có thể là sử dụng AWS CloudFront ngoài ELB. CloudFront cung cấp tùy chọn chuyển hướng tất cả lưu lượng HTTP đến sang HTTPS.
Tôi gặp sự cố lạ với cấu hình nginx và ELB. Thiết lập của tôi bao gồm 3 dịch vụ khác nhau bên trong một nginx đằng sau ELB. Và tôi đã gặp vấn đề về nội dung hỗn hợp: khi yêu cầu của bạn tới ELB là https, nhưng chỉ bên trong ELB http và máy chủ tạo đường dẫn tương đối đến tĩnh bằng http, vì vậy trình duyệt không thành công với vấn đề 'nội dung hỗn hợp'. Và tôi phải tạo giải pháp cho cả http / https hoạt động mà không có bất kỳ chuyển hướng nào.
Đây là cấu hình nằm trong nginx/conf.d/
thư mục:
# Required for http/https switching
map $http_x_forwarded_port $switch {
default off;
"80" off;
"443" on;
}
Điều này có nghĩa là chúng ta sẽ có kiến thức về giao thức máy khách thực sự là gì. Như bạn có thể thấy, chúng tôi sẽ có nó trong $switch
var. Và tại thời điểm này, bạn sử dụng nó ở mọi vị trí mà bạn cần:
location ~ /softwareapi/index.php {
fastcgi_param HTTPS $switch;
.. other settings here ..
}
Với cài đặt HTTPS, ứng dụng php sẽ tự động phát hiện đúng giao thức và cẩn thận xây dựng đường dẫn tương đối để ngăn chặn vấn đề nội dung hỗn hợp.
Trân trọng.
Dựa trên câu trả lời của @ Ulli Nếu bạn muốn định cấu hình nó bằng Terraform , đây là một ví dụ>
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"
}
}
}
Tạo một tệp .ebextensions/00_forward_http_to_https.config
với nội dung sau:
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"
Đảm bảo đặt trước biến môi trường APP_URL từ bảng điều khiển quản lý AWS.