该答案假定您已在负载均衡器安全组中启用https,将SSL证书添加到负载均衡器,负载均衡器同时转发了端口80和443,并通过Route 53将您的域名指向了Elastic Beanstalk环境(或等效的DNS服务)。
注意:此答案适用于使用Apache的Elastic Beanstalk环境。它可能不适用于基于docker的部署。
您需要做的就是将以下内容添加到项目目录中的一个.config
文件中.ebextensions
:
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重写规则,如下所示:
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
或者,如果在负载均衡器后面,就像我们在这种情况下那样:
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
但是,这些配置仅在一个<VirtualHost>
块内起作用。将更RewriteCond
改为<If>
块可以使其在块外部正常工作<VirtualHost>
,从而可以将其放入独立的Apache配置文件中。请注意,CentOS上的标准Apache设置(包括ElasticBeanstalk上的设置)包括所有/etc/httpd/conf.d/*.conf
匹配的文件,这些文件与我们存储此文件的文件路径匹配。
-n '%{HTTP:X-Forwarded-Proto}'
如果您不在负载均衡器的后面,部分条件会阻止它重定向,从而使您可以在带有负载均衡器的生产环境和https与单实例且没有https的登台环境之间进行共享配置。如果您在所有环境中都使用负载平衡器和https,则不需要这样做,但是拥有它并没有什么坏处。
我见过的不好的解决方案
我已经看到了很多解决此问题的不好的方法,值得通过他们来理解为什么需要这种方法。
使用Cloudfront: 有人建议在Elastic Beanstalk之前使用非缓存的Cloudfront设置来执行HTTP到HTTPS重定向。这增加了一个不完全合适的全新服务(因此增加了复杂性)(Cloudfront是CDN;它不是强制在固有动态内容上使用HTTPS的正确工具)。Apache config是解决此问题的常规解决方案,Elastic Beanstalk使用Apache,因此我们应该这样做。
SSH进入服务器并...:这完全与Elastic Beanstalk的观点相反,并且存在很多问题。通过自动缩放创建的任何新实例都不会具有修改后的配置。任何克隆的环境都不会配置。任意数量的一组合理的环境更改都将清除配置。这真是个坏主意。
用一个新文件覆盖Apache配置:这进入了正确的解决方案领域,但是如果Elastic Beanstalk更改了服务器设置的方面,这将给您带来维护方面的噩梦(他们很可能做到了)。另请参阅下一项中的问题。
动态编辑Apache配置文件以添加几行:这是一个不错的主意。问题是,如果Elastic Beanstalk曾经更改其默认Apache配置文件的名称,它将无法正常工作,并且在您最不期望的情况下该文件可能会被覆盖:https : //forums.aws.amazon.com/thread .jspa?threadID = 163369