Letsencrypt with Zonomi and Rimuhosting name servers using hooks

SSL is good, you should use it everywhere!

Letsencrypt it is a project that allows you to obtain signed certificates for free (you should consider donating though) to secure your website. Big efforts have been done to make this accessible to anyone.

In order to issue SSL certificates Certificate Authorities will check that you can control the domain, by either 1) sending validation emails to specific addresses within domain, 2) requesting special files in the website for the domain or 3) setup special DNS records that are checked during the certificate issue, Letsencrypt specially likes to do the latter two. These special files or DNS records are normally called challenges, and if you host DNS zones with Rimuhosting or Zonomi name servers now there is an easy way for you to issue Letsencrypt certificates.

(Photo by Steven Lilley )

In resume DNS challenges by letsencrypt are TXT records that contain a token. During the certificate request a token is provided by Letsencrypt API, such token needs to be deployed to the dns zone to probe domain control, eg:

_acme-challenge.DOMAIN.TLD. IN TXT "aaaaaaaaaabbbbbbbbbbbbbccccccccccddddddddddddd"

Once the record it is live Letencrypt API gets notified about the challenge, proceeds to verify it and if it is valid it will proceed to issue the signed cert.

The most commonly used letsencrypt clients are dehydrated and certbot.  These clients can use the Lexicon DNS manipulation library to perform the DNS validation of domain control.  We have contributed drivers to Lexicon for our Zonomi and RimuHosting DNS services so you can use dehydrated and certbot (soon to be supported as a plugin) to request dns-challenge-based- certificates.

The dns challenges are setup making use of the Zonomi or Rimuhosting dns API.

Before starting make sure you have your dns API key in hand, it can be seen at http://zonomi.com/app/cp/apikeys.jsp and https://rimuhosting.com/cp/apikeys.jsp respectively.

Dehydrated LetsEncrypt Client

Installing dehydrated (a LetsEncrypt client) it is quite straight forward:

cd /opt
git clone 'https://github.com/lukas2511/dehydrated.git'
/opt/dehydrated/dehydrated --register --accept-terms

The certificates will end up at /opt/dehydrated/certs/ for each domain, eg:

/opt/dehydrated/certs/DOMAIN.TLD/fullchain-1513034748.pem
/opt/dehydrated/certs/DOMAIN.TLD/privkey-1513034748.pem
/opt/dehydrated/certs/DOMAIN.TLD/cert-1513034748.pem
/opt/dehydrated/certs/DOMAIN.TLD/fullchain.pem
/opt/dehydrated/certs/DOMAIN.TLD/cert-1513034748.csr
/opt/dehydrated/certs/DOMAIN.TLD/cert.csr
/opt/dehydrated/certs/DOMAIN.TLD/privkey.pem
/opt/dehydrated/certs/DOMAIN.TLD/cert.pem
/opt/dehydrated/certs/DOMAIN.TLD/chain.pem
/opt/dehydrated/certs/DOMAIN.TLD/chain-1513034748.pem

Lexicon and Dehydrated

Next: install the lexicon DNS library and use the sample hook with the dehydrated LetsEncrypt client to issue certs:

pip install dns-lexicon
wget 'https://raw.githubusercontent.com/AnalogJ/lexicon/master/examples/dehydrated.default.sh' -O /opt/dehydrated/lexicon.hook.sh
chmod +x /opt/dehydrated/lexicon.hook.sh
export PROVIDER=zonomi; \
export LEXICON_ZONOMI_TOKEN=XXXXXXXXXXXXXXX; \
/opt/dehydrated/dehydrated --hook /opt/dehydrated/lexicon.hook.sh --challenge dns-01 --cron --accept-terms --domain DOMAIN.TLD

Set the LEXICON_ZONOMI_TOKEN variable your API key, also replace the right domain at DOMAIN.TLD. If you are using rimuhosting name servers, please specify the following environment variable too,  LEXICON_ZONOMI_ENTRYPOINT=rimuhosting :

export PROVIDER=zonomi; \
export LEXICON_ZONOMI_TOKEN=XXXXXXXXXXXXXXX; \
export LEXICON_ZONOMI_ENTRYPOINT=rimuhosting; \
/opt/dehydrated/dehydrated --hook /opt/dehydrated/lexicon.hook.sh --challenge dns-01 --cron --accept-terms --domain DOMAIN.TLD

Automated Certificate Renewal with Dehydrated+Lexicon

For renewals simply configure the cron with the same sample commands as above, eg:

crontab -e
@monthly export PROVIDER=zonomi; export LEXICON_ZONOMI_TOKEN=XXXXXXXXXXXXXXX; /opt/dehydrated/dehydrated --hook /opt/dehydrated/lexicon.hook.sh --challenge dns-01 --cron --accept-terms --domain DOMAIN.TLD

Make sure you also add to the command the proper service reload, eg: systemctl reload apache2.service

Dehydrated LetsEncrypt client with a bash DNS hook

The following bash hook can be used without the need of lexicon, but it may be not as feature full, based in the certbot scripts hooks below:

wget 'https://proj.ri.mu/dehydrated.zonomi.hook.sh' -O /opt/dehydrated/dehydrated.zonomi.hook.sh
chmod +x /opt/dehydrated/dehydrated.zonomi.hook.sh
export API_KEY="XXXXXXXXXXX"; \
/opt/dehydrated/dehydrated --cron --accept-terms --challenge dns-01 --hook /opt/dehydrated/dehydrated.zonomi.hook.sh --domain DOMAIN.TLD

Set the API_KEY variable your API key, also replace the right domain at DOMAIN.TLD. If you are using rimuhosting name servers, please specify the following environment variable too,  ​DNS_APIURL :

export DNS_APIURL="https://rimuhosting.com/dns/dyndns.jsp"; \
export API_KEY="XXXXXXXXXXX"; \
/opt/dehydrated/dehydrated --cron --accept-terms --challenge dns-01 --hook /opt/dehydrated/dehydrated.zonomi.hook.sh --domain DOMAIN.TLD

Automated Certificate Renewal with Dehydrated+Bash

For renewals simply configure the cron with the same sample commands as above, eg:

crontab -e
@monthly export API_KEY="XXXXXXXXXXX"; /opt/dehydrated/dehydrated --cron --accept-terms --challenge dns-01 --hook /opt/dehydrated/dehydrated.zonomi.hook.sh --domain DOMAIN.TLD

Make sure you also add to the command the proper service reload, eg: systemctl reload apache2.service

Dehydrated LetsEncrypt client with wildcard certs

For wildcard certs, some extra params are required, the order for them it is important. For example the parameters for dehydrated must be in the following order: --domain DOMAIN.TLD --domain *.DOMAIN.TLD, eg:

/opt/dehydrated/dehydrated --hook /opt/dehydrated/lexicon.hook.sh --challenge dns-01 --cron --accept-terms --domain DOMAIN.TLD --domain *.DOMAIN.TLD --alias DOMAIN.TLD, also must include --alias DOMAIN.TLD
 
/opt/dehydrated/dehydrated --cron --accept-terms --challenge dns-01 --hook /opt/dehydrated/dehydrated.zonomi.hook.sh --domain DOMAIN.TLD --domain *.DOMAIN.TLD --alias DOMAIN.TLD

Certbot LetsEncyrpt client

We are doing some work to get zonomi and rimuhosting name servers supported by certbot as a plugin.
Certificates in letsencrypt are normally located at:

/etc/letsencrypt/live/DOMAIN.TLD/
/etc/letsencrypt/live/DOMAIN.TLD/fullchain.pem
/etc/letsencrypt/live/DOMAIN.TLD/privkey.pem
/etc/letsencrypt/live/DOMAIN.TLD/cert.pem
/etc/letsencrypt/live/DOMAIN.TLD/chain.pem

You can use 'manual' hooks with the certbot LetsEncrypt client.

mkdir /etc/letsencrypt/manual-hooks
cd /etc/letsencrypt/manual-hooks
wget 'https://proj.ri.mu/certbot-zonomi-authenticator.sh'
wget 'https://proj.ri.mu/certbot-zonomi-cleanup.sh'
chmod +x certbot-zonomi-authenticator.sh certbot-zonomi-cleanup.sh

Edit the file certbot-zonomi-authenticator.sh variables API_KEY and DNS_APIURL with the right configuration, invoke certbot as follows:

certbot certonly --manual --preferenges=dns --manual-auth-hook /etc/letsencrypt/manual-hooks/certbot-zonomi-authenticator.sh \
--manual-cleanup-hook /etc/letsencrypt/manual-hooks/certbot-zonomi-cleanup.sh --manual-public-ip-logging-ok -d DOMAIN.TLD

Certbot handles configuration for the renewals once a cert has been issued correctly, but still you may need to configure services to reload certs.

Certbot LetsEncrypt client with wildcard certs

For wildcard certs, some extra params are required, the order for them it is important.   For certbot the parameters for the domains must be in the following order -d *.DOMAIN.TLD -d DOMAIN.TLD, also must include --server https://acme-v02.api.letsencrypt.org/directory, eg:

certbot certonly --manual --preferred-challenges=dns --manual-auth-hook /etc/letsencrypt/manual-hooks/certbot-zonomi-authenticator.sh --manual-cleanup-hook /etc/letsencrypt/manual-hooks/certbot-zonomi-cleanup.sh --manual-public-ip-logging-ok --server https://acme-v02.api.letsencrypt.org/directory -d *.DOMAIN.TLD -d DOMAIN.TLD

 Acme.sh LetsEncrypt Client

acme.sh is bash-based LetsEncrypt client.  It supports zonomi out of the box and works quite well, it can be even be installed as a normal user, to install:

curl https://get.acme.sh | sh

Or:

wget -O -  https://get.acme.sh | sh

During install it will configure a cron service for renewals:

0 0 * * * "/home/user/.acme.sh"/acme.sh --cron --home "/home/user/.acme.sh" > /dev/null

The certs will be placed in ~/.acme.sh/DOMAIN.TLD/

To issue a cert:

export ZM_Key=XXXXXXXXXXXXXXXXXX; acme.sh --issue --dns dns_zonomi -d DOMAIN.TLD -d *.DOMAIN.TLD

Set the variable ZM_Key to your Zonomi API key, replace DOMAIN.TLD with your domain and if make sure to include *.DOMAIN.TLD if you wish to issue a wildcard

The output of the script has plenty of information.

For more acme.sh options  see the README.md (also covers setting up a renewal cron job).

This entry was posted in HOWTO, Rimuhosting, Security and tagged , , , . Bookmark the permalink.

Leave a Reply