Using Certbot's Route53 DNS Validation

Certbot allows certificate requests to be validated against DNS records, which is incredibly handy for distributed systems like GeoJS. Being geo-routed (your request goes to the closest node) it's hard to tell where Let's Encrypt is going to end up. This makes the default HTTP proof difficult. GeoJS uses Route53 for DNS which thankfully has a python certbot package available for it.

I use the Certbot PPA repo for installation which works fine for most cases, but doesn't come bundled with Route53 support. Initially all I figured I'd have to do is pip install certbot_dns_route53 and I'd flying. The initial certificate requests via DNS worked well! Then this started appearing in my logs when it was trying to renew:

VersionConflict: (certbot 0.19.0 (/usr/lib/python2.7/dist-packages), Requirement.parse('certbot==0.20.0')

Since the renewal used systemd timers I never received email notifications that they were failing, I had to rely on my nagios monitoring to tell me my certs were nearing expiry. Thanks systemd, mad props for that one.

The fix was easy since it was just a version mismatch. The latest version for both certbot and certbot_dns_route53 was 0.20.0 at the time, but my apt installed certbot was at 0.19.0. All I had to do was reinstall certbot_dns_route53 at 0.19.0.

pip install certbot_dns_route53==0.19.0

Full Example

First things first, you need to create a AWS IAM user with permission to create records under the domain you want to validate. An example policy for the user is below:

{
    "Version": "2012-10-17",
    "Id": "certbot-dns-route53 sample policy",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "route53:ListHostedZones",
                "route53:GetChange"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect" : "Allow",
            "Action" : [
                "route53:ChangeResourceRecordSets"
            ],
            "Resource" : [
                "arn:aws:route53:::hostedzone/YOURHOSTEDZONEID"
            ]
        }
    ]
}

Now create a key pair for the user and put it in ~/.aws/credentials.

[default]
aws_access_key_id=afasf
aws_secret_access_key=RFHt/asfasfasfasfasf

Check your currently installed version of certbot and install the same version of certbot_dns_route53 via pip:

$ dpkg -s certbot | grep -i version
Version: 0.19.0-1+ubuntu16.04.1+certbot+1
$ pip install certbot_dns_route53==0.19.0

Now you're good to register!

$ certbot certonly --dns-route53 -d your-domain.rocks --post-hook "/bin/systemctl nginx reload"

Photo by Benjamin Bortels on Unsplash.

James Loh

I'm a Sysadmin for a web solutions company deploying clouds across the globe. I learn new things every day.

Australia @itsjloh jloh jloh