如何强制https亚马逊弹性豆茎,而不会失败的健康检查

时间:2011-07-28 11:53:09

标签: apache amazon-web-services mod-rewrite https amazon-elastic-beanstalk

我已经配置了我的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>

11 个答案:

答案 0 :(得分:13)

除了运行状况检查之外,Elastic Beanstalk还需要访问多个hostmananger URL。通过/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,因此让该流量跳过重写将避免重定向并使状态查找更快(我假设)。

答案 1 :(得分:9)

我认为此处的其他一些答案可能不是基于AWS当前设置的任意User-Agent。当我观看Apache日志时,我看到了这个User-Agent:

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]

答案 2 :(得分:6)

截至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

答案 3 :(得分:3)

看起来AWS Health Checker使用用户代理“AWSHealthCheck”。

如果请求来自Health Checker用户代理,我可以避免重定向。

类似的东西:

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{USER_AGENT} !^AWSHealthCheck$ 
RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

答案 4 :(得分:1)

您可以将ELB配置为使用特定路径进行运行状况检查,例如/ ping。然后,您可以明确告诉apache不要重定向该URL,而不是依赖于UserAgent字符串。

您还可以告诉ELB使用HTTPS进行运行状况检查,然后将所有HTTP URL重定向到HTTPS,包括运行状况检查。

可以在“负载均衡器”部分的EC2控制台中更改这些设置。

答案 5 :(得分:1)

如果您尝试在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

答案 6 :(得分:1)

此答案假设您已在负载均衡器安全组中启用了https,将SSL证书添加到负载均衡器,将443添加到负载均衡器转发的端口,并使用路由将您的域名指向Elastic Beanstalk环境53(或等效的DNS服务)。

您需要做的就是将以下内容添加到.conf 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,则无需这样做,但拥有它并不会有什么坏处。

我见过不好的解决方案

我已经看到了很多解决这个问题的坏方法,值得深入了解为什么这个解决方案是必要的。

  1. 使用Cloudfront:有些人建议在Elastic Beanstalk前面使用非缓存Cloudfront设置来执行HTTP到HTTPS重定向。这增加了一项并非完全合适的全新服务(因此增加了复杂性)(Cloudfront是一个CDN;它不是在非常动态内容上强制HTTPS的正确工具)。 Apache配置是解决此问题的正常方法,Elastic Beanstalk使用Apache,这是我们应该采用的方式。

  2. SSH进入服务器并......:这与Elastic Beanstalk完全相反,并且存在很多问题。通过自动缩放创建的任何新实例都没有修改后的配置。任何克隆的环境都没有配置。任何数量的合理环境更改都将消除配置。这真是个坏主意。

  3. 使用新文件覆盖Apache配置:如果Elastic Beanstalk更改了服务器设置的各个方面(即他们),这会进入正确的解决方案领域,但会让您遇到维护噩梦很好可能)。另请参阅下一项中的问题。

  4. 动态编辑Apache配置文件以添加几行:这是一个不错的主意。这样做的问题在于,如果Elastic Beanstalk更改了默认Apache配置文件的名称,它将无法正常工作,并且当您最不期望时,此文件可能会被覆盖:https://forums.aws.amazon.com/thread.jspa?threadID=163369

答案 7 :(得分:0)

创建一个静态health.html。如果可能,作为配置模板。

答案 8 :(得分:0)

这是一个简单的解决方案

  1. ssh进入您的EC2实例
  2. 将/etc/httpd/conf.d/wsgi.conf的内容复制到名为wsgi.conf的本地文件中,该文件将放在应用程序的基本文件夹中
  3. 编辑wsgi.conf的本地版本,并在&lt;中添加以下重定向规则。虚拟主机&GT; &LT; /虚拟主机&GT;标签

    RewriteEngine On
    RewriteCond %{HTTP:X-Forwarded-Proto} !https
    RewriteRule !/status https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]
    
  4. “/ status”更改为您用作运行状况检查页面的任何页面。

  5. 保存文件
  6. 编辑你的&lt;你的。 ebextensions 目录中的app&gt; .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'
    ...
    
  7. 部署代码。

  8. /etc/httd/conf.d/wsgi.conf中部署的wsg.conf版本现在将包含必要的重定向规则。
  9. 它应该可以正常工作,并且每个部署都会正确更新文件。唯一需要注意的是,如果Amazon将来更改其基本wsgi.conf文件内容,那么您的副本可能不再有效。

    Autor rickchristianson

答案 9 :(得分:0)

对我来说,将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更改您的健康检查终点。

答案 10 :(得分:0)

作为一种通用策略,对于我们而言,在AWS安全负载均衡器后面的Apache和Nginx EC2实例都是:

  1. 在负载均衡器处,将端口80转发到实例上的端口80
  2. 将端口443转发到实例
  3. 上的端口8080(例如)
  4. 在Web服务器中,侦听两个端口(80和8080)
  5. 将端口80重定向到端口443
  6. 添加环境变量&#34; HTTPS&#34;,值为&#34; on&#34;对于EC2,例如,使用Elastic Beanstalk软件配置
  7. 步骤1确保自然地处理AWS内部流量&#34;。

    第2步只允许安全的外部流量到达我们的代码

    步骤5告诉Web服务器及其背后的内容(在我们的例子中是Laravel)生成的URL应该是https:scheme。其他框架可能需要设置其他一些环境变量才能触发该行为。