将 EC2 弹性负载均衡器从 HTTP 重定向到 HTTPS

Posted

技术标签:

【中文标题】将 EC2 弹性负载均衡器从 HTTP 重定向到 HTTPS【英文标题】:Redirecting EC2 Elastic Load Balancer from HTTP to HTTPS 【发布时间】:2014-08-27 12:34:30 【问题描述】:

我想将所有 HTTP 请求重定向到 ELB 上的 https 请求。我有两个 EC2 实例。我正在使用 nginx 作为服务器。我尝试重写 nginx conf 文件但没有成功。我希望得到一些建议。

【问题讨论】:

互联网似乎无法就这个问题的单一、完整和有效的解决方案达成一致。希望你能得到一些帮助here in my post。最后,我不得不费尽心思才想出这个。 This ans 有最新的解决方案,不是公认的分析器 【参考方案1】:

AWS Application Load Balancer 现在支持本机 HTTP 到 HTTPS 重定向。

要在控制台中启用此功能,请执行以下操作:

    转到您在 EC2 中的负载均衡器并选项卡“侦听器” 在您的 HTTP 侦听器上选择“查看/编辑规则” 删除除默认规则外的所有规则(底部) 编辑默认规则:选择“重定向到”作为操作,将所有内容保留为默认值并输入“443”作为端口。

同样可以通过使用here 中描述的 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 Balancer,请使用其他人描述的 NGINX 配置之一。

【讨论】:

现在更容易了解它非常有用。但这将是一个更好的答案,提供更多关于配置内容的信息,而不仅仅是一个链接。 @JohnRees 相应地编辑了答案,希望这会有所帮助 不错。我赞成你让你归零。你应该得到更多。 @florian 您似乎正在使用 Classic Load Balancer。切换到 Application Load Balancer 以获取该选项 如何将 Application Load Balancer 分配给我的实例? (因为没有instances 标签)【参考方案2】:

ELB 设置X-Forwarded-Proto 标头,您可以使用它来检测原始请求是否为HTTP 并重定向到HTTPS。

你可以在你的server conf 中试试这个:

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

看看ELB docs。

【讨论】:

在哪里做这个配置? @ericpeters0n 答案中的 sn-p 是为nginx 配置的,但该原理适用于任何 Web 服务器。 如果您将 beanstalk 与乘客独立使用,请点击此链接了解如何更改 nginx 配置。 qiita.com/tak_nishida/items/cf30a2d373744943b943 确保您的负载均衡器上有 HTTP 和 HTTPS 侦听器。 @Ronald,响应中的服务器配置,我的意思是运行在 ELB 后面的 ec2 实例上的 nginx 服务器。【参考方案3】:

我遇到了同样的问题,在我的情况下,HTTPS 完全由 ELB 处理,我不提前知道我的源域,所以我最终做了类似的事情:

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


server 
  listen 80;
  # regular server rules ...

当然,然后将 ELB 'https' 指向实例端口 80,然后将 'http' 路由指向实例端口 81。

【讨论】:

这是天才。 @CodyBugstein 这是 nginx 配置,如果你有的话 @timurso 如果你有什么? @CodyBugstein 如果您的应用程序前面有 nginx(例如,我没有 - 它直接路由到运行 ExpressJS 的容器) nginx 会去哪里?在 ELB 内部? EC2内部?这是在 Elastic Beanstalk 中的某个地方配置的吗?【参考方案4】:

Amazon Elastic Load Balancer (ELB) 支持名为 X-FORWARDED-PROTO 的 HTTP 标头。通过 ELB 的所有 HTTPS 请求的 X-FORWARDED-PROTO 值将等于“HTTPS”。对于 HTTP 请求,您可以通过添加以下简单的重写规则来强制使用 HTTPS。对我来说效果很好!

阿帕奇

您可以在 .htaccess 文件中添加以下行:

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

或者,如果您使用 vhost.conf 来管理同一 EC2 Web 服务器中的多个域,那么您可以在 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_NAMEURL" />
</rule>
</rules>
</rewrite>

阅读更多here

【讨论】:

我们遇到了让我们的实例重定向正常 http 流量的问题,因为标头甚至不存在。我通过设置条件来解决它:RewriteCond %HTTP:X-Forwarded-Proto !(https|^$) 这会导致无限重定向。我正在使用带有 Windows 服务器的 IIS。 @It'satrap :对于 IIS,如果它不起作用,请尝试以下 URL 中的脚本:stephen.genoprime.com/2012/01/01/aws-elb-ssl-with-iis.html【参考方案5】:

上述 htaccess 解决方案导致 ELB 健康检查失败。我在找到解决方案时遇到了一些麻烦,直到我在网上发现了一篇文章,其中有人遇到了与我相同的问题。他的解决方案是将其添加到 htaccess 文件的开头:

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

在重定向时允许通过 HTTP 进行此和其他本地请求 外部请求通过ELB转HTTPS,调整rewrite 在 http 上匹配的条件,而不是在 https 上的否定匹配。

来源:Redirecting HTTP to HTTPS with AWS and ELB

【讨论】:

“调整重写条件以匹配 http 而不是 https 上的否定匹配”这是我试图修复的部分。谢谢!【参考方案6】:

这可能不是您正在寻找的解决方案,但除了 ELB 之外,另一种选择可能是使用 AWS CloudFront。 CloudFront 提供了将所有传入 HTTP 流量重定向到 HTTPS 的选项。

【讨论】:

见Example: Generating an HTTP Redirect (Generated Response)。【参考方案7】:

基于@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"
    
  

Source

【讨论】:

【参考方案8】:

我在 nginx 和 ELB 配置方面遇到了奇怪的问题。我的设置在 ELB 后面的一个 nginx 中包含 3 个不同的服务。而且我遇到了混合内容问题:当您对 ELB 的请求是 https,但仅在 ELB http 内部,并且服务器使用 http 创建静态的相对路径时,浏览器会因“混合内容”问题而失败。 而且我必须为 http/https 工作创建解决方案,而无需任何重定向。

这是位于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 ..

使用 HTTPS 设置 php 应用程序将自动检测正确的协议并仔细构建相对路径以防止混合内容问题。

最好的问候。

【讨论】:

【参考方案9】:

我刚刚完成了这个过程并使用命令测试了重定向(来自 ec2 实例 shell)

curl -Iv [your url]

例如:curl -Iv http://example.com

要求

    AWS Route 53 中为 DNS 和名称服务器设置托管区域 使用 AWS Certificate Manager 获取证书 在负载均衡器上为端口 443 添加侦听器,从 2. 和 SSL 中选择证书

我所做的是:

    重定向http://yourwebsite.com --> https://www.yourwebsite.com(第2步) 重定向http://www.yourwebsite.com --> https://www.yourwebsite.com(步骤2) 重定向https://yourwebsite.com --> https://www.yourwebsite.com(步骤3)

步骤

1.去负载均衡器

2。进入 Listener ID HTTP : 80(点击规则栏下方的查看/编辑规则)

编辑默认操作:(点击顶部的铅笔图标,使用Switch to full URL

    THEN 块 更改为 Redirect to https://www.#host:443/#path?#query 状态码:HTTP_301

再添加一个动作(点击+在顶部签名)

    选择IF块主机头是yourwebsite.com 将 THEN 块 更改为 Redirect to https://www.#host:443/#path?#query 状态码:HTTP_301

3.返回并进入 Listener ID HTTPS : 443(点击查看/编辑规则)

再添加一个动作(点击+在顶部签名)

    选择IF块主机头是yourwebsite.com 将 THEN 块 更改为 Redirect to https://www.#host:443/#path?#query 状态码:HTTP_301

不要编辑 HTTPS 上的默认操作

【讨论】:

【参考方案10】:

这里有确切的答案: 使用以下名称创建此文件并将以下内容放入其中。

重定向到 https.json

[
  
      "Type": "redirect",
      "RedirectConfig": 
          "Protocol": "HTTPS",
          "Port": "443",
          "Host": "#host",
          "Path": "/#path",
          "Query": "#query",
          "StatusCode": "HTTP_301"
      
  
]

使用此 awscli 命令在端口 80 上使用 HTTP 协议创建侦听器规则,这会将所有流量重定向到 HTTPS 端口。

aws elbv2 create-listener --load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:12345678910:loadbalancer/app/demo1-alb/b4d5fbc78965417f --port 80 --protocol HTTP --default-actions file://redirect-to-https.json

【讨论】:

【参考方案11】:

创建一个文件.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"

确保事先从 AWS 管理控制台设置 APP_URL 环境变量。

【讨论】:

平衡 TCP 连接与 ELB 的时候如何做到这一点? 我看不出你的答案在哪里适合这个问题......你在谈论弹性豆茎,而问题是关于 EC2 中的 nginx。

以上是关于将 EC2 弹性负载均衡器从 HTTP 重定向到 HTTPS的主要内容,如果未能解决你的问题,请参考以下文章

AWS 负载均衡器将 www.example.com 重定向到 example.com 不起作用

如何使用 aws 弹性负载均衡器将 http 请求强制重定向到独立乘客中的 https?

Elastic Beanstalk 和 Spring Boot 将 HTTP 重定向到 HTTPS

使用 tomcat 服务器和 aws 负载均衡器将 http 请求重定向到 https

将 CloudFront 与没有负载均衡器的单个 EC2 实例一起使用

为啥当 cpu 为 100% 时我的负载均衡器不会重定向到可用的 ec2?