turnip
turnip

Reputation: 2346

Enabling HTTPS on a Single Instance Beanstalk application: Unable to find a virtual host listening on port 80

I running a single instance application (i.e.: NOT using a load balancer) on Elastic Beanstalk and I want to enable HTTPS on it. It is a simple Flask application. In order to do this, I need to install an SSL certificate.

I tried following this article but unfortunately, I am running into this error:

PluginError: Unable to find a virtual host listening on port 80 which is currently needed for Certbot to prove to the CA that you control your domain. Please add a virtual host for port 80. Please see the logfiles in /var/log/letsencrypt for more details.

Here is my 00_apache_ssl.config file:

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"

As you can see I tried adding a virtual host on port 80 but it did not work. I also tried changing the Listen value to port 80 too.


For reference, my .ebextensions folder contains:

And the contents of wsgi_custom.config are:

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

Any ideas?

Upvotes: 4

Views: 1533

Answers (1)

imaginate
imaginate

Reputation: 59

Have the same problem as yours and I just figured it out recently.

Certbot can't verify the domain if port 80 would redirect to https. Try adding

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

in your virtualhost for port 80, right before the rewrite rule. This tells the Apache to exclude \.well-known/acme-challenge from redirection. This url is what certbot tries to retrieve while doing an HTTP-01 challenge.

Your new rewrite rule would look like this

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

Upvotes: 2

Related Questions