Personal tools
You are here: Home Web PKI LetsEncrypt Acme DNS-01 validation with LuaDNS for LetsEncrypt Certificates on CentOS v7.x

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.



Until May 2016, Certbot was named simply letsencrypt or letsencrypt-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.


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 an account for letencrypt. This will create a private key in the '/etc/letsencrypt/accounts' directory:

$ certbot register --agree-tos -m
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Starting new HTTPS connection (1):

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):

 - If you lose your account credentials, you can recover through
   e-mails sent to
 - 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 (

# 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 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

Description=Renew Let's Encrypt certificates

ExecStart=/bin/certbot renew --standalone --quiet

# cat > /etc/systemd/system/certbot-renew.timer <<EOF
Description=Daily renewal of Let's Encrypt's certificates

# twice a day, at 2AM/2PM
# Be kind to the Let's Encrypt servers: add a random delay of 0–3600 seconds



# systemctl enable certbot-renew.timer
# systemctl start certbot-renew.timer

Verify that the timer is setup with `systemctl list-timers`.



$ certbot certonly \
   --manual --manual-auth-hook=/usr/local/bin/    --manual-public-ip-logging-ok  \
   --text  --preferred-challenges dns 
   --rsa-key-size 4096  --staging 


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' (


# cd /usr/local/bin
# wget
# chmod +x

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:


  1.  Login to your Namecheap account.

  2.  Go to the Profile > Tools menu.

  3. Scroll down to the Business & Dev Tools section. Click MANAGE, next to Namecheap API Access.

  4. 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.





Install Certbot

# yum install certbot

Dependencies Resolved

 Package                              Arch                 Version                          Repository          Size
 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
 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

positional arguments:
                        specify the action to take
  domain                specify the domain, supports subdomains as well
                        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
 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)
Document Actions