如何在弹性beanstalk上强制https?
我似乎无法强制https在弹性beanstalk的免费使用层。
我已经尝试了如何强制https在亚马逊弹性beanstalk没有失败健康检查以下build议
使用这个Apache重写规则
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请求不会被redirect到https,因为我想。 相反,http页面正常加载。 我也试着用相同的结果使用X-Forwarded-Port头。
我也尝试了以下重写规则
RewriteCond %{SERVER_PORT} 80 RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [L,R]
而这个规则会导致redirect循环。 所以看起来,Apache重写规则不拾起Elastic Load Balancer头X-Forwarded-Port和X-Forwarded-Proto,但redirect循环也不是我所要做的。
请帮忙。 我是AWS的新手,Elastic Beanstalk,并不熟悉Apache规则。 我不太确定该从哪里出发。 谢谢。
此答案假定您已在负载平衡器安全组中启用https,将SSL证书添加到负载平衡器,将443添加到由负载平衡器转发的端口,并在Elastic Beanstalk环境中将您的域名用Route 53(或等效的DNS服务)。
注意:此答案适用于使用Apache的Elastic Beanstalk环境。 它也可能不适用于基于docker的部署。
您只需将以下内容添加到项目的.ebextensions
目录中的一个.config
文件中 :
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]
但是,这些configuration只能在<VirtualHost>
块中使用。 将RewriteCond
更改为<If>
块可以使其在<VirtualHost>
块之外正常工作,从而允许我们将其放入独立的Apacheconfiguration文件中。 请注意,CentOS上的标准Apache设置(包括ElasticBeanstalk上的设置)包含了所有匹配/etc/httpd/conf.d/*.conf
的文件,该文件与我们存储此文件的文件path相匹配。
如果您不在负载平衡器的后面,则条件中的-n '%{HTTP:X-Forwarded-Proto}'
部分将阻止其redirect,从而允许您在具有负载平衡器和https的生产环境之间共享configuration,以及一个单一实例,没有https的登台环境。 如果您在所有环境中使用负载均衡器和https,则这不是必需的,但是这并不会造成影响。
我看到了不好的解决scheme
我已经看到了这个问题的很多不好的解决scheme,值得通过他们来理解为什么这个解决scheme是必要的。
-
使用Cloudfront:有人build议在Elastic Beanstalk之前使用非caching的Cloudfront设置来执行HTTP到HTTPS的redirect。 这增加了一个全新的服务(因此增加了复杂性),这是不恰当的(Cloudfront是一个CDN;它不是在dynamic内容上强制HTTPS的正确工具)。 Apacheconfiguration是这个问题的正常解决scheme,Elastic Beanstalk使用Apache,所以这是我们应该去的方式。
-
SSH到服务器和…:这是Elastic Beanstalk点完全相反,有这么多的问题。 任何通过自动缩放创build的新实例都不会有修改后的configuration。 任何克隆的环境都不会有configuration。 任何数量的一组合理的环境变化都将消除configuration。 这是一个坏主意。
-
用新文件覆盖Apacheconfiguration:这正在进入正确的解决scheme领域,但如果Elastic Beanstalk更改服务器设置的某些方面(他们可能会这样做),则会给您带来维护的噩梦。 另请参阅下一项中的问题。
-
dynamic编辑Apacheconfiguration文件添加几行:这是一个体面的想法。 这个问题是,如果Elastic Beanstalk改变了默认的Apacheconfiguration文件的名称,那么这个文件就不能工作,而且当你最不期待的时候这个文件会被覆盖: https : //forums.aws.amazon.com/thread .jspa?线程ID = 163369
编辑:虽然我喜欢这个答案,现在是非常古老的 。 AWS已经提出了新的服务(如证书pipe理器 ),使得这个答案的一部分已经过时。 另外,
.ebextensions
,在Apache中使用.ebextensions
文件夹是处理此redirect的一种更.ebextensions
方式。
如果您在S3上托pipe您的网站,这个答案的部分内容可能对您仍然有用。
这对我工作:
-
使用
aws
console命令将证书上传到AWS。 命令结构是:aws iam upload-server-certificate --server-certificate-name CERTIFICATE_NAME --certificate-body "file://PATH_TO_CERTIFICATE.crt" --private-key "file://YOUR_PRIVATE_KEY.pem" --certificate-chain "file://YOUR_CERTIFICATE_CHAIN.ca-bundle" --path /cloudfront/
-
在您的Elastic Beanstalk应用程序中,转至configuration – > networking层 – > 负载平衡 ,然后单击齿轮图标 。
-
select安全侦听器端口为443 。 selectProtocol作为HTTPS 。 从步骤2中select
CERTIFICATE_NAME
以获取SSL证书ID 。 保存configuration。 -
转到您的控制台 。 点击EC2实例 。 点击负载平衡器 。 点击负载平衡器。 单击实例,然后向下滚动以查看分配给该负载均衡器的EC2实例。 如果EC2实例的名称与您的应用程序URL(或closures的)相同,请记下负载均衡器的DNS名称 。 它应该是格式
awseb-e-...
-
回到你的控制台 。 点击CloudFront 。 点击创build分配 。 select一个Web分配。
-
设置分配。 将您的源域名设置为您在步骤5中find的负载均衡器DNS名称。 将查看器协议策略设置为将HTTPredirect到HTTPS 。 将转发查询string设置为是 。 将备用域名(CNAME)设置为要用于应用程序的URL。 将SSL证书设置为您在步骤2中上传的
CERTIFICATE_NAME
。 创build你的发行版。 -
在CloudFront中点击您的分配名称。 点击来源,select您的来源,然后点击编辑 。 确保您的Origin协议策略是匹配查看器 。 回去。 点击行为 ,select您的来源,然后点击编辑 。 将转发标题更改为白名单并添加主机 。 保存。
注意: 我也写了一个更长的指南 。
这对下一个命令是适合我的:
RewriteCond %{HTTP:X-Forwarded-Port} !=443
没有https检查:
RewriteCond %{HTTP:X-Forwarded-Proto} !https
看起来ELB将X-Forwarded-Proto的值更改为http(即使在TCP协议上)。
编辑: Zags的解决scheme是更一般和正确的。 我推荐它在我的(这是特定于Python的环境)
我提出了一个干净而快速的解决scheme,可以避免黑客攻击wsgi.conf或使用CloudFront
在你的.ebextensions / some_file.config中:
# Redirect HTTP to HTTPS "/etc/httpd/conf.d/https_redirect.conf": mode: "000644" owner: root group: root content: | <Directory /opt/python/current/app/> RewriteEngine on RewriteCond %{HTTP:X-Forwarded-Proto} ^http$ RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] </Directory>
我觉得这很容易,但似乎工作正常。
另外请注意,我明确redirectHTTP而不是“不HTTPS”。
最有价值的不适用于我.. <If>指令只适用于Apache 2.4 +,但ElasticBeanstalk具有2.2.x版本。
所以,遵循上面的同样的build议。 使用以下内容创build一个名为.ebextensions / https_rewrite.config的文件
files: "/etc/httpd/conf.d/ssl_rewrite.conf": mode: "000644" owner: root group: root content: | LoadModule rewrite_module modules/mod_rewrite.so RewriteEngine On # This will enable the Rewrite capabilities RewriteCond %{HTTPS} !=on # This checks to make sure the connection is not already HTTPS RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
这似乎为我工作。
有关如何将此文件构build到WAR文件中,请参阅此答案
我有以下弹性beanstalk(运行Tomcat 8 Java 8的64位Amazon Linux 2016.09 v2.3.1)的configuration。 我创build了一个目录.ebextensions并添加了一个带有重写条件的.config YAML文件
上面描述的Zagas 解决scheme (这非常复杂)不适用于我。
- 因为“如果”条件是未知的
- 由于Apache 2.2,我没有在我的httpd.conf文件中包含mod_rewrite.so
这个解决scheme对我来说更有意义,但这也行不通。 什么也没有发生,我看不到“conf.d”目录下的“ssl_rewrite.conf”文件。
第三个尝试的解决scheme是在“.ebextendsion”目录下添加“run.config”和“ssl_rewrite.conf”文件。
run_config包含
container_commands: copy-config: command: "cp .ebextensions/ssl_rewrite.conf /etc/httpd/conf.d"
包含ssl_rewrite.conf
LoadModule rewrite_module modules/mod_rewrite.so RewriteEngine On RewriteCond %{HTTP:X-Forwarded-Proto} =http RewriteRule . https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
ssl_rewrite.conf在“conf.d”目录下创build,但是从httpredirect到https不起作用。
唯一有效的解决scheme是在“/etc/httpd/conf.d/elasticbeanstalk/00_application.conf”中添加以下行
<VirtualHost *:80> ...... RewriteEngine on RewriteCond %{HTTP:X-Forwarded-Proto} =http RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] ...... </VirtualHost>
但这是一个临时的解决scheme,如果一台机器被取代,我的httpsredirect已经消失。
上述答案都没有为我工作,但一些帮助我找出对我有效的答案我还发现了下面的url帮助http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/java-tomcat -platform.html
我创build了上述url中提到的文件结构来更改2个文件httpd.conf 00_application.conf
从您的实例中复制整个httpd.conf,并将其放在上面链接提到的文件夹结构下的.ebextention下的代码中。 然后,只需将下面一行添加到项目中的该文件即可
LoadModule rewrite_module modules/mod_rewrite.so
对00_application.conf做同样的事情,把它从你的实例拷贝到你的代码库中,放在httpd / conf.d / elasticbeanstalk / 00_application.conf下的.ebextention下。现在编辑这个文件,在VirtualHost
RewriteEngine on RewriteCond %{HTTP:X-Forwarded-Proto} =http RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
现在部署你的代码它应该工作。
在弹性beanstalk上,您可以直接添加configuration,以便AWS覆盖它,这将允许您覆盖Web服务器configuration并提交您自己的configuration。
只需在path下添加以下文件:.ebextensions \ httpd \ conf.d
文件内容:
<VirtualHost *:80> LoadModule rewrite_module modules/mod_rewrite.so RewriteEngine On RewriteCond %{HTTP:X-Forwarded-Proto} !https RewriteCond %{HTTP_USER_AGENT} !ELB-HealthChecker RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} <Proxy *> Order deny,allow Allow from all </Proxy> ProxyPass / http://localhost:8080/ retry=0 ProxyPassReverse / http://localhost:8080/ ProxyPreserveHost on ErrorLog /var/log/httpd/elasticbeanstalk-error_log </VirtualHost>
'.ebextensions'是AWS中的标准configuration文件夹,剩下的就是指向你想要覆盖的文件和文件夹。 如果文件或文件夹不存在,简单地创build它们。
我很困惑,所以在提出解决scheme之后,我详细解释了我的解决scheme ,希望可以帮助别人。 这是特定于Tomcat 8,Apache2和Spring Boot应用程序。 AWS labs github中有非常有用的ebextension示例 。
什么为我工作的总结:
- 在/src/main/webapp/.ebextensions/httpd/conf.d/elasticbeanstalk.conf创build一个文件
- 添加重写conds /规则要小心包括“LoadModule rewrite_module modules / mod_rewrite.so”
- 部署到AWS EBS
这是一个Spring Boot应用程序的例子 。
为什么不简单地把一个.htaccess文件放在根文件夹中? 这样你可以简单地testing和debugging它。 如果将其包含在.zip中,它将自动再次部署到所有实例上。
只需使用.htaccess
:
RewriteEngine on RewriteCond %{HTTP:X-Forwarded-Proto} !https RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
请注意,现在投票最多的答案已经有点老了。 保罗的答案实际上是正确的答案。 他的答案中提供的链接是由AWS提供的(因此,在Elastic Beanstalk上运行应用程序时,推荐的方法是覆盖Apacheconfiguration,以便从HTTPredirect到HTTPS)。
有一件非常重要的事情需要注意。 如果您正在部署多个Web应用程序,则在您的一个Web应用程序内添加.ebextensions文件夹将不起作用。 您将会注意到您指定的configuration的Non被写入或创build。 如果要在Elastic Beanstalk环境中部署多个Web应用程序,则需要阅读AWS Java Tomcat的这篇文章。 在Elastic Beanstalk上部署多个WAR文件
通常,在发出eb命令来部署WAR文件之前,需要具有以下结构:
MyApplication.zip ├── .ebextensions ├── foo.war ├── bar.war └── ROOT.war
如果.ebextentions文件夹存在于每个WAR文件中,那么您会注意到它完全被忽略,不会执行任何configuration更改。
希望这可以帮助别人。
如果您使用Load Balanced环境,则可以按照AWS Elastic Beanstalk环境的HTTPSconfiguration说明进行操作 ,最后禁用HTTP端口。
请注意,目前AWS免费使用套件包含与EC2微型实例相同的Elastic Load Balancing(ELB)小时数。
这是一个简单的解决scheme
- ssh进入你的EC2实例
- 将/etc/httpd/conf.d/wsgi.conf的内容复制到一个名为wsgi.conf的本地文件中,该文件将被放置在应用程序的基本文件夹中
-
编辑wsgi.conf的本地版本,并在<VirtualHost> </ VirtualHost>标签中添加以下redirect规则
RewriteEngine On RewriteCond %{HTTP:X-Forwarded-Proto} !https RewriteRule !/status https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]
-
将“/ status”更改为您用作健康检查页面的任何页面。
- 保存文件
-
编辑你的<app> .conf文件。 ebextensions目录添加一个容器命令,将这个版本的wsgi.conf复制到Amazon的版本上
container_commands: 01_syncdb: command: "django-admin.py syncdb --noinput" leader_only: true 02_collectstatic: command: "django-admin.py collectstatic --noinput" 03_wsgireplace: command: 'cp wsgi.conf ../wsgi.conf' ...
-
部署代码。
- /etc/httd/conf.d/wsgi.conf中部署的wsg.conf版本现在将包含必要的redirect规则。
它应该工作,文件将被正确地更新为每个部署。 唯一值得注意的是,如果亚马逊在未来改变其基础wsgi.conf文件内容,那么你的副本可能不再工作。
作者rickchristianson