Информация на этой странице находится в доработке. Информация может добавляться и изменяться.
Рассматриваем работу с сертификатами Let’s Encrypt при помощи утилиты #LeGo.
- Скачать #LeGo и распаковать в директорию
/root/apps/acme/
. - Создать файл
hook.sh
в директории /root/apps/acme/
. - Изучить документацию и справку по командам для составления запросов на получение и обновление сертификатов.
- Выбрать метод получения и обновления сертификатов.
Let’s Encrypt выдаёт клиенту токен, клиент записывает этот токен в файл на web-сервере по пути http://example.com/.well-known/acme-challenge/<TOKEN>
.
Плюсы метода:
- Легко автоматизировать без дополнительных знаний о домене.
- Работает со всеми web-серверами.
- Можно использовать для проверки IP-адресов.
Минусы метода:
- Не работает, если провайдер блокирует порт
80
. - Не позволяет получать wildcard-сертификаты.
- Зарегистрировать адрес
mail@example.com
и получить сертификат для доменов example.com
и mail.example.com
в директорию /root/apps/acme/
:
1
| "${HOME}/apps/acme/lego" --accept-tos --path="${HOME}/apps/acme" --email='mail@example.com' --domains='example.com' --domains='mail.example.com' --pem --pfx --http --http.webroot='/var/www/html' run
|
--accept-tos
- автоматически принять соглашение.--path
- путь к хранилищу сертификатов (/root/apps/acme/
).--email
- адрес электронной почты для регистрации и восстановления сертификата Let’s Encrypt (mail@example.com
).--domains
- список доменов для получения сертификата (example.com
и mail.example.co
).--http
- получение сертификата методом HTTP-01
.--http.webroot
- WEB-директория сервера для интеграции идентификатора .well-known/acme-challenge
.
- Обновить сертификат для доменов
example.com
и mail.example.com
в директории /root/apps/acme/
и запустить файл hook.sh
при успешном обновлении:
1
| "${HOME}/apps/acme/lego" --path="${HOME}/apps/acme" --email='mail@example.com' --domains='example.com' --domains='mail.example.com' --pem --pfx --http --http.webroot='/var/www/html' --renew-hook="${HOME}/apps/acme/hook.sh" renew
|
--renew-hook
- выполнение специального скрипта только после успешного обновления сертификата.
- Создать файл
/etc/cron.d/app_acme_example_com
со следующим содержанием:
1
2
3
4
5
| SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOME=/root
35 3 * * * root "${HOME}/apps/acme/lego" --path="${HOME}/apps/acme" --email='mail@example.com' --domains='example.com' --domains='mail.example.com' --pem --pfx --http --http.webroot='/var/www/html' --renew-hook="${HOME}/apps/acme/hook.sh" renew > /dev/null 2>&1
|
Let’s Encrypt проверяет принадлежность домена клиенту при помощи специальной TXT-записи _acme-challenge.example.com
для доменного имени.
Плюсы метода:
- Позволяет получать wildcard-сертификаты.
- Работает со множеством серверов.
Минусы метода:
- Необходимо хранить данные API от DNS-провайдера на сервере.
- DNS-провайдер может не предоставлять специальный API для изменения записей домена.
- Нельзя использовать для проверки IP-адресов.
- Зарегистрировать адрес
mail@example.com
и получить сертификат для доменов example.com
и *.example.com
в директорию /root/apps/acme/
:
1
| CF_DNS_API_TOKEN='TOKEN'; "${HOME}/apps/acme/lego" --accept-tos --path="${HOME}/apps/acme" --email='mail@example.com' --domains='example.com' --domains='*.example.com' --pem --pfx --dns='cloudflare' --dns.resolvers '1.1.1.1:53' --dns.resolvers '8.8.8.8:53' --dns.resolvers '77.88.8.8:53' run
|
CF_DNS_API_TOKEN
- токен доступа #LeGo к редактированию зоны example.com
.--accept-tos
- автоматически принять соглашение.--path
- путь к хранилищу сертификатов (/root/apps/acme
).--email
- адрес электронной почты для регистрации и восстановления сертификата Let’s Encrypt (mail@example.com
).--domains
- список доменов для получения сертификата (example.com
и *.example.com
).--dns
- получение сертификата методом DNS-01
.--dns.resolvers
- список внешних серверов DNS для доменных имён.
- Обновить сертификат для доменов
example.com
и *.example.com
в директории /root/apps/acme/
и запустить файл hook.sh
при успешном обновлении:
1
| CF_DNS_API_TOKEN='TOKEN'; "${HOME}/apps/acme/lego" --path="${HOME}/apps/acme" --email='mail@example.com' --domains='example.com' --domains='*.example.com' --pem --pfx --dns='cloudflare' --dns.resolvers '1.1.1.1:53' --dns.resolvers '8.8.8.8:53' --dns.resolvers '77.88.8.8:53' --renew-hook="${HOME}/apps/acme/hook.sh" renew
|
--renew-hook
- выполнение специального скрипта только после успешного обновления сертификата.
- Создать файл
/etc/cron.d/app_acme_example_com
со следующим содержанием:
1
2
3
4
5
6
| SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOME=/root
CF_DNS_API_TOKEN_FILE="${HOME}/apps/acme/CF_TOKEN_EXAMPLE_COM"
35 3 * * * root "${HOME}/apps/acme/lego" --path="${HOME}/apps/acme" --email='mail@example.com' --domains='example.com' --domains='*.example.com' --pem --pfx --dns='cloudflare' --dns.resolvers='1.1.1.1:53' --dns.resolvers='8.8.8.8:53' --dns.resolvers='77.88.8.8:53' --renew-hook="${HOME}/apps/acme/hook.sh" renew > /dev/null 2>&1
|
Проверка TLS-ALPN-01 выполняется через TLS handshake на порте 443
. Применяется специальный протокол ALPN
, чтобы на запросы валидации отвечали только серверы, знающие о таком типе проверки. Присутствует возможность использовать поле SNI
, совпадающее с именем домена, для которого проводится валидация, для увеличения надёжности проверки.
Плюсы метода:
- Работает при закрытом порте
80
. - Проверка выполняется исключительно на уровне TLS.
- Можно использовать для проверки IP-адресов.
Минусы метода:
- Возможно, какие-то web-серверы не поддерживают данный метод проверки.
- Не позволяет получать wildcard-сертификаты.
К сожалению, метод проверки требует не занятого порта 443
. Если какой то сервис уже занимает порт 443
, то этот сервис на время проверки необходимо выключить. Чтобы обойти данное ограничение, можно до-настроить Angie таким образом, чтобы он перенаправлял соединения TLS-ALPN
на сервис проверки сертификатов, а остальные соединения направлял на виртуальные хосты HTTPS.
- На всех виртуальных хостах изменить порт
443
на 8443
. - Создать балансировщик нагрузки
ALPN
, добавив в файл /etc/angie/angie.conf
следующую конфигурацию:
1
2
3
4
5
6
7
8
| # -------------------------------------------------------------------------------------------------------------------- #
# ACME: TLS-ALPN
# -------------------------------------------------------------------------------------------------------------------- #
stream {
map $ssl_preread_alpn_protocols $tls_port { ~\bacme-tls/1\b 10443; default 8443; }
server { listen 443; proxy_pass 127.0.0.1:$tls_port; ssl_preread on; }
}
|
- Зарегистрировать адрес
mail@example.com
и получить сертификат для доменов example.com
и mail.example.com
в директорию /root/apps/acme/
:
1
| "${HOME}/apps/acme/lego" --accept-tos --path="${HOME}/apps/acme" --email='mail@example.com' --domains='example.com' --domains='mail.example.com' --pem --pfx --tls --tls.port=':10443' run
|
--accept-tos
- автоматически принять соглашение.--path
- путь к хранилищу сертификатов (/root/apps/acme/
).--email
- адрес электронной почты для регистрации и восстановления сертификата Let’s Encrypt (mail@example.com
).--domains
- список доменов для получения сертификата (example.com
и mail.example.co
).--tls
- получение сертификата методом TLS-ALPN-01
.--tls.port
- номер порта для работы #LeGo (10443
).
- Обновить сертификат для доменов
example.com
и mail.example.com
в директории /root/apps/acme/
и запустить файл hook.sh
при успешном обновлении:
1
| "${HOME}/apps/acme/lego" --path="${HOME}/apps/acme" --email='mail@example.com' --domains='example.com' --domains='mail.example.com' --pem --pfx --tls --tls.port=':10443' --renew-hook="${HOME}/apps/acme/hook.sh" renew
|
--renew-hook
- выполнение специального скрипта только после успешного обновления сертификата.
- Создать файл
/etc/cron.d/app_acme_example_com
со следующим содержанием:
1
2
3
4
5
| SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOME=/root
35 3 * * * root "${HOME}/apps/acme/lego" --path="${HOME}/apps/acme" --email='mail@example.com' --domains='example.com' --domains='mail.example.com' --pem --pfx --tls --tls.port=':10443' --renew-hook="${HOME}/apps/acme/hook.sh" renew > /dev/null 2>&1
|
- Создать файл приложения
/root/apps/acme/hook.sh
со следующим содержанием:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
| #!/usr/bin/env -S bash -eu
# -------------------------------------------------------------------------------------------------------------------- #
# ACME: HOOK
# -------------------------------------------------------------------------------------------------------------------- #
# @package Bash
# @author Kai Kimera
# @license MIT
# @version 0.1.0
# @link https://lib.onl/ru/2025/03/481a0666-eb21-555f-858f-0c2d695b9a74/
# -------------------------------------------------------------------------------------------------------------------- #
(( EUID != 0 )) && { echo >&2 'This script should be run as root!'; exit 1; }
# Sources.
SRC_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd -P )" # Source directory.
SRC_NAME="$( basename "$( readlink -f "${BASH_SOURCE[0]}" )" )" # Source name.
# shellcheck source=/dev/null
. "${SRC_DIR}/${SRC_NAME%.*}.conf" # Loading configuration file.
# Parameters.
DATA=("${DATA:?}"); readonly DATA
SERVICES=("${SERVICES[@]:?}"); readonly SERVICES
# -------------------------------------------------------------------------------------------------------------------- #
# INITIALIZATION
# -------------------------------------------------------------------------------------------------------------------- #
run() { cert && svcs; }
# -------------------------------------------------------------------------------------------------------------------- #
# CERTIFICATES
# -------------------------------------------------------------------------------------------------------------------- #
cert() {
[[ ! -d "${DATA}" ]] && mkdir -p "${DATA}"
for i in "${LEGO_CERT_PATH}" "${LEGO_CERT_KEY_PATH}" "${LEGO_CERT_PEM_PATH}" "${LEGO_CERT_PFX_PATH}"; do
install -u 'root' -g 'root' -m '0644' "${i}" "${DATA}"
done
}
# -------------------------------------------------------------------------------------------------------------------- #
# SERVICES
# -------------------------------------------------------------------------------------------------------------------- #
svcs() {
for s in "${SERVICES[@]}"; do _if_svc "${s}" && systemctl reload "${s}"; done
}
# -------------------------------------------------------------------------------------------------------------------- #
# ------------------------------------------------< COMMON FUNCTIONS >------------------------------------------------ #
# -------------------------------------------------------------------------------------------------------------------- #
_if_svc() {
local s; s="${1}"
systemctl list-units --type='service' --state='running' | grep -Fq "${s}" && return 0 || return 1
}
# -------------------------------------------------------------------------------------------------------------------- #
# -------------------------------------------------< RUNNING SCRIPT >------------------------------------------------- #
# -------------------------------------------------------------------------------------------------------------------- #
run && exit 0 || exit 1
|
- Создать файл настроек
/root/apps/acme/hook.conf
со следующим содержанием:
1
2
3
4
5
6
7
8
9
| DATA='/etc/ssl/acme'
SERVICES=(
'angie.service'
'apache2.service'
'dovecot.service'
'exim4.service'
'nginx.service'
'postfix.service'
)
|
В этом разделе представлены настройки использования сертификата Let’s Encrypt для различных приложений.
- Настроить параметры в
/etc/postfix/main.cf
для домена example.com
:
1
2
3
4
5
6
7
| # -------------------------------------------------------------------------------------------------------------------- #
# SSL / TLS
# -------------------------------------------------------------------------------------------------------------------- #
smtpd_tls_cert_file = /etc/ssl/acme/example.com.crt
smtpd_tls_key_file = /etc/ssl/acme/example.com.key
smtpd_tls_CAfile = /etc/ssl/acme/example.com.crt
|
- Настроить параметры в
/etc/dovecot/dovecot.conf
для домена example.com
:
1
2
3
4
5
6
7
| # -------------------------------------------------------------------------------------------------------------------- #
# SSL / TLS
# -------------------------------------------------------------------------------------------------------------------- #
ssl_cert = </etc/ssl/acme/example.com.crt
ssl_key = </etc/ssl/acme/example.com.key
ssl_ca = </etc/ssl/acme/example.com.crt
|
- Настроить параметры в
/etc/mysql/my.cnf
для домена example.com
:
1
2
3
4
5
6
7
8
9
| [mariadbd]
# -------------------------------------------------------------------------------------------------------------------- #
# SSL / TLS
# -------------------------------------------------------------------------------------------------------------------- #
ssl_cert = '/etc/ssl/acme/example.com.crt'
ssl_key = '/etc/ssl/acme/example.com.key'
ssl_ca = '/etc/ssl/acme/example.com.crt'
|
- Настроить параметры в
/etc/ldap/slapd.conf
для домена example.com
:
1
2
3
4
5
6
7
| # -------------------------------------------------------------------------------------------------------------------- #
# SSL / TLS
# -------------------------------------------------------------------------------------------------------------------- #
TLSCertificateFile /etc/ssl/acme/example.com.crt
TLSCertificateKeyFile /etc/ssl/acme/example.com.key
TLSCACertificateFile /etc/ssl/acme/example.com.crt
|