|
|
|
# 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.
|