问题描述
我似乎无法在弹性豆茎的免费使用层上强制使用 https.
I can't seem to force https on the free usage tier of elastic beanstalk.
我在 如何在不通过健康检查的情况下在亚马逊弹性豆茎上强制使用 https
使用这个 Apache 重写规则
Using this Apache rewrite rule
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{REQUEST_URI} !^/status$
RewriteCond %{REQUEST_URI} !^/version$
RewriteCond %{REQUEST_URI} !^/_hostmanager/
RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
当我尝试这样做时,http 请求不会像我希望的那样重定向到 https.相反,http 页面正常加载.我还尝试使用 X-Forwarded-Port 标头获得相同的结果.
When I try that, http requests do not get redirected to https as I would like. Instead, the http page loads normally. I've also tried to use the X-Forwarded-Port header with the same result.
我也尝试了以下重写规则
I've also tried the following rewrite rule
RewriteCond %{SERVER_PORT} 80
RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
并且此规则会导致重定向循环.因此,apache 重写规则似乎没有选择 Elastic Load Balancer 标头 X-Forwarded-Port 和 X-Forwarded-Proto,而且重定向循环也不是我想要的.
And this rule causes a redirect loop. So it would seem that the apache rewrite rules don't pick up the Elastic Load Balancer headers X-Forwarded-Port and X-Forwarded-Proto, but also a redirect loop isn't what I am going for either.
请帮忙.我是 AWS、Elastic Beanstalk 的新手,对 Apache 规则不是很熟悉.我不太确定从这里去哪里.谢谢.
Please help. I am new to AWS, Elastic Beanstalk, and not very familiar with Apache rules. I am not too sure where to go from here. Thanks.
推荐答案
此答案假设您已经在负载均衡器安全组中启用了 https,向负载均衡器添加了 SSL 证书,并且 80 和 443 端口都被转发负载均衡器,并将您的域名指向具有 Route 53(或等效 DNS 服务)的 Elastic Beanstalk 环境.
This answer assumes you have already enabled https in the load balancer security group, added the SSL certificate to the load balancer, have both ports 80 and 443 being forwarded by the load balancer, and pointed your domain name at the Elastic Beanstalk environment with Route 53 (or equivalent DNS service).
这仅在您处于使用 Apache 的 Elastic Beanstalk 环境中时才有可能.它可能不适用于基于 docker 的部署.
This is only possible if you are on an Elastic Beanstalk environment that uses Apache. It may not work for a docker-based deployment.
大多数基于 AWS Linux 版本 2 的平台都可以选择选择 Apache 作为您的代理主机.这可以通过转到配置"来完成.>软件">容器选项"并设置代理服务器"到阿帕奇".
Most AWS Linux version 2 based platforms have the option to pick Apache as your proxy host. This can be done by going to "Configuration" > "Software" >"Container Options" and setting "Proxy Server" to "Apache".
完成后,将名为 .platform/httpd/conf.d/ssl_rewrite.conf
的配置文件添加到您的代码库 (相关 AWS 文档),内容如下:
Having done that, add a configuration file named .platform/httpd/conf.d/ssl_rewrite.conf
to your codebase (relevant AWS docs) with the following contents:
RewriteEngine On
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</If>
亚马逊 Linux 1
您需要做的就是将以下内容添加到您的 .ebextensions 目录中的 code>.config 文件:
Amazon Linux 1
All you need to do is add the following to one of your .config
files in the .ebextensions
directory of your project:
files:
"/etc/httpd/conf.d/ssl_rewrite.conf":
mode: "000644"
owner: root
group: root
content: |
RewriteEngine On
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</If>
说明
这在 Elastic Beanstalk 之外是相当直接的.通常会添加如下的 Apache 重写规则:
Explanation
This is moderately straight forward outside of Elastic Beanstalk. One usually adds an Apache rewrite rule like the following:
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
或者,如果在负载均衡器后面,就像我们在这种情况下一样:
Or, if behind a load balancer, like we are in this case:
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
但是,这些配置仅在 块中起作用.将
RewriteCond
更改为 块允许它在
块之外正常工作,允许我们放入在独立的 Apache 配置文件中.请注意,CentOS 上的标准 Apache 设置(包括 ElasticBeanstalk 上的设置)包括与
/etc/httpd/conf.d/*.conf
匹配的所有文件,这些文件与我们存储此文件的文件路径匹配.
However, these configurations only work within a <VirtualHost>
block. Changing the RewriteCond
to an <If>
block allows it to work properly outside of a <VirtualHost>
block, allowing us to put in in a standalone Apache config file. Note that standard Apache setup on CentOS (including the setup on ElasticBeanstalk) inculdes all files matching /etc/httpd/conf.d/*.conf
, which matches the file path where we are storing this file.
条件的 -n '%{HTTP:X-Forwarded-Proto}'
部分阻止它在您不在负载均衡器后面时重定向,允许您在带有负载均衡器和 https 的生产环境,以及一个单实例且没有 https 的暂存环境.如果您在所有环境中都使用负载平衡器和 https,则这不是必需的,但使用它也无妨.
The -n '%{HTTP:X-Forwarded-Proto}'
part of the condition prevents it from redirecting if you are not behind a load balancer, allowing you to have shared configuration between a production evironment with a load balancer and https, and a staging environment that is single instance and does not have https. This is not necessary if you are using load balancers and https on all of your environments, but it doesn't hurt to have it.
这仅在您使用应用程序负载均衡器时才有可能.亚马逊在此处提供了有关如何执行此操作的说明:https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-httpredirect.html
This is only possible if you are using an Application Load Balancer. Amazon has instructions for how to do that here: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-httpredirect.html
您需要做的就是将以下内容添加到您的 .ebextensions 目录中的 code>.config 文件 用重定向替换 http 侦听器:
All you need to do is add the following to one of your .config
files in the .ebextensions
directory of your project to replace the http listener with a redirect:
Resources:
AWSEBV2LoadBalancerListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn:
Ref: AWSEBV2LoadBalancer
Port: 80
Protocol: HTTP
DefaultActions:
- Type: redirect
RedirectConfig:
Host: "#{host}"
Path: "/#{path}"
Port: "443"
Protocol: "HTTPS"
Query: "#{query}"
StatusCode: "HTTP_301"
我见过的糟糕的解决方案
我见过很多针对这个问题的糟糕的解决方案,值得通过它们来理解为什么需要这个解决方案.
Bad solutions I have seen
I have seen a lot of bad solutions to this problem, and it is worth going through them to understand why this solution is necessary.
使用 Cloudfront: 有些人建议在 Elastic Beanstalk 前使用非缓存的 Cloudfront 设置来执行 HTTP 到 HTTPS 的重定向.这增加了一个并不完全合适的全新服务(从而增加了复杂性)(Cloudfront 是一个 CDN;它不是在固有动态内容上强制使用 HTTPS 的正确工具).Apache config 是解决此问题的常规方法,Elastic Beanstalk 使用 Apache,所以我们应该这样做.
Use Cloudfront: Some people suggest using non-cached Cloudfront setup in front of Elastic Beanstalk to do the HTTP to HTTPS redirect. This adds a whole new service (thus adding complexity) that isn't exactly appropriate (Cloudfront is a CDN; it's not the right tool for forcing HTTPS on inherantly dynamic content). Apache config is the normal solution to this problem and Elastic Beanstalk uses Apache, so that's the way we should go.
通过 SSH 连接到服务器和...: 这与 Elastic Beanstalk 的观点完全相反,并且存在很多问题.通过自动缩放创建的任何新实例都不会具有修改后的配置.任何克隆的环境都没有配置.任何一组合理的环境更改都会清除配置.这真是个坏主意.
SSH into the server and...: This is completely antithetical to the point of Elastic Beanstalk and has so many problems. Any new instances created by autoscaling won't have the modified configuration. Any cloned environments won't have the configuration. Any number of a reasonable set of environment changes will wipe out the configuration. This is just such a bad idea.
用新文件覆盖 Apache 配置:这是进入正确的解决方案领域,但如果 Elastic Beanstalk 更改服务器设置的各个方面(他们很好).另请参阅下一项中的问题.
Overwrite the Apache config with a new file: This is getting into the right realm of solution but leaves you with a maintenance nightmare if Elastic Beanstalk changes aspects of the server setup (which they very well may do). Also see the problems in the next item.
动态编辑 Apache 配置文件以添加几行: 这是一个不错的主意.这样做的问题是,如果 Elastic Beanstalk 更改了其默认 Apache 配置文件的名称,它将无法正常工作,并且该文件可能会在您最不期望的情况下被覆盖:https://forums.aws.amazon.com/thread.jspa?threadID=163369
Dynamically edit the Apache config file to add a few lines: This is a decent idea. The problems with this is that it won't work if Elastic Beanstalk ever changes the name of their default Apache config file, and that this file can get overwritten when you least expect: https://forums.aws.amazon.com/thread.jspa?threadID=163369
这篇关于如何在弹性豆茎上强制使用https?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!