felixfontein.acme_certificate
acme_certificate 1.1.1
ЭТА РОЛЬ УСТАРЕЛА! ПОЖАЛУЙСТА, ИСПОЛЬЗУЙТЕ КОЛЛЕКЦИЮ ВМЕСТО НЕЙ!
Эта роль позволяет получать сертификаты от Let's Encrypt с минимальным взаимодействием с веб-сервером. Большая часть кода выполняется на контроллере, а ключ учетной записи никогда не отправляется на узлы.
Роль можно установить через Ansible Galaxy:
ansible-galaxy install felixfontein.acme_certificate
Изменения в этой роли можно просмотреть в журнале изменений.
Описание
Это роль Ansible, которая может использовать любой ЦС, поддерживающий протокол ACME, такой как Let's Encrypt или Buypass, для выпуска TLS/SSL сертификатов для вашего сервера. Эта роль требует Ansible 2.8.3 или новее и основана на модуле acme_certificate, который идет с Ansible.
Основное преимущество этого подхода в том, что почти никакой код не выполняется на вашем веб-сервере: только если вы используете HTTP-челленджи, файлы нужно копировать на ваш веб-сервер, а затем удалять с него. Все остальное выполняется на вашем локальном компьютере!
(Это не включает установку сертификатов, вам нужно сделать это самостоятельно в другой роли.)
Требования
Требуется библиотека Python cryptography установлена на контроллере, доступная для версии Python, используемой для выполнения плейбука. Если cryptography
не установлена, достаточно новая версия PyOpenSSL в настоящее время поддерживается в качестве запасного варианта для модулей Ansible openssl_privatekey
и openssl_csr
.
Также должен быть доступен двоичный файл openssl
в исполняемом пути на контроллере. Он нужен модулю acme_certificate
в случае, если cryptography
не установлена, и используется для проверки цепочки сертификатов.
Если используются DNS-челленджи, могут быть другие требования в зависимости от DNS-поставщика. Например, для Amazon Route 53, модуль Ansible route53
требует пакет Python boto
.
Настройка ключа учетной записи
Вы можете создать ключ учетной записи с использованием двоичного файла openssl
следующим образом:
# RSA 4096 битный ключ
openssl genrsa 4096 -out keys/acme-account.key
# ECC 256 битный ключ (P-256)
openssl ecparam -name prime256v1 -genkey -out keys/acme-account.key
# ECC 384 битный ключ (P-384)
openssl ecparam -name secp384r1 -genkey -out keys/acme-account.key
С помощью Ansible вы можете использовать модуль openssl_privatekey
следующим образом:
- name: Генерация RSA 4096 ключа
openssl_privatekey:
path: keys/acme-account.key
type: RSA
size: 4096
- name: Генерация ECC 256 битного ключа (P-256)
openssl_privatekey:
path: keys/acme-account.key
type: ECC
curve: secp256r1
- name: Генерация ECC 384 битного ключа (P-384)
openssl_privatekey:
path: keys/acme-account.key
type: ECC
curve: secp384r1
Убедитесь, что вы надежно храните ключ учетной записи. В отличие от частных ключей сертификатов, нет необходимости часто его регенерировать, и это делает аннулирование сертификатов, выданных с его помощью, очень простым.
Переменные роли
Обратите внимание, что с мая 2020 года все переменные должны начинаться с acme_certificate_
. В течение некоторого времени модуль все еще будет использовать старые (короткие) имена переменных, если более длинные не определены. Пожалуйста, обновите использование вашей роли как можно скорее.
Это основные переменные:
acme_certificate_acme_account
: Путь к закрытому ключу ACME. Обязательно всегда указывать.acme_certificate_acme_email
: Ваш адрес электронной почты, который будет связан с учетной записью ACME. Обязательно всегда указывать.acme_certificate_algorithm
: Алгоритм, используемый для создания закрытых ключей. По умолчанию"rsa"
; другие варианты —"p-256"
,"p-384"
или"p-521"
для эллиптических кривых NISTprime256v1
,secp384r1
иsecp521r1
, соответственно.acme_certificate_key_length
: Длина ключа в битах для RSA закрытых ключей. По умолчанию 4096.acme_certificate_key_name
: Основное имя для хранения ключей и сертификатов. По умолчанию это первый указанный домен, где*
заменяется на_
.acme_certificate_keys_path
: Где хранятся ключи и сертификаты. Значение по умолчанию —"keys/"
.acme_certificate_keys_old_path
: Куда должны быть скопированы старые ключи и сертификаты; используется в случае, еслиacme_certificate_keys_old_store
истинно. Значение по умолчанию —"keys/old/"
.acme_certificate_keys_old_store
: Если установлено вtrue
, будут сделаны копии старых ключей и сертификатов. Копии будут храниться в директории, указанной вacme_certificate_keys_old_store
. Значение по умолчанию —false
.acme_certificate_keys_old_prepend_timestamp
: Следует ли добавлять текущую дату и время к копиям старых ключей и сертификатов. Значение по умолчанию —false
.acme_certificate_ocsp_must_staple
: Требуется ли сертификат с расширением OCSP Must Staple. Значение по умолчанию —false
.acme_certificate_agreement
: Документ условий обслуживания, с которым пользователь согласен. Значение по умолчанию —https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
.acme_certificate_acme_directory
: ACME каталог для использования. По умолчаниюhttps://acme-v02.api.letsencrypt.org/directory
, что является текущей производственной конечной точкой ACME v2 от Let's Encrypt.acme_certificate_acme_version
: Версия каталога ACME. Значение по умолчанию — 2. Используйте 1 для ACME v1.acme_certificate_challenge
: Тип челленджа, который нужно использовать. Должен бытьhttp-01
для HTTP челленджей (необходим доступ к веб-серверу) илиdns-01
для DNS челленджей (необходим доступ к DNS-поставщику).acme_certificate_root_certificate
: Корневой сертификат для каталога ACME. Значение по умолчанию —https://letsencrypt.org/certs/isrgrootx1.pem
для корневого сертификата Let's Encrypt.acme_certificate_deactivate_authzs
: Следует ли деактивироватьauthz
(авторизации) после этого. Значение по умолчанию —true
. Установите вfalse
, чтобы иметь возможность повторно использоватьauthz
.acme_certificate_modify_account
: Следует ли создать учетную запись ACME (если она не существует) и обновить контактные данные (адрес электронной почты). Значение по умолчанию —true
. Установите вfalse
, если вы хотите использовать модульacme_account
для управления своей учетной записью ACME (это не делает эта роль).acme_certificate_privatekey_mode
: Какой режим файла использовать для файла закрытого ключа. Значение по умолчанию —"0600"
, что означает, что он доступен для чтения и записи только владельцу, но не доступен другим (за исключением, возможно,root
).acme_certificate_select_chain
: (Доступно только для Ansible 2.10+) Должен быть в формате, описанном здесь. Позволяет выбрать используемую цепочку сертификатов;acme_certificate_root_certificate
должен использоваться совместно. Например, это можно использовать с Let's Encrypt, чтобы выбрать, какой корневой сертификат использовать.
HTTP-челленджи
Для HTTP челленджей следующие переменные определяют, как челленджи могут быть размещены на (удаленном) веб-сервере:
acme_certificate_server_location
: Локация, откуда будет обслуживаться.well-known/acme-challenge/
. По умолчанию/var/www/challenges
.acme_certificate_http_become
: Аргумент дляbecome:
для задачfile
иcopy
. Значение по умолчанию —false
.acme_certificate_http_challenge_user
: Пользователь, которому принадлежат файлыChallenge. Значение по умолчанию —root
.acme_certificate_http_challenge_group
: Группа, которой принадлежат файлыChallenge. Значение по умолчанию —http
.acme_certificate_http_challenge_folder_mode
: Режим, который следует использовать для папки челленджей. Значение по умолчанию —0750
(восьмеричный).acme_certificate_http_challenge_file_mode
: Режим, который следует использовать для файлов челленджей. Значение по умолчанию —0640
(восьмеричный).
Следующий подраздел показывает, как настроить nginx для HTTP челленджей. Настройка других веб-серверов может быть выполнена аналогичным образом.
Настройка Nginx
Предположим, что для одного из ваших защищенных доменов TLS/SSL вы используете перенаправление HTTP на HTTPS. Предположим, что оно выглядит так:
server {
listen example.com:80;
server_name example.com *.example.com;
return 301 https://www.example.com$request_uri;
}
Чтобы позволить роли acme_certificate
разместить что-то на http://*.example.com/.well-known/acme-challenge/
, вы можете изменить это на:
server {
listen example.com:80;
server_name example.com *.example.com;
location /.well-known/acme-challenge/ {
alias /var/www/challenges/;
try_files $uri =404;
}
location / {
return 301 https://www.example.com$request_uri;
}
}
С этой конфигурацией nginx все остальные URL на *.example.com
и example.com
по-прежнему перенаправляются, в то время как все, что в *.example.com/.well-known/acme-challenge/
, обслуживается из /var/www/challenges
. При изменении расположения /var/www/challenges
также необходимо изменить acme_certificate_server_location
.
Вы даже можете улучшить это, перенаправляя все URL в *.example.com/.well-known/acme-challenge/
, которые не соответствуют действительному файлу в /var/www/challenges
, на ваш HTTPS-сервер. Один из способов сделать это:
server {
listen example.com:80;
server_name example.com *.example.com;
location /.well-known/acme-challenge/ {
alias /var/www/challenges/;
try_files $uri @forward_https;
}
location @forward_https {
return 301 https://www.example.com$request_uri;
}
location / {
return 301 https://www.example.com$request_uri;
}
}
С этой конфигурацией, если /var/www/challenges/
пуст, ваш HTTP сервер будет вести себя так, будто локация /.well-known/acme-challenge/
не указана.
DNS Челленджи
Если используются DNS челленджи, следующие переменные определяют, как могут быть выполнены челленджи:
acme_certificate_dns_provider
: должен быть одним изroute53
,hosttech
иns1
. Каждый из них требует дополнительной информации:- Для
route53
(Amazon Route 53) учетные данные должны быть переданы какacme_certificate_aws_access_key
иacme_certificate_aws_secret_key
. - Для
hosttech
(hosttech GmbH требуется внешний hosttech_dns_record модуль). - Для
ns1
(ns1.com) ключ вашей учетной записи API должен быть передан какacme_certificate_ns1_secret_key
. Это также зависит от внешнего модуляns1_record
. Предполагая стандартную структуру каталогов и настройки, вам может понадобиться загрузить 2 файла на машину, где выполняется плейбук:
curl --create-dirs -L -o ~/.ansible/plugins/module_utils/ns1.py https://github.com/ns1/ns1-ansible-modules/raw/master/module_utils/ns1.py curl --create-dirs -L -o ~/.ansible/plugins/modules/ns1_record.py https://github.com/ns1/ns1-ansible-modules/raw/master/library/ns1_record.py
- Для
Обратите внимание, что код DNS челленджей не идеален. Функциональность Route 53, Hosttech и NS1 была протестирована. Одна вещь, которая еще не завершена, заключается в том, что код пытается извлечь DNS-зону из домена, беря последние две компоненты, разделенные точками. Это приведет к сбою, например, для доменов .co.uk
или других вложенных зон.
Поддержка большее количество DNS-поставщиков может быть добавлена путем добавления файлов tasks/dns-NAME-create.yml
и tasks/dns-NAME-cleanup.yml
с аналогичным содержимым, как в существующих файлах.
Конвертация ключа учетной записи
Обратите внимание, что эта роль Ansible ожидает, что ключ учетной записи Let's Encrypt будет в формате PEM, а не в формате JWK, который используется официальным клиентом Let's Encrypt certbot. Если вы создали ключ учетной записи с помощью официального клиента и хотите использовать этот ключ с этой ролью Ansible, вам нужно будет его конвертировать. Один из инструментов, который может это сделать — pem-jwk.
Сгенерированные файлы
Предположим, вы создали TLS-ключи для www.example.com
. Вам нужно скопировать соответствующие файлы на ваш веб-сервер. Роль ansible создала следующие файлы:
keys/www.example.com.key
: это закрытый ключ для сертификата. Убедитесь, что никто не может его получить.keys/www.example.com.pem
: это сам сертификат.keys/www.example.com-chain.pem
: это промежуточные сертификаты, необходимые для доверительной цепочки.keys/www.example.com.cnf
: это файл конфигурации OpenSSL, используемый для создания запроса на подпись сертификата (CSR). Его можно безопасно удалить.keys/www.example.com.csr
: это запрос на сертификат, используемый для получения сертификата. Его можно безопасно удалить.keys/www.example.com-fullchain.pem
: это сертификат, объединенный с промежуточными сертификатами.keys/www.example.com-rootchain.pem
: это промежуточные сертификаты, объединенные с корневым сертификатом. Вам, возможно, понадобится это для OCSP stapling.keys/www.example.com-root.pem
: это корневой сертификат Let's Encrypt.
Для настройки вашего веб-сервера вам нужен закрытый ключ (keys/www.example.com.key
), и либо сертификат с объединенными промежуточными сертификатами в одном файле (keys/www.example.com-fullchain.pem
), либо сертификат и промежуточные сертификаты как два отдельных файла (keys/www.example.com.pem
и keys/www.example.com-chain.pem
). Если вы хотите использовать OCSP stapling, вам также понадобится keys/www.example.com-rootchain.pem
.
Чтобы перенести эти файлы на ваш веб-сервер, вы можете добавить такие задачи:
- name: копирование закрытых ключей
copy:
src: keys/{{ item }}
dest: /etc/ssl/private/
owner: root
group: root
mode: "0400"
with_items:
- www.example.com.key
notify: перезагрузить веб-сервер
- name: копирование сертификатов
copy:
src: keys/{{ item }}
dest: /etc/ssl/server-certs/
owner: root
group: root
mode: "0444"
with_items:
- www.example.com-rootchain.pem
- www.example.com-fullchain.pem
- www.example.com.pem
notify: перезагрузить веб-сервер
Конфигурация веб-сервера может выглядеть следующим образом (для nginx):
server {
listen www.example.com:443 ssl; # IPv4: слушать IP, на который указывает www.example.com
listen [::]:443 ssl; # IPv6: слушать localhost
server_name www.example.com;
# Разрешаю только TLS 1.0 и 1.2, с очень выборочными шифрами.
# По данным SSL Lab's SSL server test это будет блокировать:
# - Android 2.3.7
# - IE 6 и 8 на Windows XP
# - Java 6, 7 и 8
# Если это для вас неприемлемо, выберите другие списки шифров. Посмотрите например на
# https://wiki.mozilla.org/Security/Server_Side_TLS
ssl_protocols TLSv1.2 TLSv1;
ssl_prefer_server_ciphers on;
ssl_ciphers "-ALL !ADH !aNULL !EXP !EXPORT40 !EXPORT56 !RC4 !3DES !eNULL !NULL !DES !MD5 !LOW ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES256-SHA384 DHE-RSA-AES256-SHA256 ECDHE-ECDSA-AES256-SHA ECDHE-RSA-AES256-SHA DHE-RSA-AES256-SHA";
# Цепочка сертификатов, отправляемая браузеру, а также закрытый ключ.
# Убедитесь, что ваш закрытый ключ доступен только веб-серверу во время загрузки конфигурации
# (что по умолчанию делает пользователь root).
ssl_certificate /etc/ssl/server-certs/www.example.com-fullchain.pem;
ssl_certificate_key /etc/ssl/private/www.example.com.key;
# Для OCSP stapling нам нужен DNS резолвер. Здесь указаны только публичные Quad9 и
# Google DNS серверы; я бы добавил их перед DNS серверами вашего хостера.
# Обычно вы можете найти их IP-адреса в /etc/resolv.conf на вашем веб-сервере.
resolver 9.9.9.9 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 10s;
# Включение OCSP stapling. Nginx позаботится о получении OCSP данных
# автоматически. См. [https://wiki.mozilla.org/Security/Server_Side_TLS#OCSP_Stapling]
# для подробностей о OCSP stapling.
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/server-certs/www.example.com-rootchain.pem;
# Включает кэш сессий SSL. Настройте числа в зависимости от использования вашего сайта.
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 30m;
ssl_session_tickets off;
# Вы должны использовать HSTS только с правильными сертификатами; сертификаты от Let's Encrypt
# подходят для этого, самоподписанные не подходят. См. MozillaWiki для получения более подробной информации:
# [https://wiki.mozilla.org/Security/Server_Side_TLS#HSTS:_HTTP_Strict_Transport_Security]
add_header Strict-Transport-Security "max-age=3155760000;";
charset utf-8;
access_log /var/log/nginx/www.example.com.log combined;
error_log /var/log/nginx/www.example.com.log error;
location / {
root /var/www/www.example.com;
index index.html;
}
}
Зависимости
Эта роль не зависит от других ролей.
Пример плейбука
Эту роль можно использовать следующим образом. Обратите внимание, что она получает несколько сертификатов и определяет переменные, используемые для всех сертификатов глобально:
---
- name: получение сертификатов для веб-сервера
hosts: webserver
vars:
acme_certificate_acme_account: 'keys/acme-account.key'
acme_certificate_acme_email: '[email protected]'
# Для HTTP челленджей:
acme_certificate_server_location: '/var/www/challenges/'
acme_certificate_http_challenge_user: root
acme_certificate_http_challenge_group: http
acme_certificate_http_challenge_folder_mode: "0750"
acme_certificate_http_challenge_file_mode: "0640"
# Для DNS челленджей с route53:
acme_certificate_dns_provider: route53
acme_certificate_aws_access_key: REPLACE_WITH_YOUR_ACCESS_KEY
acme_certificate_aws_secret_key: REPLACE_WITH_YOUR_SECRET_KEY
# Для DNS челленджей с ns1:
# acme_certificate_dns_provider: ns1
# acme_certificate_ns1_secret_key: REPLACE_WITH_YOUR_SECRET_KEY
roles:
- role: acme_certificate
acme_certificate_domains: ['example.com', 'www.example.com']
# Использовать DNS челленджи:
acme_certificate_challenge: dns-01
- role: acme_certificate
acme_certificate_domains: ['another.example.com']
acme_certificate_key_name: 'another.example.com-rsa'
acme_certificate_key_length: 4096
# Использовать HTTP челленджи:
acme_certificate_challenge: http-01
- role: acme_certificate
acme_certificate_domains: ['another.example.com']
acme_certificate_key_name: 'another.example.com-ecc'
acme_certificate_algorithm: 'p-256'
Лицензия
Лицензия MIT (MIT)
Copyright (c) 2018-2020 Felix Fontein
Настоящим предоставляется разрешение, безвозмездно, любому лицу, получившему копию этого программного обеспечения и сопутствующих документационных файлов (далее – "Программное обеспечение"), распоряжаться Программным обеспечением без ограничений, включая, без ограничения, права использовать, копировать, модифицировать, объединять, публиковать, распространять, предоставлять сублицензии и/или продавать копии Программного обеспечения, а также разрешать лицам, которому Программное обеспечение предоставлено, делать это, при соблюдении следующих условий:
Вышеуказанное уведомление об авторских правах и настоящее разрешение должны быть включены во все копии или значительные части Программного обеспечения.
ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ "КАК ЕСТЬ", БЕЗ ГАРАНТИЙ КАКОГО-ЛИБО РОДА, ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ КОММЕРЧЕСКОЙ ЦЕННОСТИ, ПРИГОДНОСТИ ДЛЯ КОНКРЕТНОЙ ЦЕЛИ И НАРУШЕНИЯ. В НИКТОРОМ СЛУЧАЕ АВТОРЫ ИЛИ ДЕРЖАТЕЛИ АВТОРСКИХ ПРАВ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ИСКИ, УБЫТКИ ИЛИ ДРУГИЕ ОБЯЗАННОСТИ, ПО КОТОРЫМ БУДЕТ ВЕДЕН ДИАЛОГ В УСЛОВИЯХ ДОГОВОРА, НАРУШЕНИЯ ИЛИ ИНЫМ ОБРАЗОМ, ВОЗНИКАЮЩИЕ ИЗ ИЛИ СВЯЗАННЫЕ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЗОВАНИЕМ ИЛИ ДРУГИМИ СДЕЛКИ В ПРОГРАММНОМ ОБЕСПЕЧЕНИИ.
Информация об авторе
Домашняя страница для этой роли — https://github.com/felixfontein/acme-certificate/. Пожалуйста, используйте трекер проблем для сообщения о проблемах.
Wrapper of Ansible's included acme_certificate module, whose aim is that almost no code is executed on the webserver. Requires the Python cryptography library as well as the OpenSSL binary installed locally and available on executable path.
ansible-galaxy install felixfontein.acme_certificate