尝试使用负载均衡器启用 SSL/HTTPS 时 AWS elastic beanstalk HTTP 502

问题描述 投票:0回答:1

我想在序言中指出,网络不是我的强项,但我必须在我的用例中使用它。

我正在尝试与在 Apache Tomcat 上运行的 Web 应用程序建立 HTTPS 连接。我在 AWS elastic beanstalk 中启动了容器,当我只使用单个实例时,它运行得很好。当我放入负载均衡器时,它也工作得很好,保留默认端口侦听器并按原样处理。但是,当我尝试将传入连接重定向到 HTTPS 时,我收到 502 错误。我检查了控制台,看起来端口 443 或 8443 上都没有运行侦听器(我已确认在 tomcat 配置文件夹下的 server.xml 文件中启用了后者),当我检查 Catalina 时我注意到,似乎正在运行的唯一协议处理程序是为端口 8080 设置的协议处理程序,尽管配置文件明确指出了其他情况。日志中没有错误,这表明我的应用程序启动正确。此外,502 bad gateway 错误页面没有显示其他信息 - 没有 nginx 版本来指示错误与代理有关,并且 Amazon 的任何日志记录中都没有有用的信息。

我完全被难住了,因为亚马逊的文档中没有真正的迹象表明,使用 HTTPS 需要对其 tomcat 环境进行任何进一步的特殊配置——其范围意味着发生在 EBS 设置配置中,其中负载均衡器和这样配置的。您是否有可能无法重新配置环境以追溯使用 HTTPS,而我必须重建整个环境才能实现此目的?在过去的一天半里,我只是觉得我在用头撞墙。

我尝试重新启动实例,修改负载均衡器重定向配置,并将代理服务器从 nginx 切换到 apache httpd。显然,我希望应用程序能够加载,而不是继续这种令人讨厌的拒绝合作(AWS 就像一头愤怒的公牛,过去几周我一直在与它争论)。根据日志,tomcat 似乎正在尝试将请求解释为未加密的 HTTP 请求,所以显然缺少某些内容...帮助!

amazon-web-services tomcat amazon-ec2 https amazon-elastic-beanstalk
1个回答
0
投票

对于将来遇到这种头痛的其他人,这就是我所做的(最终)有效的。

AWS 文档中隐藏着有关使用 YAML 和/或 JSON 文件手动配置 beanstalk 环境的信息(据我所知,您可以在文件中混合语法)。 .ebextensions 文件夹包含这些文件,然后 .platform 文件夹包含特定于您的服务器的配置(在本例中为 Apache)。我还获得了用于端到端加密的自签名证书,因为浏览器只能看到负载均衡器正在使用的证书,而不必担心后端是自签名的。 (为此,我必须大量阅读有关 SSL 和安全性的内容,几年后它将过时......叹息)

您的应用程序根目录中需要两个文件夹(也就是说,如果您解压 WAR,如果您使用的是 Java EE 或 Spring,这些文件夹将与 WEB-INF 文件夹处于同一级别)。 在 .ebextensions 下,您必须配置负载均衡器(我还借此机会在此文件夹中指定了我的环境变量)。

配置应该如下所示(您可以拆分文件,只要将它们命名为相对容易记住的名称即可):

packages:
    yum:
       mod_ssl : []
Resources:
    AWSEBAutoScalingGroup:
        Type: "AWS::AutoScaling::AutoScalingGroup"
        Metadata:
            AWS::CloudFormation::Authentication:
                S3Auth:
                    type: "S3"
                    buckets: ["elasticbeanstalk-us-east-1-705738864590"]
                    roleName:
                        "Fn::GetOptionSetting":
                            Namespace: "aws:autoscaling:launchconfiguration"
                            OptionName: "IamInstanceProfile"
                            DefaultValue: (your instance profile name)
option_settings:
    aws:elbv2:listener:443:
        Protocol: HTTPS
        SSLCertificateArns: (put the ARN for your certificate here)
    aws:elasticbeanstalk:environment:process:default:
        Port: '443'
        Protocol: HTTPS
        StickinessEnabled: 'true'
        StickinessLBCookieDuration: '43200'
    aws:elasticbeanstalk:environment:proxy:
        ProxyServer: apache
files:
/etc/pki/tls/certs/server.crt:
    mode: "000400"
    owner: root
    group: root
    content: |
-----BEGIN CERTIFICATE-----
(paste your self-signed certificate's public key here)
-----END CERTIFICATE-----
/etc/pki/tls/certs/server.key:
    mode: "000400"
    owner: root
    group: root
    authentication: "S3Auth"
    source: (link your certificate's private key from the S3 bucket here)
/opt/elasticbeanstalk/hooks/appdeploy/post/99_start_httpd.sh:
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      sudo service httpd restart

然后你需要有一个配置文件来将侦听器放在端口 443 和 80 上 - 这位于 .platform 下(这在文档中并不明显,我花了相当多的时间才找到答案 - - 如果您尝试将它们放在 .ebextensions 下,它将不起作用)。事实证明,我遇到的很多麻烦是因为我的端口重定向导致运行状况检查失败——我需要为重定向规则设置一个重写条件,这样它就不会扰乱运行状况检查.

.platform/httpd/conf.d/redirect.conf:

RewriteEngine On
RewriteCond %{HTTP_HOST} !localhost
RewriteCond %{HTTP_USER_AGENT} !^ELB-HealthChecker.*
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</If>

.platform/httpd/conf.d/https.conf:

Listen 443
LoadModule ssl_module modules/mod_ssl.so
<VirtualHost *:443>
  <Proxy *>
    Order deny,allow
    Allow from all
  </Proxy>

  ServerName            (your domain)
  SSLEngine             on
  SSLCertificateFile    "/etc/pki/tls/certs/server.crt"
  SSLCertificateKeyFile "/etc/pki/tls/certs/server.key"
  SSLCipherSuite        EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
  SSLProtocol           All -SSLv2 -SSLv3
  SSLHonorCipherOrder   On

  Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
  Header always set X-Frame-Options DENY
  Header always set X-Content-Type-Options nosniff

  ProxyPass / http://localhost:8080/ retry=0
  ProxyPassReverse / http://localhost:8080/
  ProxyPreserveHost on

</VirtualHost>

请注意,证书和密钥文件名只需与您在 .ebextensions 下的文件系统配置中输入的内容相匹配。

无论如何,足以说明 AWS 不遗余力地让这对我来说是一大堆看似不必要的工作,我现在更有理由鄙视 Jeff Bezos。

© www.soinside.com 2019 - 2024. All rights reserved.