OpenVPN: Let’s Encrypt DNS verification on AWS Route53 and OpenVPN Access Server SSL certificate auto update
Tags: openvpn, security, ssl, dns
Published: 2019-05-24 13:00:56

---
title: OpenVPN: Let’s Encrypt DNS verification on AWS Route53 and OpenVPN Access Server SSL certificate auto update
published: true
tags: OpenVPN,Security,SSL,DNS
canonical_url: https://rtfm.co.ua/en/openvpn-lets-encrypt-dns-verification-on-aws-route53-and-openvpn-access-server-ssl-certificate-auto-update/
---

![](https://rtfm.co.ua/wp-content/uploads/2014/07/openvpn-logo-1.png)In addition to the [OpenVPN: SSL and hostname configuration](https://rtfm.co.ua/en/openvpn-ssl-and-hostname-configuration/) post about OpenVPN Access Server, set up and configuration.

So, three months passed and it’s time to renew Let’s Encrypt SSL certificate (see. [Prometheus: Alertmanager и blackbox-exporter — проверка срока действия SSL и нотификация в Slack](https://rtfm.co.ua/prometheus-alertmanager-i-blackbox-exporter-proverka-sroka-dejstviya-ssl-i-notifikaciya-v-slack/), Rus).

I could use a well-know for me scheme with the webroot but OpenVPN AS accepts connections itself and there is no NGINX, and install it just for the webroot and Let’s Encrypt renewals – not too good idea.

Better let’s use DNS verification now.

### AWS IAM and certbot-user

We have our domains served by AWS Route53 so use [certbot-dns-route53](https://certbot-dns-route53.readthedocs.io/) here.

Get your zone ID:

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190524_131355.png "OpenVPN: Let's Encrypt DNS verification и обновление сертификата в OpenVPN Access Server")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190524_131355.png)

Create IAM-policy, in the `ChangeResourceRecordSets` set zone’s ID:

```
{
    "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/Z30***LB6"
            ]
        }
    ]
}
```

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190524_124141.png "OpenVPN: Let's Encrypt DNS verification и обновление сертификата в OpenVPN Access Server")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190524_124141.png)

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190524_124251.png "OpenVPN: Let's Encrypt DNS verification и обновление сертификата в OpenVPN Access Server")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190524_124251.png)_(later I thought that it could be a good idea to add zone name to the policy or user names to make them more descriptive, as zone/user has access to the only one zone here)_

Create a new user with the _Programmatic access_:

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190524_124410.png "OpenVPN: Let's Encrypt DNS verification и обновление сертификата в OpenVPN Access Server")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190524_124410.png)

In the _Permissions_ chose _Attach existing policies directly_ and attach policy created above:

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190524_124508.png "OpenVPN: Let's Encrypt DNS verification и обновление сертификата в OpenVPN Access Server")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190524_124508.png)

For testing – install `aws-cli`:

```
root@openvpnas2:~# apt -y install awscli
```

Under the _openvpnas_ user configure AWS CLI default-profile:

```
openvpnas@openvpnas2:~$ aws configure
AWS Access Key ID [None]: AKI***JEL
AWS Secret Access Key [None]: Lry***ide
Default region name [None]:
Default output format [None]: json
```

Check config:

```
root@openvpnas2:~# cat /home/openvpnas/.aws/config
[default]
output = json
```

OK – profile exists and it will be used later by the `certbot`.

To test access – try to get zones list:

```
openvpnas@openvpnas2:~$ aws route53 list-hosted-zones --output text
HOSTEDZONES     33C2D264-***-***-***-3052BEA607A9    /hostedzone/Z30***LB6      example.com. 103
...
```

All good here.

### certbot DNS verification

Install `certbot`:

```
openvpnas@openvpnas2:~$ sudo apt -y install certbot
```

And the Route53 plugin:

```
openvpnas@openvpnas2:~$ sudo apt -y install python3-certbot-dns-route53
```

Authorize and obtain the certificate:

```
root@openvpnas2:~# certbot certonly --dns-route53 -d vpn.example.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Found credentials in shared credentials file: ~/.aws/credentials
Plugins selected: Authenticator dns-route53, Installer None
Attempting to parse the version 0.31.0 renewal configuration file found at /etc/letsencrypt/renewal/vpn.example.com.conf with version 0.23.0 of Certbot. This might not work.
Cert is due for renewal, auto-renewing...
Renewing an existing certificate
Performing the following challenges:
dns-01 challenge for vpn.example.com
Waiting 10 seconds for DNS changes to propagate
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:

- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/vpn.example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/vpn.example.com/privkey.pem
...
```

Check the zone in the Route53 – `certbot` must create a TXT-record here which will be used for authorization, and `certbot` will update it with a new value on each renewal

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190524_131922.png "OpenVPN: Let's Encrypt DNS verification и обновление сертификата в OpenVPN Access Server")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190524_131922.png)

Check renewals config for this domain:

```
root@openvpnas2:~# cat /etc/letsencrypt/renewal/vpn.example.com.conf
renew_before_expiry = 30 days
...
Options used in the renewal process
[renewalparams]
authenticator = dns-route53
account = 6bc***4f6
installer = None
```

Then will be enough just to execute `certbot renew`.

### OpenVPN Access Server SSL update

To update SSL in the OpenVPN AS need to:

1. upload the domain's certificate:
`sacli --key "cs.cert" --value_file "/etc/letsencrypt/live/vpn.example.com/cert.pem" ConfigPut`
2. upload Let’s Encrypt's certificate:  
`sacli --key "cs.ca_bundle" --value_file "/etc/letsencrypt/live/vpn.example.com/chain.pem" ConfigPut`
3. upload our private key:  
`sacli --key "cs.priv_key" --value_file "/etc/letsencrypt/live/vpn.example.com/privkey.pem" ConfigPut`
4. and rstart OpenVPN server

Collect all of them in one bash-script which will be called later by `cron`.

Go to the OpenVPN scripts catalog:

```
root@openvpnas2:~# cd  /usr/local/openvpn_as/scripts/
```

Create a `ssl_renew.sh` script:

```
#!/usr/bin/env bash

SCRIPTS="/usr/local/openvpn_as/scripts/"

$SCRIPTS/sacli --key "cs.cert" --value_file "/etc/letsencrypt/live/vpn.example.com/cert.pem" ConfigPut
$SCRIPTS/sacli --key "cs.ca_bundle" --value_file "/etc/letsencrypt/live/vpn.example.com/chain.pem" ConfigPut
$SCRIPTS/sacli --key "cs.priv_key" --value_file "/etc/letsencrypt/live/vpn.example.com/privkey.pem" ConfigPut

$SCRIPTS/sacli start
```

Just in case – backup exisitng keys:

```
root@openvpnas2:/usr/local/openvpn_as/scripts# cp /usr/local/openvpn_as/etc/web-ssl/server.crt /usr/local/openvpn_as/etc/web-ssl/server.crt.OLD

root@openvpnas2:/usr/local/openvpn_as/scripts# cp /usr/local/openvpn_as/etc/web-ssl/server.key /usr/local/openvpn_as/etc/web-ssl/server.key.OLD
```

Run your new script:

```
root@openvpnas2:/usr/local/openvpn_as/scripts# ./ssl_renew.sh
[True, {}]
[True, {}]
[True, {}]
RunStart warm None
{
  "active_profile": "ProfileName",
  "errors": {},
  "service_status": {
    ...
    "web": "restarted"
  }
}

WILL_RESTART ['web', 'client']
```

Check in a browser:

[![](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190524_133817.png "OpenVPN: Let's Encrypt DNS verification и обновление сертификата в OpenVPN Access Server")](https://rtfm.co.ua/wp-content/uploads/2019/05/Screenshot_20190524_133817.png)

Then add a hook for `certbot` to run this script after renew.

Edit the `/etc/letsencrypt/renewal/vpn.example.com.conf` file:

```
...
[renewalparams]
authenticator = dns-route53
account = 6bc***4f6
installer = None
renew_hook = /usr/local/sbin/openvpnas_renewcerts.sh
```

And the last thing – add a crontask with `certbot renew`, execute `crontab -e`:

```
0 0 * * * /usr/bin/certbot renew &> /var/log/letsencrypt/letsencrypt.log
```

Done.

### Similar posts
 
- <small>02/26/2019</small> [OpenVPN: SSL and hostname configuration](https://rtfm.co.ua/en/openvpn-ssl-and-hostname-configuration/)<small> </small>  
 
- <small>02/22/2019</small> [OpenVPN: DNS and dnsmasq configuration](https://rtfm.co.ua/en/openvpn-dns-and-dnsmasq-configuration/)<small></small>