Certbot host script for Nginx running in a Docker container
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Thor the Norseman 6d91ae31b8 Revised comments in certboy.py for clarity 9 months ago
.gitignore Initial commit 9 months ago
LICENSE Initial commit 9 months ago
README.md Edited README.md. 9 months ago
certbot.py Revised comments in certboy.py for clarity 9 months ago
certbot_config.example.py Initial commit 9 months ago

README.md

Docker Nginx Certbot script

This is a Python 3 script that configures Let's Encrypt for an Nginx server running inside of a Docker container.

certbot.py

The main script. It expects a config file, located in the same directory, named certbot_config.py. Make a copy of the included example configuration and edit to taste.

Dependencies

sudo apt install certbot
pip3 install crossplane

Setup

certbot expects a file in the .well-known directory on the webroot when verifying domains. Certbot typically modifies the Nginx configuration files and reloads them underway in order to serve this directory via plain HTTP before SSL is configured. Since the script uses the webroot plugin, we need to take a different approach:

The script assumes that the SSL configuration directives for each Nginx host is kept in separate files under /etc/nginx/conf.d per host. Before SSH is enabled for a new host, its HTTPS configuration file should be a dotfile in order to prevent Nginx from attempting to load it.

The plain HTTP configuration file for a host should look roughly like this:

server {
    listen 80;
    server_name host.tld www.host.tld;
  
    location ~ /.well-known {
        root /usr/share/nginx/certbot;
    }  

    location / {
        return 301 https://$host$request_uri;
    }
}

It resembles the HTTP half of an Nginx host configuration file generated by Certbot's Nginx plugin; the difference being that it serves .well-known if requested, instead of unconditionally redirecting to HTTPS. The path /usr/share/nginx/certbot on the container, mounted somewhere on the host, is used by Certbot to configure all domains for SSL.

For certbot.py to work, it's required that all include statements in your Nginx configuration files use relative paths, or Crossplane won't be able to parse them properly.

For convenience, create a file /etc/nginx/ssl.conf looking roughly like this:

ssl_certificate /etc/letsencrypt/live/$PRIMARY_DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$PRIMARY_DOMAIN/privkey.pem;

ssl_dhparam ssl-dhparams.pem;

ssl_session_cache shared:le_nginx_SSL:1m;
ssl_session_timeout 1440m;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

ssl_ciphers "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS";

Be sure to substitute $PRIMARY_DOMAIN for the primary domain in your certbot_config.py file, as this is the location Certbot will place your certificates in.

The SSL version of your Nginx host configuration files would look roughly like this:

server {
    listen 443 ssl;
    server_name host.tld www.host.tld;
    
    include ssl.conf;

    location / {
        root   /usr/share/nginx/host.tld;
        index  index.html index.htm;
    }
}

With these files in place, you can reload Nginx and run ./certbot.py. Certificate configuration should then commence in the usual fashion.

Once completed, undotify all your SSL dotfiles and reload Nginx again. You should now have a working SSL configuration for all your domains.

To add new domains, simply follow the same procedure as above, while leaving the other configuration files in place, and certbot.py will generate a new certificate containing the new domains.