Skip to content

Latest commit

 

History

History
201 lines (148 loc) · 9.06 KB

howto-use.md

File metadata and controls

201 lines (148 loc) · 9.06 KB

How to use acme-dns-tiny project

If you already have a Let's Encrypt issued certificate and just want to renew, you should only have to do Steps 3 and 6.

Step 1: Create a Let's Encrypt account private key (if you haven't already)

This step need to be done on the machine which will run the acme-dns-tiny script.

You must have a public key registered with Let's Encrypt and sign your requests with the corresponding private key. If you don't understand what I just said, this script likely isn't for you! Please use the official Let's Encrypt client. To accomplish this you need to initially create a key, that can be used by acme-dns-tiny, to register an account for you and sign all following requests.

NOTE: currently, acme-dns-tiny expects the account key to be a RSA key, as the original acme-tiny. It seems that the external contributor drdaeman has been able to update the original script to be able to detect automatically ECDSA account key.

openssl genrsa 4096 > account.key

Use existing Let's Encrypt key

Alternatively you can convert your key, previously generated by the original Let's Encrypt client.

The private account key from the Let's Encrypt client is saved in the JWK format. acme-dns-tiny is using the PEM key format. To convert the key, you can use the tool conversion script by JonLundy:

# Download the script
curl 'https://gist.githubusercontent.com/JonLundy/f25c99ee0770e19dc595/raw/6035c1c8938fae85810de6aad1ecf6e2db663e26/conv.py' > conv.py

# Copy your private key to your working directory
cp /etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/<id>/private_key.json private_key.json

# Create a DER encoded private key
openssl asn1parse -noout -out private_key.der -genconf <(python conv.py private_key.json)

# Convert to PEM
openssl rsa -in private_key.der -inform der > account.key

Step 2: Create a certificate signing request (CSR) for your domains.

This step need to be done on the server running TLS services.

The ACME protocol (what Let's Encrypt uses) requires a CSR file to be submitted to it, even for renewals. You can use the same CSR for multiple renewals.

NOTE: you can't use your account private key as your domain private key!

Let's encrypt has support for both RSA and ECDSA (ECC) certificates. Depending on your needs and if you don't have a private key already, you can generate a new key with one of the following command:

# Generate a 384-bit ECDSA domain private key (to get an ECC certificate)
openssl ecparam -out domain.key -name secp384r1 -genkey
# Or generate a RSA domain private key
openssl genrsa 4096 > domain.key

Then, you can generate the Certificate Signing Request (CSR), using one of the following commands:

# If you want to sign a single domain
openssl req -new -sha256 -key domain.key -subj "/CN=example.org" > domain.csr

# If multiple domains should be signed and your OpenSSL version is >= 1.1.1
# (use this one if you want both www.example.org and example.org)
openssl req -new -sha256 -key domain.key -subj "/" -addext "subjectAltName = DNS:example.org, DNS:www.example.org" > domain.csr

# If multiple domains should be signed and your OpenSSL version is < 1.1.1
openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:example.org,DNS:www.example.org")) > domain.csr

Finally, copy the CSR (yes, only the CSR without the key) on the machine which will run the acme-dns-tiny script.

Step 3: Make your DNS server allows dynamic updates

You must prove you own the domains you want a certificate for, so Let's Encrypt requires you host some specific DNS resource records during the signing process.

When you'll ask to verify the domain example.com, ACME protocol requires your DNS server to host a TXT resource record to the domain _acme-challenge.example.com with a specific identifier as value (if you ask to verify multiple domains, you'll have to create for each domain a record prefixed by _acme-challenge).

The acme-dns-tiny script will generate and write those DNS records to your DNS server by use of DNS dynamic message updates.

So you have to configure your DNS server to allow dynamic DNS updates and create a TSIG key which will give rights to perform updates on TXT records for every domain prefixed by _acme-challenge.

If you use BIND9 as DNS server, you can read the step by step example on the bind9 setup how to

The configuration of the script will need:

  • the TSIG key name and value
  • the algorithm used for TSIG key (hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384 or hmac-512; list of algoithm depends on known ones by dnspython module)
  • the DNS zone to update
  • the address and the port of the DNS server

Step 4: Configure the script

This step need to be done on the machine which will run the acme-dns-tiny script.

The simplest way to configure the script is to copy the example.ini file from this repository.

Be careful! Set read permissions correctly on the configuration file, because it will contain the key authorized to modify your DNS configuration !

Then update the configuration file with path to the account key, the CSR, the TSIG informations, your DNS configurations.

Note, as DNS update may won't be applied instantly we apply a default delay of 10 seconds between the DNS update and the self-validation of DNS record. You can modify/suppress this delay by updating the TTL setting to correspond to your DNS server configuration (keep in mind the "self-validation" will wait up to 10 * TTL seconds before giving up).

Note, the example.ini contains by default the staging Let's Encrypt server URL. When you'll be ready, you'll need to set up the ACMEDirectory with the production URL of your CA. For example, the Let's Encrypt CA production URL is https://acme-v02.api.letsencrypt.org/directory.

Step 5: Get a signed certificate!

This step need to be done on the machine which will run the acme-dns-tiny script.

Now that you have setup your DNS server, generated all the needed files and configured the acme-dns-tiny script, you can run this script on a computer containing your private account key, the CSR and the configuration (it doesn't need to be run on your production server directly).

python3 acme_dns_tiny.py example.ini > ./chain.pem

If every thing was ok, chain.pem contains your signed certificate followed by the CA's certificate which signed yours.

Step 6: Install the certificate

The certificate chain that is output by this script can be used along with your private domain key to run any service on your server which need TSL encryption. You need to include both file in the TLS settings of your services.

So you have to copy the chain file from your machine which have run the acme-dns-tiny script$ to your server running TLS services.

Step 7: Setup an auto-renew cronjob

Congrats! Your server is now using TLS!

Unfortunately, Let's Encrypt certificates only last for 90 days, so you need to renew them often. No worries! It can be automated !

Just make a bash script and add it to your crontab (see below for an example, you may prefer another script language ;)).

Example of a skeleton for renew_cert.sh script:

#!/bin/bash

# Configuration
## You should use another directory as /tmp could be destroyed regularly
WORKINGDIR="/tmp/acme-dns-tiny"

# Notes about this script
## You should also add code to create backup of older certificates
## You may need code to handle HPKP (key pining in HTTP) updates
## You may need to update DANE (key pining in DNS) too
## With HPKP and DANE, you should also consider your automatic key rollover
## which will need to update the CSR file and/or your DNS DANE records.

# Pre run script: configure a secure workspace using ACL POSIX
mkdir -p "${WORKINGDIR}"
setfacl -m "default:other:--- , other:---" "${WORKINGDIR}"

# Run the script
python3 /path/to/acme_dns_tiny.py domain.ini > "${WORKINGDIR}/chain.pem" || exit

# Post run script
## Here, you should give access to your TLS services to the chain.pem file
## (maybe by sending it to the server running the TLS services or move to a location readable
## by these services if the script is on the same machine)
## and  reload/restart each service using TLS

Then you'll need to configure a cron job to execute this script regularly. If you use systemd, you can create a "one shot" systemd service and a systemd timer to run it.

For the cron/timer configuration, you should consider:

  • Certificates issued by Let's Encrypt servers are currently valid for 3 months, so set the timer a bit shorter.
  • To avoid DDOS on CA servers, set random minutes (and/or day in the month) to run the script
  • systemd allow to run this script with a non-privileged user service and chain it with a privileged service which will restart TLS based services.