apache - 如何在 Elastic Beanstalk 上强制使用https?

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

我似乎无法在 Elastic Beanstalk 的免费使用层上强制使用 https。

我在 How to force https on amazon elastic beanstalk without failing the health check 尝试了以下建议

使用这个 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 请求不会像我希望的那样重定向到 https。相反,http 页面正常加载。我还尝试使用 X-Forwarded-Port header 获得相同的结果。

我也试过以下重写规则
RewriteCond %{SERVER_PORT} 80
RewriteRule . https://%{SERVER_NAME}%{REQUEST_URI} [L,R]

并且此规则会导致重定向循环。因此,apache 重写规则似乎没有选择弹性负载均衡器 header X-Forwarded-Port 和 X-Forwarded-Proto,但重定向循环也不是我想要的。

请帮忙。我是 AWS、Elastic Beanstalk 的新手,对 Apache 规则不是很熟悉。我不太确定从这里去哪里。谢谢。

最佳答案

此答案假设您已在负载均衡器安全组中启用 https,将 SSL 证书添加到负载均衡器,负载均衡器转发端口 80 和 443,并将您的域名指向具有 Route 53 的 Elastic Beanstalk 环境(或等效的 DNS 服务)。
选项 1:使用 Apache 进行重定向
仅当您在使用 Apache 的 Elastic Beanstalk 环境中时才可能这样做。它可能不适用于基于 docker 的部署。
亚马逊 Linux 2
大多数基于 AWS Linux 版本 2 的平台都可以选择选择 Apache 作为您的代理主机。这可以通过转到“配置”>“软件”>
“容器选项”并将“代理服务器”设置为“Apache”。
完成后,添加一个名为 .platform/httpd/conf.d/ssl_rewrite.conf 的配置文件。到您的代码库( relevant AWS docs ),其中包含以下内容:

RewriteEngine On
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</If>
亚马逊 Linux 1
您需要做的就是将以下内容添加到您的 .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,则这不是必需的,但拥有它并没有什么坏处。
选项 2:使用 ALB 进行重定向
这仅在您使用 Application Load Balancer 时才有可能。亚马逊在此处提供了有关如何执行此操作的说明:https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-httpredirect.html
您需要做的就是将以下内容添加到您的 .config files in the .ebextensions directory of your project 之一用重定向替换 http 监听器:
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"
我见过的糟糕的解决方案
我见过很多针对这个问题的糟糕的解决方案,值得通过它们来理解为什么这个解决方案是必要的。
  • 使用 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
  • 关于apache - 如何在 Elastic Beanstalk 上强制使用https?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14693852/

    相关文章:

    python - celery 如恶魔

    php - 如何在 Debian Linux 中允许用户 www-data 访问 i2c?

    curl - 当我将 curl -X Post 与 https 一起使用时,所有内容都加密了吗?

    https - 如何使用 VBSCRIPT 并接受所有证书来使用 HTTPS 连接下载文件

    .htaccess - https 页面上的 htaccess 重写规则

    php - Laravel 的 AsgardCMS 无法在 Ubuntu 上正常运行

    php getcwd() 解析符号链接(symbolic link)的目标而不是当前目录

    apache - 将 HTTP 应用于 Apache 上运行的 HTTPS 网站的一个区域

    apache - mod_jk 不适用于 apache2.2 和 tomcat7

    .htaccess - htaccess 文件夹下所有内容的 URL 重写规则