acme_letsencrypt
acme-letsencrypt
Обзор
Это роль на чистом 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