letsencrypt

Ansible роль для получения SSL сертификатов Let's Encrypt

Интеграция Ansible Galaxy

Эта роль предназначена для запроса SSL сертификатов от Let's Encrypt, используя HTTP или DNS challenge для их ACME API.

Возможности:

  • Устанавливает и настраивает certbot и вспомогательный скрипт для DNS challenge
  • Поддерживает как HTTP, так и DNS challenge
    • Для HTTP challenge поддерживаются плагины аутентификации apache, nginx, standalone и webroot
  • DNS challenge использует отдельную зону только для токенов ACME challenge, что снижает риски безопасности от динамических обновлений
  • Перезапуск служб при обновлении сертификата с использованием пост-хуков или пользовательской команды пост-хука
  • Управление доступом к сертификатам с помощью специальной системной группы

Поддерживаемые дистрибутивы:

  • Debian 11 (Bullseye)
  • Debian 12 (Bookworm)

Тестировалось на:

  • Debian 11 (Bullseye)
  • Debian 12 (Bookworm)
  • CentOS7
  • Ubuntu 2204 (Jammy Jellyfish)

Роль выполняет следующее:

  • Когда letsencrypt_setup равно True (по умолчанию), эта роль будет:

    • Устанавливать certbot
    • Регистрировать учетную запись в Let's Encrypt
    • Устанавливать необходимые файлы/ключи для DNS challenge
    • Создавать системную группу 'letsencrypt'
  • Когда вызывается с заполненной переменной 'letsencrypt_cert':

    • Запрашивает SSL сертификат через Let's Encrypt ACME API, используя либо HTTP challenge, либо DNS challenge
    • По желанию устанавливает пост-хук для обновления сертификата (для перезапуска необходимых служб после этого)
    • По желанию добавляет системных пользователей в группу 'letsencrypt', чтобы предоставить им доступ к сертификатам SSL и их закрытым ключам

Как это работает (примеры)

  • Установка certbot ansible-playbook site.yml -l localhost -t letsencrypt
  • Создание сертификата через HTTP challenge и аутентификатор webroot (перезапуск службы 'apache2' при обновлении): ansible-playbook site.yml -l localhost -t letsencrypt -e '{"letsencrypt_cert":{"name":"sub.example.org","domains":["sub.example.org"],"challenge":"http","http_auth":"webroot","webroot_path":"/var/www/sub.example.org","services":["apache2"]}}'
  • Создание сертификата через DNS challenge (предоставление доступа к сертификатам пользователю 'Debian-exim', перезапуск служб 'exim4' и 'dovecot' при обновлении): ansible-playbook site.yml -l localhost -t letsencrypt -e '{"letsencrypt_cert":{"name":"sub2","domains":["sub2.example.org","sub2.another.example.org"],"challenge":"dns","services":["dovecot","exim4"],"users":["Debian-exim"]}}'
  • Создание сертификата через HTTP challenge и аутентификатор standalone (повторное использование того же закрытого ключа при обновлении и выполнение пользовательского скрипта пост-хука при обновлении): ansible-playbook site.yml -l localhost -t letsencrypt -e '{"letsencrypt_cert":{"name":"sub3","domains":["sub3.example.org"],"challenge":"http","http_auth":"standalone","reuse_key":True,"post_hook":"/usr/local/bin/cert-post-hook.sh"}}'

Ожидаемая структура переменной letsencrypt_cert

Переменная letsencrypt_cert ожидается как словарь:

letsencrypt_opts_extra: "--register-unsafely-without-email"
letsencrypt_cert:
  name: sub.example.org
  domains:
    - sub.example.org
  challenge: http
  http_auth: webroot
  webroot_path: /var/www/sub.example.org
  services:
    - apache2

или:

letsencrypt_cert:
  name: sub2
  domains:
    - sub2.example.org
    - sub2.another.example.org
  challenge: dns
  services:
    - dovecot
    - exim4
  users:
    - Debian-exim

или:

letsencrypt_cert:
  name: sub3
  domains:
    - sub3.example.org
  challenge: http
  http_auth: standalone
  reuse_key: True
  post_hook: "/usr/local/bin/cert-post-hook.sh"
letsencrypt_cert:
  name: sub3
  domains:
    - sub3.example.org
  challenge: http
  http_auth: standalone
  reuse_key: True
  deploy_hook: "/usr/local/bin/cert-post-hook.sh"

Словарь поддерживает следующие ключи:

  • name: имя сертификата [опционально]
  • domains: список доменов для сертификата [обязательно]
  • challenge: 'http' или 'dns' [обязательно]
    • для challenge 'http': http_auth: 'webroot', 'apache' или 'nginx' [опционально, по умолчанию 'webroot']
      • для http_auth 'webroot': webroot_path [опционально, по умолчанию '/var/www']
  • services: список служб для перезапуска в пост-хуке [опционально]
  • reuse_key: Повторное использование того же закрытого ключа при обновлении сертификата. 'True' или 'False' (по умолчанию 'False')
  • post_hook: Пользовательский пост-хук, который будет выполнен после попытки получить/обновить сертификат [опционально]
  • deploy_hook: Пользовательский деплой-хук, который будет выполнен после успешной попытки получить/обновить сертификат [опционально]
  • renew_hook: Пользовательский хук для обновлений, который будет выполнен один раз для каждого обновленного сертификата после обновления [опционально]
  • users: список пользователей для добавления в системную группу 'letsencrypt' [опционально]

Общие предварительные требования

Роль заботится о установке certbot и запросе SSL сертификатов, используя либо HTTP, либо DNS challenge. Она не устанавливает и не настраивает необходимую инфраструктуру (например, веб-сервер Apache или DNS сервер).

Роль протестирована только с Ansible 2.2. Нет гарантии, что она будет работать с более ранними версиями Ansible.

HTTP challenge

Требования:

  • Доменное имя(я) запрашиваемого сертификата должно указывать на систему
  • Для http_auth 'apache' на системе должен быть установлен (и настроен) Apache2
  • Для http_auth 'nginx' на системе должен быть установлен (и настроен) NGINX

DNS challenge

Требования:

  • DNS сервер с отдельной зоной, используемой только для ACME DNS challenge. Эта зона должна разрешать динамические обновления DNS (NSUPDATE) для TXT записей (см. ниже).
  • CNAME записи для _acme-challenge.sub.example.org для всех доменных имен(ий) запрашиваемого сертификата должны указывать на sub.example.org._le.example.org (внутри отдельной зоны для ACME DNS challenge).
  • Содержимое ключа обновления DNS и закрытые ключи DNS обновления должны быть доступны в переменных Ansible letsencrypt_ddns_key и letsencrypt_ddns_privkey (предпочтительно внутри хранилища).

Эта роль устанавливает вспомогательный скрипт для DNS challenge в /usr/local/bin/certbot-dns-hook.sh. Этот скрипт добавит токен валидации в TXT запись на sub.example.org._le.example.org во время DNS challenge и удалит его после.

Поддержка подстановочных знаков с DNS challenge

Получение сертификатов с подстановочными знаками должно работать «из коробки» через DNS challenge.

Настройка bind9 для DNS challenge

(Другой вариант — использовать acme-dns сервер для этого)

Сгенерируйте ключ для динамических обновлений:

cd /etc/bind/keys
dnssec-keygen -a HMAC-SHA512 -b 512 -n USER _le.example.org_ddns_update
chown -R bind:bind /etc/bind/keys

Добавьте ключ в конфигурацию bind (например, в /etc/bind/named.conf.options):

key "_le.example.org_ddns_update" {
    algorithm hmac-sha512;
    secret "...";
};

Создайте зону для динамических обновлений:

$ORIGIN .
$TTL 86400	; 1 день
_le.example.org		IN SOA	ns1.example.org. postmaster.example.org. (
                2017061501 ; серийный номер
                86400      ; обновление (1 день)
                3600       ; повтор (1 час)
                2419200    ; срок действия (4 недели)
                86400      ; минимальный (1 день)
                )
            NS	ns1.example.org.
            NS	ns2.example.org.
            TXT	"v=spf1 -all"

и настройте ее в вашей конфигурации bind (например, в /etc/bind/named.conf.local):

zone "_le.example.org" {
    type master;
    file "/etc/bind/zones/db._le.example.org";
    update-policy { grant _le.example.org_ddns_update wildcard *._le.example.org. TXT; };
};

Формат для /etc/letsencrypt/keys/ddns_update.key (из bind):

key "<key>" {
    algorithm HMAC-SHA512;
    secret "<key>";
};

Формат для /etc/letsencrypt/keys/ddns_update.private:

Private-key-format: v1.3
Algorithm: 165 (HMAC_SHA512)
Key: <key>
Bits: AAA=
Создан: 20181017144534
Опубликован: 20181017144534
Активирован: 20181017144534

Значения переменных Ansible по умолчанию

# Выполнить шаг настройки; установить false для отключения
letsencrypt_setup: True

# Предоставить существующие учетные данные для копирования
letsencrypt_account: ""
# letsencrypt_account:
#   hash: 1234567890abcdef1234567890abcdef
#   id: 123456789
#   creation_host: localhost
#   creation_dt: 2020-12-13T13:12:00Z
#   private_key:
#     n: 1234
#     e: 5678
#     d: 90ab
#     p: cdef
#     q: 1234
#     dp: 5678
#     dq: 90ab
#     qi: cdef
#     kty: RSA

# Установить адрес электронной почты, связанный с учетной записью Let's Encrypt
letsencrypt_account_email: ""

# Аутентификатор по умолчанию для HTTP challenge ('webroot' или 'apache')
letsencrypt_http_auth: webroot

# Путь к веб-корню для аутентификатора 'webroot'
letsencrypt_webroot_path: /var/www

# Установить вспомогательный скрипт для DNS challenge и ключ обновления DNS
letsencrypt_dns_challenge: yes

# Настройки для динамических обновлений зоны DNS
# letsencrypt_ddns_server: ""
# letsencrypt_ddns_zone: ""
# letsencrypt_ddns_key: ""
# letsencrypt_ddns_privkey: ""

# Создание системной группы 'letsencrypt' для доступа к сертификатам
letsencrypt_group: yes

# Повторное использование закрытого ключа при обновлении сертификата?
letsencrypt_reuse_key: False

# Разрешить подмножество имен?
letsencrypt_subset_names: True

# Установить глобальные дополнительные параметры командной строки для certbot
letsencrypt_opts_extra: ""

# Установить путь для каталога letsencrypt (без завершающего "/" !!)
letsencrypt_directory: /etc/letsencrypt

Тестирование

В целях тестирования переменная letsencrypt_test может быть установлена. Если она установлена в True, роль будет использовать тестовые серверы Let's Encrypt для создания учетной записи и получения сертификата.

Для разработки и тестирования роли мы используем Molecule и Vagrant/Github Actions. В локальной среде вы можете легко протестировать роль с помощью

molecule test

Лицензия

Эта Ansible роль лицензирована под GNU GPLv3.

Автор

Авторские права 2017-2019 systemli.org (https://www.systemli.org/)

О проекте

Role to obtain Let's Encrypt SSL certificates

Установить
ansible-galaxy install systemli/ansible-role-letsencrypt
Лицензия
gpl-3.0
Загрузки
25155
Владелец
Your friendly tech collective