Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save bamoo456/ce51c10a57b59c225023613f01d9d93e to your computer and use it in GitHub Desktop.
Save bamoo456/ce51c10a57b59c225023613f01d9d93e to your computer and use it in GitHub Desktop.
Setup automatic LetsEncrypt wildcard certificate renewal on Ubuntu server 18.04 with Namecheap

All credits go to by Bryan Roessler for his original post that I followed on how to setup LetsEncrypt wildcard certificate auto-renewal with Namecheap. I highly recommend you read his tutorial first and if you bump into issues, check out this gist next.

Unfortunately the original article is not up-to-date and doesn't have the option to leave comments so I can't communicate with the author for updates so I decided to write the updates in a Gist. I highlighted the sections that required an updated with Correction #:. I managed to get the correct setup with the help of the amazing guys at LetsEncrypt community. Here's the help thread.

Set up acme-dns

  1. Download acme-dns from https://github.com/joohoi/acme-dns/releases
  2. Move the binary somewhere sensible since we will be using a systemd service: sudo cp ~/downloads/acme-dns /usr/local/bin/acme-dns
  3. Make the necessary directories: sudo mkdir /etc/acme-dns/ /var/lib/acme-dns
  4. Make sure you’ve removed any existing _acme-challenge DNS records from your DNS host records
  5. Modify the provided config file like so:
[general]
listen = "public_server_IP:53"
protocol = "both"
domain = "acme.example.com"
nsname = "ns1.example.com"
nsadmin = "admin.example.com"
records = [
    "acme.example.com. A public_server_IP",
    "ns1.example.com. A public_server_IP",
    "acme.example.com. NS ns1.example.com.",
]
debug = false

[database]
engine = "sqlite3"
connection = "/var/lib/acme-dns/acme-dns.db"

[api]
api_domain = ""
ip = "127.0.0.1"
disable_registration = false
autocert_port = "80"
port = "9000"
tls = "none"
tls_cert_privkey = "/etc/tls/example.org/privkey.pem"
tls_cert_fullchain = "/etc/tls/example.org/fullchain.pem"
acme_cache_dir = "api-certs"
corsorigins = [
    "*"
]
use_header = false
header_name = "X-Forwarded-For"

[logconfig]
loglevel = "debug"
logtype = "stdout"
logformat = "text"

Correction 1: In Bryan's tutorial he configures the listen IP as :53, which prevents acme-dns from starting in my case. Having it set to local IP 127.0.0.1 caused it to be unreachable from outside, thus I set it to the public server IP.

  1. Open port 53: sudo ufw allow 53 && sudo ufw reload
  2. Move acme-dns.service file to /etc/systemd/system/acme-dns.service and remove the user and group
  3. Enable and start the service: sudo systemctl daemon-reload && sudo systemctl enable --now acme-dns.service
  4. Check that the service is running sudo systemctl status acme-dns
  5. Test that it is working curl http://localhost:9000/health if you get nothing, it means it works.

Configure Namecheap

  1. Configure Namecheap with an A record called ns1 pointing the public IP of the server running acme-dns
  2. Confgiure Namecheap with an NS record called acme pointing to ns1.example.com

Correction 2: Notice that unlike's Bryan's tutorial, I created a ns1 A record instead of ns1.acme which for some odd reason didn't work in my case.

Configuring the Certbot auth hook

  1. Install python2 requests: sudo apt-get install python-requests
  2. Acquire the acme-dns certbot hook file: sudo wget -O /etc/letsencrypt/acme-dns-auth.py https://raw.githubusercontent.com/joohoi/acme-dns-certbot-joohoi/master/acme-dns-auth.py
  3. Configure the program you just downloaded: sudo vim /etc/letsencrypt/acme-dns-auth.py and change ACMEDNS_URL = "http://localhost:9000"

Run Certbot

You will need to run certbot manually one time in order to be able to run certbot renew in the future to handle the certificate renewals manually. If you’ve followed the rest of this tutorial, go ahead and run certbot to acquire your certs:

sudo certbot certonly -d "*.<yoursite>.com" -d "<youresite>.com" \
--agree-tos --manual-public-ip-logging-ok \
--server https://acme-v02.api.letsencrypt.org/directory \
--preferred-challenges dns --manual \
--manual-auth-hook /etc/letsencrypt/acme-dns-auth.py \
--debug-challenges

When you run the command certbot will prompt you to add one more DNS CNAME record to your DNS host.

Example: _acme-challenge..com CNAME ch30791e-33f4-1af1-7db3-1ae95ecdde28.acme..com.

In Namecheap, create a new CNAME record named _acme-challenge and give it the value you got from certbot. In this example, it's ch30791e-33f4-1af1-7db3-1ae95ecdde28.acme.<yoursite>.com..

Wait a few minutes and hit to complete the ACME challenge and receive your certificates!

Correction 3: In Bryan's tutorial, he instructs us to add a CNAME record with name: \_acme-challenge, which I believe is an unintentional typo.

Auto renewal setup

Follow Bryan's tutorial from this point and on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment