matrey / acme-tiny-auto

Bash wrapper for acme_tiny.py. It helps you procure Let's Encrypt or Buypass certificates in a few commands, renew them automatically, and it should not break your server if anything fails during renewal.
MIT License
3 stars 0 forks source link
acme acme-tiny certificate https letsencrypt nginx ssl-certificate

acme-tiny-auto

Bash wrapper for acme_tiny.py. It helps you procure Let's Encrypt or Buypass certificates (single domain only, HTTP-01 validation only) in a few commands, renew them automatically, and it should not break your server if anything fails during renewal.

Usage: ./acme-tiny-auto.sh [init | add [domain]| renew [domain] | force-renew [domain] | renew-all ]

Step by step instructions (Nginx)

Create the folder for the scripts and certificates

All the steps below are to be run as root. We decided to store everything in a new path /acme ; update the commands and configurations accordingly if you choose another location.

mkdir -p /acme

Send requests for /.well-known/acme-challenge to our custom folder

Make sure to create the webroot folder in advance (otherwise Nginx will fail to restart)

mkdir -p /acme/shared/.well-known/acme-challenge

Edit Nginx default server configuration for port 80 (you should see something like listen 80 default_server;) to add these 2 locations:

    # From https://community.letsencrypt.org/t/how-to-nginx-configuration-to-enable-acme-challenge-support-on-all-http-virtual-hosts/5622 
    location ^~ /.well-known/acme-challenge/ {
        default_type "text/plain";
        root /acme/shared;
    }
    location = /.well-known/acme-challenge/ {
        return 404;
    }

Restart Nginx.

Initialize the environment (once per machine)

cd /acme
wget https://raw.githubusercontent.com/matrey/acme-tiny-auto/master/acme-tiny-auto.sh
# wget https://gitee.com/matrey/acme-tiny-auto/raw/master/acme-tiny-auto.sh # (from China)
chmod +x acme-tiny-auto.sh
./acme-tiny-auto.sh

It will ask you to create a config.sh file, and offers the following template:

# Provider: either "letsencrypt" or "buypass". For buypass you must provide an email address.
ACMEPROVIDER=buypass
ACMECONTACTEMAIL=nobody@example.com

# This should be the webroot for challenges. If you don't rewrite URLs it should contain /.well-known/acme-challenge/ (and these folders should exist)
WELLKNOWNROOT=/acme/shared/.well-known/acme-challenge/

# (optional) This is the function to be called if at least one certificate has been changed (renew, renew-all only)
function apply_new_cert(){
  # SIGHUP nginx
  kill -HUP $( cat /run/nginx.pid )
}

Save these lines under /acme/config.sh and ensure WELLKNOWNROOT is correct (it should match the path configured in Nginx's default host). We will get back to apply_new_cert later.

Then we initialize the environment (download root certs from Let's Encrypt, download acme_tiny.py, etc.)

./acme-tiny-auto.sh init
# VENDORED=1 ./acme-tiny-auto.sh init # (from China)

Verify all went fine.

Add one domain (for each new domain)

First we get the certificate for it (replace example.com by your (sub)domain)

cd /acme
./acme-tiny-auto.sh add example.com

If all goes well, we end up with:

Then we need to edit this host's Nginx configuration.

Go get proper settings from https://mozilla.github.io/server-side-tls/ssl-config-generator/

In the generated code, remember to edit:

Side note: for ssl_dhparam you can use openssl dhparam -out /acme/dhparam.pem 2048 to generate the file under /acme/dhparam.pem

Restart Nginx and verify all is fine. You can use Qualys SSLTest service to verify the grade for your server: https://www.ssllabs.com/ssltest/

Renewal management

Automatically renew certificates

Remember to schedule a cronjob on root that calls /acme/acme-tiny-auto.sh renew-all. e.g.

20 16 * * * /acme/acme-tiny-auto.sh renew-all

It will automatically renew certificates for all domains under domains, no more than 7 days before they expire. So it's not a problem to run it "often" (daily at 4:20pm in the example above).

We finally get back to the apply_new_cert function in config.sh. It will be called at the end of renew-all if any certificate has been renewed. The objective is to send a signal to the webserver to load the new certificate. For Nginx, the following usually works well: kill -HUP $( cat /run/nginx.pid )

Stop renewing certificates for a domain

To just let the current certificate expire, and not attempt to renew it, you can put an empty "do_not_renew" file in the domain folder. e.g.

touch /acme/domains/example.com/do_not_renew