Acme DNS-01 validation with LuaDNS for LetsEncrypt Certificates on CentOS v7.x
This work was adandoned as Certbot doesn't support DNS-01 reissuing of certificates with a manual hook script. The procedure also requires more dependencies than desired (EPEL, CentOS Openstack and a pip install).
This describes setting up the LetEncrypt acme client to perform DNS-01 validation for SMTP/IMAP/XMPP and other non-HTTP server certificates.
An authoritative DNS server is required that has API support so that validation records can be added (and removed). The NSD nameserver (which is used as the domain primary) does not support API based addition and remove of records (without lots of contortions), so a different zone is used for authentication. This technique is also useful in that production zones can explicitly delegate authority for certificate issuing to specific zones with less stringent requirements.
Note:
Until May 2016, Certbot was named simply
letsencrypt
orletsencrypt-auto
, depending on install method. Instructions on the Internet, and some pieces of the software, may still refer to this older name.
Several 'free' options were explored. They needed to be free, easy and able to register any zone. LuaDNS provides a simple free service that is great for use as a DNS-01 authentication zone.
CertBot
The CertBot package is part of the EPEL repository (along with python-certbot-apache if required). Add the EPEL repository to the machine and install certbot. The 'stable' (old) certbot can be simply installed using the following command:
# yum install epel-release # yum install certbot
However I found with DNS01 validation a more recent CertBot was required. The latest release version is available in the EPEL testing repository (# yum update --enablerepo epel-testing certbot)
The certbot is going to be run as the acme user. Create directories that are owned by the acme user/group.
for D in /var/log/letsencrypt /etc/letsencrypt/{accounts,renewal,keys,csr,archive,live} ; do mkdir -p $D ; chown acme:acme $D ; done
Register
Register an account for letencrypt. This will create a private key in the '/etc/letsencrypt/accounts' directory:
$ certbot register --agree-tos -m xxx.yyy-letsencrypt-certbot@lucidsolutions.co.nz Saving debug log to /var/log/letsencrypt/letsencrypt.log Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org ------------------------------------------------------------------------------- Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about EFF and our work to encrypt the web, protect its users and defend digital rights. ------------------------------------------------------------------------------- (Y)es/(N)o: Y Starting new HTTPS connection (1): supporters.eff.org IMPORTANT NOTES: - If you lose your account credentials, you can recover through e-mails sent to xxx.yyy-letsencrypt-certbot@lucidsolutions.co.nz. - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal.
LuaDNS and Lexicon
Setup a free DNS zone on LuaDNS.com (acme.lucidsolutions.co.nz).
# yum install centos-release-openstack-ocata # yum install python-pip python-devel openssl_devel # pip install dns-lexicon Collecting dns-lexicon Downloading dns-lexicon-1.2.4.tar.gz Requirement already satisfied (use --upgrade to upgrade): requests in /usr/lib/python2.7/site-packages (from dns-lexicon) Collecting tldextract (from dns-lexicon) Downloading tldextract-2.0.2-py2.py3-none-any.whl (52kB) 100% |████████████████████████████████| 61kB 1.0MB/s Requirement already satisfied (use --upgrade to upgrade): future in /usr/lib/python2.7/site-packages (from dns-lexicon) Requirement already satisfied (use --upgrade to upgrade): setuptools in /usr/lib/python2.7/site-packages (from tldextract->dns-lexicon) Collecting requests-file>=1.4 (from tldextract->dns-lexicon) Downloading requests_file-1.4.1-py2.py3-none-any.whl Requirement already satisfied (use --upgrade to upgrade): idna in /usr/lib/python2.7/site-packages (from tldextract->dns-lexicon) Requirement already satisfied (use --upgrade to upgrade): six in /usr/lib/python2.7/site-packages (from requests-file>=1.4->tldextract->dns-lexicon) Installing collected packages: requests-file, tldextract, dns-lexicon Running setup.py install for dns-lexicon ... done Successfully installed dns-lexicon-1.2.4 requests-file-1.4.1 tldextract-2.0.2 You are using pip version 8.1.2, however version 9.0.1 is available. You should consider upgrading via the 'pip install --upgrade pip' command.
Renew certificates
Setup a systemd timer to renew certificates twice a day (Let's Encrypt recommend twice a day, so that if a certificate is revoked downtime will be limited).
The renewal service runs as the acme user.
# cat > /etc/systemd/system/certbot-renew.service <<EOF [Unit] Description=Renew Let's Encrypt certificates [Service] Type=simple User=acme ExecStart=/bin/certbot renew --standalone --quiet EOF # cat > /etc/systemd/system/certbot-renew.timer <<EOF [Unit] Description=Daily renewal of Let's Encrypt's certificates [Timer] # twice a day, at 2AM/2PM OnCalendar=02:00:00,14:00:00 # Be kind to the Let's Encrypt servers: add a random delay of 0–3600 seconds RandomizedDelaySec=3600 Persistent=true [Install] WantedBy=timers.target EOF
# systemctl enable certbot-renew.timer # systemctl start certbot-renew.timer
Verify that the timer is setup with `systemctl list-timers`.
Examples
$ certbot certonly \ --manual --manual-auth-hook=/usr/local/bin/namecheap_dns_api_hook.sh --manual-public-ip-logging-ok \ --text --preferred-challenges dns --rsa-key-size 4096 --staging -d mta.lucidsolutions.co.nz
Namecheap
NOTE: ABONDONED (as it wasn't easy and free)
Namecheap provides free support for DNS hosting. A whole domain could be used for DNS01 validation, however this configuration uses a sub-domain called 'acme' (acme.lucidsolutions.co.nz).
# cd /usr/local/bin # wget https://raw.githubusercontent.com/wdouglascampbell/letsencrypt_namecheap_dns_api_hook/master/namecheap_dns_api_hook.sh # chmod +x namecheap_dns_api_hook.sh
Namescheap API Access
Following the instructions from Namecheap to enable API access:
The steps to enable API access are similar for both production and sandbox environments. To enable API access, follow these steps on the appropriate environment:
Login to your Namecheap account.
Go to the Profile > Tools menu.
Scroll down to the Business & Dev Tools section. Click MANAGE, next to Namecheap API Access.
Toggle ON/OFF, read our Terms of Service, enter your account password.
After enabling API access, you will be allotted an APIUsername and APIKey. Your access to the API is authenticated using these elements.
It turns out this isn't free and the option to enable it states:
We’re sorry, you have not met the criteria to qualify for API access. To qualify, you must have: Account balance of $50+, 20+ domains in your account, or purchases totaling $50+ within the last 2 years.
Links
- https://github.com/certbot/certbot
- https://certbot.eff.org/docs/intro.html
- http://serverfault.com/questions/750902/how-to-use-lets-encrypt-dns-challenge-validation
- https://github.com/lukas2511/dehydrated/wiki/Examples-for-DNS-01-hooks
- https://community.letsencrypt.org/t/web-hosting-who-support-lets-encrypt/6920
- https://github.com/certbot/certbot/issues/2053
- https://github.com/AnalogJ/lexicon
- http://www.luadns.com/api.html
- https://letsencrypt.org/docs/client-options/
- https://github.com/Neilpang/acme.sh
- https://github.com/certbot/certbot/blob/master/certbot/plugins/manual.py
- https://mjanja.ch/2016/07/using-systemd-timers-to-renew-lets-encrypt-certificates/
Appendices
Install Certbot
# yum install certbot Dependencies Resolved ===================================================================================================================== Package Arch Version Repository Size ===================================================================================================================== Installing: certbot noarch 0.9.3-1.el7 epel 16 k Installing for dependencies: dialog x86_64 1.2-4.20130523.el7 base 208 k pyOpenSSL x86_64 0.13.1-3.el7 base 133 k python-cffi x86_64 1.6.0-5.el7 base 218 k python-chardet noarch 2.2.1-1.el7_1 base 227 k python-enum34 noarch 1.0.4-1.el7 base 52 k python-idna noarch 2.0-1.el7 base 92 k python-ipaddress noarch 1.0.16-2.el7 base 34 k python-ndg_httpsclient noarch 0.3.2-1.el7 epel 43 k python-parsedatetime noarch 1.5-3.el7 epel 61 k python-ply noarch 3.4-10.el7 base 123 k python-psutil x86_64 2.2.1-1.el7 epel 114 k python-pycparser noarch 2.14-1.el7 base 104 k python-requests noarch 2.6.0-1.el7_1 base 94 k python-six noarch 1.9.0-2.el7 base 29 k python-urllib3 noarch 1.10.2-2.el7_1 base 100 k python-zope-component noarch 1:4.1.0-1.el7 epel 110 k python-zope-event noarch 4.0.3-2.el7 epel 79 k python-zope-interface x86_64 4.0.5-4.el7 base 138 k python2-acme noarch 0.9.3-1.el7 epel 168 k python2-certbot noarch 0.9.3-1.el7 epel 361 k python2-configargparse noarch 0.11.0-1.el7 epel 30 k python2-cryptography x86_64 1.3.1-3.el7 base 471 k python2-dialog noarch 3.3.0-6.el7 epel 94 k python2-mock noarch 1.0.1-9.el7 epel 92 k python2-pyasn1 noarch 0.1.9-7.el7 base 100 k python2-pyrfc3339 noarch 1.0-2.el7 epel 13 k pytz noarch 2012d-5.el7 base 38 k Transaction Summary ===================================================================================================================== Install 1 Package (+27 Dependent packages) Total download size: 3.3 M Installed size: 15 M
Update CertBot
# yum update --enablerepo epel-testing certbot Dependencies Resolved ================================================================================================================ Package Arch Version Repository Size ================================================================================================================ Updating: certbot noarch 0.11.1-2.el7 epel-testing 17 k Installing for dependencies: python2-future noarch 0.16.0-2.el7 epel 799 k Updating for dependencies: python2-acme noarch 0.11.1-1.el7 epel-testing 168 k python2-certbot noarch 0.11.1-2.el7 epel-testing 396 k Transaction Summary ================================================================================================================ Install ( 1 Dependent package) Upgrade 1 Package (+2 Dependent packages) Total download size: 1.3 M
Lexicon help
$ lexicon luadns --help usage: lexicon luadns [-h] [--name NAME] [--content CONTENT] [--ttl TTL] [--priority PRIORITY] [--identifier IDENTIFIER] [--auth-username AUTH_USERNAME] [--auth-token AUTH_TOKEN] {create,list,update,delete} domain {A,AAAA,CNAME,MX,NS,SOA,TXT,SRV,LOC} positional arguments: {create,list,update,delete} specify the action to take domain specify the domain, supports subdomains as well {A,AAAA,CNAME,MX,NS,SOA,TXT,SRV,LOC} specify the entry type optional arguments: -h, --help show this help message and exit --name NAME specify the record name --content CONTENT specify the record content --ttl TTL specify the record time-to-live --priority PRIORITY specify the record priority --identifier IDENTIFIER specify the record for update or delete actions --auth-username AUTH_USERNAME specify email address used to authenticate --auth-token AUTH_TOKEN specify token used authenticate
Install centos-release-openstack-ocata
# yum install centos-release-openstack-ocata Dependencies Resolved =========================================================================================================== Package Arch Version Repository Size =========================================================================================================== Installing: centos-release-openstack-ocata noarch 1-1.el7 extras 5.1 k Installing for dependencies: centos-release-ceph-jewel noarch 1.0-1.el7.centos extras 4.1 k centos-release-qemu-ev noarch 1.0-1.el7 extras 11 k centos-release-storage-common noarch 1-2.el7.centos extras 4.5 k centos-release-virt-common noarch 1-1.el7.centos extras 4.5 k Transaction Summary =========================================================================================================== Install 1 Package (+4 Dependent packages)