Chuyển hướng Bộ cân bằng tải đàn hồi EC2 từ HTTP sang HTTPS


104

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ó.


1
Có vẻ như Internet không thể thống nhất về một giải pháp duy nhất, đầy đủ và hiệu quả cho vấn đề này. Hy vọng rằng bạn có thể nhận được một số trợ giúp ở đây trong bài đăng của tôi . Cuối cùng, tôi đã phải nhảy qua nhiều vòng để nghĩ ra điều này.
ADTC

1
Ans này có giải pháp mới nhất, không phải anser được chấp nhận
AsifM 22/02 '19

Câu trả lời:


87

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:

  1. Đi tới Bộ cân bằng tải của bạn trong EC2 và tab "Người nghe"
  2. Chọn "Xem / chỉnh sửa quy tắc" trên trình nghe HTTP của bạn
  3. Xóa tất cả các quy tắc ngoại trừ quy tắc mặc định (dưới cùng)
  4. Chỉnh sửa quy tắc mặc định: chọn "Chuyển hướng đến" làm hành động, để mọi thứ làm mặc định và nhập "443" làm cổng.

Quy tắc trình nghe chuyển hướng gốc

Đ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.


1
Rất hữu ích để biết nó dễ dàng hơn bây giờ. Nhưng đây sẽ là một câu trả lời tốt hơn với nhiều thông tin hơn về những gì cần cấu hình thay vì chỉ một liên kết.
John Rees

1
@JohnRees đã chỉnh sửa câu trả lời cho phù hợp, hy vọng điều này sẽ giúp ích
Ulli

Đẹp. Tôi ủng hộ bạn để đưa bạn về số 0. Bạn xứng đáng hơn.
John Rees

2
@florian có vẻ như bạn đang sử dụng Cân bằng tải cổ điển. Chuyển sang Bộ cân bằng tải ứng dụng để có tùy chọn đó
Ulli

làm cách nào để gán Bộ cân bằng tải ứng dụng cho phiên bản của tôi? (vì không có instancestab)
Florian

107

ELB đặt X-Forwarded-Prototiê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 .


3
Người ta thực hiện cấu hình này ở đâu?
ericpeters0n

2
@ ericpeters0n đoạn mã trong câu trả lời dành cho nginxcấ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.
Dmitry Mukhin

1
nếu bạn đang sử dụng cây đậu với hành khách độc lập, hãy nhấp vào liên kết này để biết cách thực hiện thay đổi cấu hình nginx. qiita.com/tak_nishida/items/cf30a2d373744943b943
Yeonho

3
Đảm bảo bạn có trình nghe HTTP và HTTPS trên bộ cân bằng tải của mình.
Gavin Palmer

1
@Ronald, bởi máy chủ conf trong phản hồi, tôi có nghĩa là máy chủ nginx trên các trường hợp ec2 đang chạy sau ELB.
Dmitry Mukhin

34

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.


3
Đây là thiên tài.
Andy Hayden

2
@CodyBugstein đây là cấu hình nginx, nếu bạn có
timurso

@timurso nếu bạn có cái gì?
CodyBugstein

@CodyBugstein nếu bạn có nginx ở phía trước ứng dụng của mình (ví dụ: tôi thì không - nó được định tuyến trực tiếp đến vùng chứa chạy ExpressJS)
timurso

Nginx sẽ đi đâu? Bên trong ELB? Bên trong EC2? Điều này có được định cấu hình trong Elastic Beanstalk ở đâu đó không?
CodyBugstein

16

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


Chúng tôi đã gặp sự cố khi phiên bản của chúng tôi chuyển hướng lưu lượng truy cập http bình thường vì tiêu đề thậm chí không có. Tôi giải quyết nó bằng cách làm cho tình trạng này:RewriteCond %{HTTP:X-Forwarded-Proto} !(https|^$)
natronite

Điều này gây ra chuyển hướng vô hạn. Tôi đang sử dụng IIS với máy chủ windows.
Đó là một cái bẫy

@ Itatrap: Đối với IIS nếu nó không hoạt động thì hãy thử tập lệnh trong URL này: stephen.genoprime.com/2012/01/01/aws-elb-ssl-with-iis.html
Iman Sedighi

5

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.

Nguồn: Chuyển hướng HTTP sang HTTPS với AWS và ELB


"điều chỉnh điều kiện viết lại để khớp trên http thay vì khớp phủ định trên https" đó là phần tôi đang cố gắng sửa chữa. Cảm ơn bạn!
Merricat


3

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 $switchvar. 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.


3

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

Nguồn


-2

Tạo một tệp .ebextensions/00_forward_http_to_https.configvớ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.


Làm cách nào để thực hiện việc này khi cân bằng kết nối TCP với ELB?
boom

1
Tôi không thấy câu trả lời của bạn phù hợp với câu hỏi ở đâu ... bạn đang nói về thân cây đậu đàn hồi và câu hỏi là về nginx bên trong EC2.
jvarandas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.