acme_letsencrypt

acme-letsencrypt

CI release Ansible Galaxy

Обзор

Это роль на чистом Ansible для достижения следующих целей:

  • Создание ECC или RSA закрытых ключей
  • Генерация запросов на подпись сертификатов (для нескольких доменов)
  • Отправка запроса в Let's Encrypt или другого провайдера ACME на ваш выбор
  • Установка всех файлов в определенном месте

Я написал эту роль, чтобы получить сертификаты Let's Encrypt, не полагаясь на сторонние инструменты (такие как certbot, acme-tiny, acme.sh и т.д.) и иметь больше контроля над процессом.

В настоящее время поддерживается только тип Challenge HTTP.

Так как это просто роль Ansible, она не обрабатывает автоматическое продление сертификатов. Для этого вы можете периодически запускать эту роль из вашего CI/CD пайплайна или использовать ее в режиме Ansible Pull с crontab.

Версия Ansible

Эта роль, начиная с версии 2.0.0, гарантированно совместима только с Ansible >=2.10.

Если вам нужна совместимость с <2.10 (т.е. "предколлекции"), используйте любую версию с тегом 1.x.x.

Требования

На целевом хосте:

  • openssl

Примеры плейбуков

Используя ключ secp384r1 ECC для сертификата SAN (несколько доменов).

- name: "Получить сертификаты для webserver01"
  hosts: webserver01
  become: true
  roles:
    - dhach.acme_letsencrypt
  vars:
    le_base_directory: /etc/letsencrypt
    le_certificates:
      - name: ecc.example.com
        domains:
          - secp.example.com
          - ecc.example.com
        key:
          curve: secp384r1

Теперь используем ключ secp256r1, заставляя его пересоздаться, и затем отправим запрос на сервер проверки Let's Encrypt:

- name: "Получить сертификаты для webserver02"
  hosts: webserver02
  become: true
  roles:
    - dhach.acme_letsencrypt
  vars:
    le_acme_directory: https://acme-v02.api.letsencrypt.org/directory
    le_certificates:
      - name: another-domain.example.com
        domains:
          - another-domain-abc.example.com
          - another-domain-def.example.com
          - another-domain-ghi.example.com
          - another-domain-jkl.example.com
          - another-domain-mno.example.com
        ssl:
          type: ECC
          curve: secp256r1
          renew: true

Или используйте ключи RSA для получения одного сертификата для домена:

- name: "Получить сертификаты для webserver03"
  hosts: webserver03
  become: true
  roles:
    - dhach.acme_letsencrypt
  vars:
    le_certificates:
      - name: example.com
        domains:
          - foo.example.com
        key:
          type: RSA
          size: 4096
      - name: more.example.com
        domains:
          - bar.example.com
        key:
           type: RSA
           size: 4096

Где найти файлы

Все сгенерированные ключи, запросы сертификатов и последующие сертификаты можно найти по следующему пути: {{ le_base_directory }}/{{ le_certificates['name'] }}.

Например, если вы укажете name как 'example.com', а le_base_directory будет установлен на '/etc/letsencrypt/', результат будет:

/etc/letsencrypt/example.com/
├── domain.csr
├── domain.key
├── domain.pem
├── fullchain.pem
└── intermediate.pem

Как настроить ваш веб-сервер

Серверы ACME требуют, чтобы вы ответили на задачу, поместив файл с конкретным именем и содержанием в заранее определенный путь, который ваш веб-сервер обслуживает через HTTP.

Ваш веб-сервер должен обслуживать местоположение /.well-known/acme-challenge с содержимым следующего каталога: {{ le_base_directory }}/.well-known/acme-challenge/.

Примеры, если используется значение по умолчанию для le_base_directory:

Nginx:

location /.well-known/acme-challenge {
    alias /etc/letsencrypt/.well-known/acme-challenge/;

}

Apache:

Alias /.well-known/acme-challenge/ "/etc/letsencrypt/.well-known/acme-challenge/"
<Directory "/etc/letsencrypt/.well-known/acme-challenge/">
    AllowOverride None
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
    Require method GET POST OPTIONS
</Directory>

Переменные роли и значения по умолчанию

Все определенные переменные перечислены ниже с их значениями по умолчанию.

Запросы сертификатов

Вы можете контролировать, для каких доменов должен запрашиваться сертификат. Также у вас есть возможность указать детали, касающиеся генерации ключа. Варианты немного отличаются между ключами RSA и ECC.

Все запросы сертификатов формируются как SAN (SubjectAltName) запросы.

ECC:

le_certificates:
  - name: example.com  # фактически внутренний идентификатор и место для сохранения файла
    domains:  # список доменов, для которых вы хотите получить сертификат
      - foo.example.com
      - bar.example.com
    key:  # детали для закрытого ключа, если он будет сгенерирован
      type: ECC  # (обязательный) Поддерживаемые типы: ECC, RSA
      curve: secp384r1  # (необязательный | по умолчанию: secp384r1) Кривая для ECC ключа (не влияет на RSA ключи).
      renew: false  # (необязательный | по умолчанию: false) Нужно ли принудительно пересоздавать ключ. Всегда будет сохраняться резервная копия.

RSA:

le_certificates:
  - name: example.com  # фактически внутренний идентификатор и место для сохранения файла
    domains:  # список доменов, для которых вы хотите получить сертификат
      - foo.example.com
      - bar.example.com
    key:  # детали для закрытого ключа, если он будет сгенерирован
      type: RSA  # (обязательный) Поддерживаемые типы: ECC, RSA
      size: 4096  # (необязательный | по умолчанию :4096) Длина RSA ключа (не влияет на ECC ключи)
      renew: false  # (необязательный | по умолчанию: false) Нужно ли принудительно пересоздавать ключ. Всегда будет сохраняться резервная копия.

Каталоги и разрешения

le_base_directory: Основной каталог, где будут храниться все сгенерированные файлы (по умолчанию: /etc/letsencrypt)

le_files_owner: Кто должен владеть сгенерированными файлами и папками (по умолчанию: root)

le_files_group: Какой группе должны принадлежать сгенерированные файлы и папки (по умолчанию: root)

Ключ учетной записи Let's Encrypt

le_account_key_path: Где поместить (или найти) ключ учетной записи Let's Encrypt (по умолчанию: "{{ le_base_directory }}/account.key")

le_account_key_type: Какой тип ключа (RSA, ECC) использовать для ключа учетной записи (по умолчанию: RSA)

le_account_key_size: Размер ключа. Только для ключей RSA. (по умолчанию: 4096)

le_account_key_curve: Какую кривую использовать. Только для ключей ECC, не влияет на ключи RSA. (по умолчанию: secp384r1)

le_account_key_regenerate: Нужно ли регенерировать существующий ключ или нет. Будет храниться резервная копия. (по умолчанию: false)

К сожалению, Let's Encrypt не поддерживает ключи учетной записи ECC. Лучше оставить на RSA 4096.

Версия Let's Encrypt / ACME и каталог

le_acme_version: Версия ACME, которую нужно использовать. Может быть необходимо, если вы решите использовать другого поставщика, кроме Let's Encrypt (по умолчанию: 2)

le_acme_directory: URL-адрес каталога ACME для запроса сертификатов. По соображениям безопасности, по умолчанию установлен каталог тестирования Let's Encrypt (по умолчанию: https://acme-staging-v02.api.letsencrypt.org/directory)

Производственный каталог Let's Encrypt: https://acme-v02.api.letsencrypt.org/directory.

le_renew_if_invalid_after: Попробовать продлить сертификаты, если они действительны менее чем на это количество дней (по умолчанию: 30)

le_force_renew: попытка принудительного продления сертификатов (по умолчанию: false)

le_csr_only: Если вы хотите только сгенерировать закрытые ключи и CSRs, установите это значение в true. Это может быть полезно для отладки. (по умолчанию: false)

Участие и проблемы

Все взносы приветствуются. Не стесняйтесь открывать проблемы или создавать запросы на изменение.

Я с радостью рассмотрю любую поднятую проблему и всегда стараюсь улучшить роль.

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

Все тесты проводятся с помощью Molecule.

CI пайплайн реализован с помощью GitHub Actions и использует стратегию матрицы, которая тестирует на Ubuntu, Debian и CentOS.

Чтобы начать локальное тестирование, настройте локальную Python venv, установите все зависимости и запустите тесты. Это требует установленного Docker на вашем компьютере (или использования Docker-Machine):

python3 -m venv venv
source venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -r test-requirements.txt

molecule test

Так как эта роль, по сути, требует отправления запросов на сервер ACME, и, следовательно, требует контроля над доменом, для которого нужно динамически установить запись DNS, тестирование ограничено линтингом, проверкой создания ключей и CSRs, и если они содержат ожидаемое содержание.

Полное тестирование роли со всеми функциями проводится на тестовом сервере Let's Encrypt на реальной, подключенной к Интернету машине, но вручную.

Лицензия

GNU General Public License v3.0

О проекте

Requests certificates from Let's Encrypt (or another ACME server)

Установить
ansible-galaxy install dhach/ansible-role-acme-letsencrypt
Лицензия
gpl-3.0
Загрузки
91
Владелец