如何在 AWS ALB 上重定向到 https://example.com/ 而不是 https://example.com:443/?

Posted

技术标签:

【中文标题】如何在 AWS ALB 上重定向到 https://example.com/ 而不是 https://example.com:443/?【英文标题】:How to redirect to https://example.com/ instead of https://example.com:443/ on AWS ALB? 【发布时间】:2021-01-01 12:19:36 【问题描述】:

我已将以下重定向规则配置到我的 AWS Application Load Balancer 以将所有 HTTP 流量重定向到 HTTPS:

问题是当我现在curl(或在浏览器中访问域)时,我会得到这个丑陋而多余的Location响应(域更改为example.com):

~ $ curl -I http://www.example.com
HTTP/1.1 301 Moved Permanently
Server: awselb/2.0
Date: Mon, 14 Sep 2020 18:28:48 GMT
Content-Type: text/html
Content-Length: 150
Connection: keep-alive
Location: https://www.example.com:443/

我知道https://www.example.com:443/ 在实践中很好,我知道它不会显示在最终用户的浏览器的 URL 字段中。但是,它仍然会显示在浏览器的网络选项卡的“响应标头”中,在我看来,与没有端口的重定向相比,它看起来不专业,例如:

~ $ curl -I http://www.apple.com
HTTP/1.1 301 Moved Permanently
Server: AkamaiGHost
Content-Length: 0
Location: https://www.apple.com/
Cache-Control: max-age=0
Expires: Mon, 14 Sep 2020 18:33:23 GMT
Date: Mon, 14 Sep 2020 18:33:23 GMT
Connection: keep-alive
strict-transport-security: max-age=31536000
Set-Cookie: geo=FI; path=/; domain=.apple.com
Set-Cookie: ccl=izHQtSPVGso4jrdTGqyAkA==; path=/; domain=.apple.com

从 URL 中删除端口似乎是合乎逻辑的事情,但不幸的是,这是一个必填字段:

“切换到完整 URL”选项似乎也没有真正的帮助,即使可以在那里清除端口:

保存后还是会出现:

有什么办法可以做到吗?

编辑: 我的域是通过 AWS Route 53 管理的。

【问题讨论】:

【参考方案1】:

如果您担心的是,这仍会显示在您的浏览器的 URL 字段中而没有端口。

默认情况下,解释器假定如果协议为 HTTPS,则端口为 443,因此您无需指定任何内容,当重定向发生时,它不会在末尾添加端口号,除非您指定非标准端口,例如作为4430

您必须指定协议(HTTPS)和端口(443),因为配置需要这些项目,这不会显示给用户。这与其他 AWS 配置相同,例如在配置 ELB 期间。

【讨论】:

是的,我知道它在浏览器的 URL 字段中正确显示,但它仍然在 curl 输出中显示“丑陋”格式,例如在 Chrome 开发工具网络选项卡的“响应标头”@987654323 @.【参考方案2】:

您可以将 CloudFront 放在您的服务器前面并让它执行 https 重定向。如果您仅将 ELB 用于 SSL 终止,您可以将其完全删除并让 CloudFront 终止您的 SSL。这将为您节省一些钱,因为如果您仅将 ELB 用于一台源服务器,则它非常昂贵。 https://aws.amazon.com/cloudfront/

【讨论】:

我的 ELB 转发到 4 个不同的目标组,所以我无法删除它。【参考方案3】:

您可以使用 CloudFront 并将源设置为负载均衡器。然后在云端强制 HTTPS 重定向,将 Viewer Protocol Policy 设置为 Redirect HTTP to HTTPS

在这种方法中,仍然会应用所有 ELB 规则。

【讨论】:

【参考方案4】:

更新:也许值得一提的是,这是一个很好的练习和展示能力。但是,在 Lambda 重定向和纯负载均衡器重定向之间,我仍然建议您使用 ALB-native。它具有更高的性能(没有冷启动,没有额外的跃点),更不容易出错(不需要编码),只是为了网络跟踪或开发工具的美观。最终用户永远不会注意到这一点(您可能每天都会浏览很多这些网站,而您甚至都不知道)。所以如果你问我,我建议不要用这样的东西去生产。

如果您想要一些非常简单的重定向,您可以创建一个目标组,指向一个返回重定向的 Lambda 函数。它不需要管理 CloudFront 分配或尝试使其在负载均衡器后面工作的开销,因为这也需要更改您的 DNS,因为您不能只将 CloudFront 放在负载均衡器后面(我不知道,至少)。

对于您的情况,我使用以下代码创建了一个 Lambda 函数 (Python 3.8):

def lambda_handler(event, context):
    response = 
    
    if event.get('headers', ).get('x-forwarded-proto', '') == 'http':
        print(event)
        response["statusCode"]=302
        response["headers"] = "Location": f"https://event['headers']['host']event['path']"
        response["body"]=""
        
    return response

然后,我使用该 Lambda 函数作为后端创建了一个新目标组:

最后,我将端口 80 上的侦听器配置为重定向目标组:

通过此实现,您的 302 重定向将按您的预期显示:

【讨论】:

很好地使用 lambda:-) 我最初的想法是 lambda@edge,但这似乎更容易。 感谢您的回答。尽管顾名思义,Lambda@Edge 是 CloudFront 的一项功能,因此您需要一个分发版。最后,我没有在上面的重定向中包含“查询字符串”,但如果您需要,可以。您必须从docs.aws.amazon.com/lambda/latest/dg/services-alb.html 加入属性queryStringParameters 中的所有对象 我也认为这不值得表面上的收益,最好放弃它并使用本机 ELB 重定向。不过感谢您的概念证明!

以上是关于如何在 AWS ALB 上重定向到 https://example.com/ 而不是 https://example.com:443/?的主要内容,如果未能解决你的问题,请参考以下文章

使用负载均衡器在 AWS Elastic Beanstalk 上重定向所有 www 和 http ==>> 非 www https

如何在 Elastic Beanstalk 配置文件中为 ALB 设置 HTTPS 重定向

如何在 Elastic Beanstalk 配置文件中为 ALB 设置 HTTPS 重定向

apache_conf 在Mamp上重定向到https

如何创建到 ALB 的 Route 53 记录? (AWS)

从 http 重定向到 https 时,cloudfront 域被应用程序负载均衡器 dns 名称替换