在单实例 Beanstalk 应用程序上启用 HTTPS:找不到在端口 80 上侦听的虚拟主机

Posted

技术标签:

【中文标题】在单实例 Beanstalk 应用程序上启用 HTTPS:找不到在端口 80 上侦听的虚拟主机【英文标题】:Enabling HTTPS on a Single Instance Beanstalk application: Unable to find a virtual host listening on port 80 【发布时间】:2019-05-19 03:33:25 【问题描述】:

我在 Elastic Beanstalk 上运行 单个实例 应用程序(即:不使用负载均衡器),我想在其上启用 HTTPS。这是一个简单的 Flask 应用程序。为此,我需要安装 SSL 证书。

我尝试关注this article,但不幸的是,我遇到了这个错误:

PluginError:无法找到正在侦听端口 80 的虚拟主机,Certbot 当前需要该虚拟主机向 CA 证明您控制您的域。请为端口 80 添加虚拟主机。 有关详细信息,请参阅 /var/log/letsencrypt 中的日志文件。

这是我的00_apache_ssl.config 文件:

Resources:
    sslSecurityGroupIngress:
        Type: AWS::EC2::SecurityGroupIngress
        Properties:
            GroupId: "Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]
            IpProtocol: tcp
            ToPort: 443
            FromPort: 443
            CidrIp: 0.0.0.0/0

files:
    /etc/httpd/conf.d/ssl.pre:
        mode: "000644"
        owner: root
        group: root
        content: |
            LoadModule ssl_module modules/mod_ssl.so
            Listen 443

            <VirtualHost *:80>
                RewriteEngine On
                RewriteCond %HTTPS off
                RewriteRule (.*) https://%HTTP_HOST%REQUEST_URI
            </VirtualHost>

            <VirtualHost *:443>
                <Directory /opt/python/current/app/build/static>
                    Order deny,allow
                    Allow from all
                </Directory>

                SSLEngine on
                SSLCertificateFile "/etc/letsencrypt/live/EB_INSTANCE_DOMAIN_NAME/fullchain.pem"
                SSLCertificateKeyFile "/etc/letsencrypt/live/EB_INSTANCE_DOMAIN_NAME/privkey.pem"
                SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
                SSLProtocol All -SSLv2 -SSLv3
                SSLHonorCipherOrder On
                SSLSessionTickets Off

                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:80/ retry=0
                ProxyPassReverse / http://localhost:80/
                ProxyPreserveHost on
                RequestHeader set X-Forwarded-Proto "https" early
                # If you have pages that may take awhile to
                # respond, add a ProxyTimeout:
                # ProxyTimeout seconds
            </VirtualHost>

    /tmp/renew_cert_cron:
        mode: "000777"
        owner: root
        group: root
        content: |
            # renew Lets encrypt cert with certbot command
            0 1,13 * * * /tmp/certbot-auto renew

packages:
    yum:
        epel-release: []
        mod24_ssl : []

# Steps here
# 1. Install certbot
# 2. Get cert (stop apache before grabbing)
# 3. Link certs where Apache can grab
# 4. Get the Apache config in place
# 5. Move certbot-auto into tmp folder
container_commands:
    10_installcertbot:
        command: "wget https://dl.eff.org/certbot-auto;chmod a+x certbot-auto"
    20_getcert:
        command: "sudo ./certbot-auto certonly --debug --non-interactive --email MY_EMAIL --agree-tos --debug --apache --domains EB_INSTANCE_DOMAIN_NAME --keep-until-expiring"
    30_link:
        command: "sudo ln -sf /etc/letsencrypt/live/EB_INSTANCE_DOMAIN_NAME"
    40_config:
        command: "sudo mv /etc/httpd/conf.d/ssl.pre /etc/httpd/conf.d/ssl.conf"
    50_mv_certbot_to_temp_for_cron_renew:
        command: "sudo mv ./certbot-auto /tmp"
    60_create_cert_crontab:
        command: "sudo crontab /tmp/renew_cert_cron"
    70_delete_cronjob_file:
        command: "sudo  rm /tmp/renew_cert_cron"

如您所见,我尝试在端口 80 上添加虚拟主机,但没有成功。我也尝试将 Listen 值更改为端口 80。


作为参考,我的.ebextensions 文件夹包含:

00_apache_ssl.config wsgi_custom.config

wsgi_custom.config的内容是:

files:
  "/etc/httpd/conf.d/wsgi_custom.conf":
    mode: "000644"
    owner: root
    group: root
    content: |
      WSGIPassAuthorization On

有什么想法吗?

【问题讨论】:

【参考方案1】:

遇到和你一样的问题,最近才发现。

如果端口 80 将重定向到 https,则 Certbot 无法验证域。尝试添加

RewriteCond %REQUEST_URI !\.well-known/acme-challenge

在您的虚拟主机中为端口 80,就在重写规则之前。这告诉 Apache 从重定向中排除 \.well-known/acme-challenge。此 url 是 certbot 在执行 HTTP-01 质询时尝试检索的内容。

您的新重写规则如下所示

RewriteEngine On
RewriteCond %HTTPS off
RewriteCond %REQUEST_URI !\.well-known/acme-challenge
RewriteRule (.*) https://%HTTP_HOST%REQUEST_URI

【讨论】:

以上是关于在单实例 Beanstalk 应用程序上启用 HTTPS:找不到在端口 80 上侦听的虚拟主机的主要内容,如果未能解决你的问题,请参考以下文章

如何为我的 Elastic Beanstalk 单实例配置 SSL

Spring Boot 和单实例 AWS Beanstalk SSL 设置错误

如何为我的 Elastic Beanstalk Java 应用程序启用 HTTPS?

在 AWS Elastic Beanstalk 应用程序上启用 HTTPS

Elastic Beanstalk 环境的 Auto Scaling 组

如何在运行 java 应用程序的弹性 beanstalk 应用程序上启用 java 调试?