В продолжение темы об установке и настройке OpenVPN Access Server, см. OpenVPN: настройка SSL и hostname.
Прошло три месяца, строк действия сертификата от Let’s Encrypt закончился, надо его обновить (см. Prometheus: Alertmanager и blackbox-exporter — проверка срока действия SSL и нотификация в Slack).
Можно было бы использовать привычную мне схему с webroot, но OpenVPN AS сам принимает подключения — NGINX тут нет, а устанавливать NGINX чисто ради Let’s Encrypt верификацию через webroot — так себе идея.
Сделаем по другому: используем DNS-авторизацию.
Содержание
AWS IAM и certbot-пользователь
У нас домен обслуживается AWS Route53 — используем плагин certbot-dns-route53.
Получаем ID зоны:
Создаём IAM-policy, в ChangeResourceRecordSets указываем 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"
]
}
]
}
(уже позже подумал, что каждая политика создаётся на отдельную зону, потому в имени политики лучше добавлять имя домена, и если пользователей создавать отдельных — то тоже указывать имя домена, к которому есть доступ)
Создаём юзера c Programmatic access:
В Permissions выбираем Attach existing policies directly, и подключаем созданную политику:
Для проверки — устанавливаем aws-cli:
[simterm]
root@openvpnas2:~# apt -y install awscli
[/simterm]
Под пользователем openvpnas настраиваем default-профайл:
[simterm]
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
[/simterm]
Проверяем конфиг:
[simterm]
root@openvpnas2:~# cat /home/openvpnas/.aws/config [default] output = json
[/simterm]
Профиль есть, настроен. Далее его будет использовать certbot.
Для проверки прав доступа — пробуем получить зону:
[simterm]
openvpnas@openvpnas2:~$ aws route53 list-hosted-zones --output text HOSTEDZONES 33C2D264-C922-FCDE-8654-3052BEA607A9 /hostedzone/Z30KLN6M3D0LB6 example.com. 103 ...
[/simterm]
Окей.
certbot DNS verification
Устанавливаем certbot:
[simterm]
openvpnas@openvpnas2:~$ sudo apt -y install certbot
[/simterm]
И сам плагин:
[simterm]
openvpnas@openvpnas2:~$ sudo apt -y install python3-certbot-dns-route53
[/simterm]
Авторизируемся, и получаем сертификат:
[simterm]
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 ...
[/simterm]
Проверяем зону в Route53 — certbot создал TXT-запись, которая используется ддля авторизации, и далее certbot будет обновлять её каждые три месяца:
Проверяем конфиг для обновлений:
[simterm]
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
[/simterm]
Для обновления — достаточно вызвать certbot renew.
OpenVPN Access Server SSL update
Для обновления сертификата в OpenVPN AS потребуются:
- загрузить сертификат:
sacli --key "cs.cert" --value_file "/etc/letsencrypt/live/vpn.example.com/cert.pem" ConfigPut - загрузить сертификат Let’s Ecnrypt:
sacli --key "cs.ca_bundle" --value_file "/etc/letsencrypt/live/vpn.example.com/chain.pem" ConfigPut - и загрузить приватный ключ нашего сертификата:
sacli --key "cs.priv_key" --value_file "/etc/letsencrypt/live/vpn.example.com/privkey.pem" ConfigPut - перезагрузить OpenVPN сервер
Соберём все команды в скрипт, который потом будем вызывать из cron.
Переходим в каталог скриптов OpenVPN:
[simterm]
root@openvpnas2:~# cd /usr/local/openvpn_as/scripts/
[/simterm]
Создаём скрипт ssl_renew.sh:
#!/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
Чисто на всякий случай — бекапим текущие ключи:
[simterm]
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
[/simterm]
Запускаем скрипт для проверки:
[simterm]
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']
[/simterm]
Проверяем в браузере:
Далее, добавляем хук для certbot, что бы он вызывал скрипт после обновления сертификата.
Редактируем /etc/letsencrypt/renewal/vpn.example.com.conf:
... [renewalparams] authenticator = dns-route53 account = 6bc***4f6 installer = None renew_hook = /usr/local/sbin/openvpnas_renewcerts.sh
И последним шагом — добавляем вызов certbot в cron — вызываем crontab -e:
0 0 * * * /usr/bin/certbot renew &> /var/log/letsencrypt/letsencrypt.log
Готово.










