Let's Encrypt, but simple
Posted on 2018-03-18 16:20 in misc
I don't like big monolithic things like Caddy or docker-oriented heavy web servers.
I don't like Certbot managing my web server; it's busy and functionnal already.
I don't like changing DNS records for TLS; most servers don't have any control over their domains, and that's good.
What I like, is having one default HTTP vhost (should be the only one present) that handles Let's Encrypt challenges and redirect the rest to the proper HTTPS vhost; and behind that, a Certbot that will only interact through a shared directory.
Nginx is great and can do that very easily, without heavy additional tools:
server {
listen 80 default_server;
access_log off;
location ^~ /.well-known/acme-challenge/ {
root /var/www/challenges/;
}
location / {
rewrite / https://$host$uri;
}
}
It's also a good place to use stub_status if you need any,
between the two location
blocks:
location /nginx_status {
stub_status on;
allow 127.0.0.1;
deny all;
}
Before reloading nginx, create that shared directory:
mkdir -p /var/www/challenges/
systemctl reload nginx
You of course need Certbot, which has a very nice package for
Debian 9 (current stable) and Ubuntu: apt install certbot
Otherwise, https://certbot.eff.org/ has good installation instructions.
Often forgotten step but very important, reload nginx after certificates
are changed. crontab -e
as root and add that at the end:
0 0 * * * service nginx reload > /dev/null
(You could edit /etc/cron.d/certbot
like this
but I prefer not to edit files already managed by dpkg.)
Add a vhost
Now the wholesome simple part that hopefully should just work once your DNS is correct:
certbot certonly --webroot -w /var/www/challenges/ -d example.com -d sub.example.com
# feel free to remove the "-d sub.example.com" or add more names
You can add multiple subdomains or alternative domains to the same certificate,
but they will have to be renewed at the same time.
It's a bit easier to maintain mutliple certs, especially when it's nicely
automated like that. I recommend grouping certs by domain or usage/service.
(see Let's Encrypt's rate limits, also keep in mind
names will be publicly associated in the certificate)
And once that's done, you should be able to just add or enable the related vhost, with functional TLS.
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com sub.example.com;
root /var/www/example/;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
}
The example.com
in all /etc/letsencrypt/
paths is the first -d
option
passed to certbot, used to identify the certificate.
If you added multiple -d
options, they will share that certificate.
And with the previous default HTTP vhost,
http://example.com
and http://sub.example.com
will redirect to their
https://
version, unless it's about ACME challenges.