如何在亚马逊弹性豆茎上强制 https 而不会失败健康检查 [重复]
Posted
技术标签:
【中文标题】如何在亚马逊弹性豆茎上强制 https 而不会失败健康检查 [重复]【英文标题】:How to force https on amazon elastic beanstalk without failing the health check [duplicate] 【发布时间】:2011-10-15 01:38:37 【问题描述】:我已将我的 Elastic Beanstalk 环境配置为将所有页面重定向到 https,重定向工作,但是,实例未通过运行状况检查并被终止,任何想法如何配置重写规则?
我的配置:
NameVirtualHost *:80
<VirtualHost *:80>
.
.
.
RewriteEngine On
RewriteCond %HTTP:X-Forwarded-Proto !https
RewriteRule !/_hostmanager/healthcheck https://%SERVER_NAME%REQUEST_URI [L,R]
</VirtualHost>
【问题讨论】:
互联网似乎无法就这个问题的单一、完整和有效的解决方案达成一致。希望你能得到一些帮助here in my post。最后,我不得不费尽心思才想出这个。 【参考方案1】:除了运行状况检查之外,Elastic Beanstalk 还需要访问多个 hostmananger URL。 Grepping /var/log/httpd/elasticbeanstalk-access_log
,我看到对 /_hostmanager/tasks
和 /_hostmanager/healthcheck
的请求。
以下是我在我的 EC2 实例上添加到 /etc/httpd/sites/elasticbeanstalk
的规则:
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]
请注意,我还允许非 https 流量访问我的 /status
和 /version
页面。我实际上使用/status
作为实际的健康检查查找 URL,因此让该流量跳过重写将避免重定向并使状态查找更快(我假设)。
【讨论】:
这仍然会导致我的运行状况检查失败。【参考方案2】:我认为这里的其他一些答案可能不是基于任意User-Agent
AWS 当前设置的。当我查看 Apache 日志时,我看到了这个用户代理:
ELB-HealthChecker/1.0
在撰写本文时,以下mod_rewrite
规则对我有效:
RewriteEngine On
RewriteCond %HTTP:X-Forwarded-Proto !https
RewriteCond %HTTP_USER_AGENT !^ELB-HealthChecker.*
RewriteRule . https://%SERVER_NAME%REQUEST_URI [L,R]
【讨论】:
【参考方案3】:截至 2016 年,这些答案都不适合我,但这有效:
1 检索/etc/httpd/conf.d/wsgi.conf
2 将以下内容添加到虚拟主机:(请注意,第三行可防止设置脚本 /opt/elasticbeanstalk/hooks/config.py
等待 5 分钟无法加载路径 /
的问题。)
RewriteEngine On
RewriteCond %HTTP:X-Forwarded-Proto !https
RewriteCond %HTTP_HOST !localhost
RewriteCond %HTTP_USER_AGENT !^ELB-HealthChecker.*
RewriteRule . https://%SERVER_NAME%REQUEST_URI [L,R=301]
3 将文件放入您的存储库,并添加以下容器命令:
06_https:
command: "cp wsgi.conf /opt/python/ondeck/wsgi.conf"
安装脚本会自动将该文件复制到/etc/httpd/conf.d
。
【讨论】:
【参考方案4】:AWS Health Checker 似乎使用了用户代理“AWSHealthCheck”。
如果请求来自健康检查器用户代理,我通过避免重定向来解决这个问题。
类似的东西:
RewriteEngine On
RewriteCond %HTTP:X-Forwarded-Proto !https
RewriteCond %USER_AGENT !^AWSHealthCheck$
RewriteRule . https://%SERVER_NAME%REQUEST_URI [L,R]
【讨论】:
这很接近,但似乎并不适合我。健康检查仍然失败。%USER_AGENT
似乎不是有效的 mod_rewrite
变量。根据httpd.apache.org/docs/2.2/mod/mod_rewrite.html 的文档,正确的变量是HTTP_USER_AGENT
【参考方案5】:
您可以将 ELB 配置为使用特定路径进行健康检查,例如 /ping。然后,您可以明确告诉 apache 不要重定向该 URL,而不是依赖 UserAgent 字符串。
您还可以告诉 ELB 使用 HTTPS 进行健康检查,然后将所有 HTTP URL 重定向到 HTTPS,包括健康检查。
这两项设置都可以在 EC2 控制台的负载均衡器部分进行更改。
【讨论】:
【参考方案6】:如果您尝试在 Wordpress 或 php 中执行此操作,您可以按如下方式设置您的 .htaccess
,而无需通过 .ebextensions 进行任何修改:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %HTTP:X-Forwarded-Proto !https
RewriteCond %REQUEST_URI !^/status\.html$
RewriteCond %REQUEST_URI !^/_hostmanager/
RewriteRule ^.*$ https://%SERVER_NAME%REQUEST_URI [R=301,L]
</IfModule>
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %REQUEST_FILENAME !-f
RewriteCond %REQUEST_FILENAME !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
记得将 status.html 更改为您用于执行 Elastic Beanstalk 运行状况检查的任何路径
欲了解更多信息,请参阅我的回复here。
【讨论】:
这非常适合我的 Wordpress/Woocommerce Docker 部署。【参考方案7】:此答案假设您已经在负载均衡器安全组中启用了 https,将 SSL 证书添加到负载均衡器,将 443 添加到负载均衡器转发的端口,并使用 Route 将您的域名指向 Elastic Beanstalk 环境53(或等效的 DNS 服务)。
您只需将以下内容添加到您的.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 重写规则,如下所示:
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
【讨论】:
【参考方案8】:创建一个静态 health.html。如果可能,作为配置模板。
【讨论】:
【参考方案9】:这是一个简单的解决方案
-
SSH 到您的 EC2 实例
将 /etc/httpd/conf.d/wsgi.conf 的内容复制到名为 wsgi.conf 的本地文件中,该文件将放置在应用程序的基本文件夹中
编辑 wsgi.conf 的本地版本并在
RewriteEngine On
RewriteCond %HTTP:X-Forwarded-Proto !https
RewriteRule !/status https://%SERVER_NAME%REQUEST_URI [L,R=301]
将“/status”更改为您用作健康检查页面的任何页面。
保存文件在您的 .ebextensions 目录中编辑您的 .conf 文件,以添加一个容器命令,将这个版本的 wsgi.conf 复制到亚马逊的版本
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 版本现在将包含必要的重定向规则。它应该可以工作,并且每次部署都会正确更新文件。唯一需要注意的是,如果 Amazon 将来更改其基本 wsgi.conf 文件内容,那么您的副本可能不再有效。
作者rickchristianson
【讨论】:
【参考方案10】:对我来说,将wsgi.conf
复制到适当的位置从未奏效。 EB 将无法部署,或者文件将被覆盖。
我发现唯一有效的答案是here。本质上,他使用sed
将必要的重写规则插入到wsgi.conf
中。他说要添加的容器命令是
container_commands:
01_http_to_https_redirect:
command:
sed -i '/\<VirtualHost \*:80\>/a RewriteEngine On\nRewriteCond %HTTP:X-Forwarded-Proto !https\nRewriteRule \!/robots.txt https://%SERVER_NAME%REQUEST_URI [L,R=301]' /opt/python/ondeck/wsgi.conf
不要忘记将您的健康检查端点从 robots.txt
更改。
【讨论】:
【参考方案11】:作为一个通用策略,对于我们来说,Apache 和 nginx EC2 实例都位于 AWS 安全负载均衡器后面:
-
在负载均衡器上,将端口 80 转发到实例上的端口 80
在实例上将端口 443 转发到端口 8080(例如)
在 Web 服务器中,监听两个端口(80 和 8080)
将端口 80 重定向到端口 443
将环境变量“HTTPS”,值为“on”添加到 EC2,例如使用 Elastic Beanstalk 软件配置
第 1 步确保 AWS 内部流量得到“自然”处理。
第 2 步只允许安全的外部流量到达我们的代码
第 5 步告诉 Web 服务器和它背后的东西(在我们的例子中是 Laravel)生成的 URL 应该被赋予 https: 方案。其他框架可能需要设置其他一些环境变量才能触发该行为。
【讨论】:
以上是关于如何在亚马逊弹性豆茎上强制 https 而不会失败健康检查 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何在亚马逊弹性豆茎上强制 https 而不会失败健康检查 [重复]
如何在亚马逊弹性豆茎上强制 https 而不会失败健康检查 [重复]