Wildcard SSL-сертификат (*.example.com) покрывает все поддомены одного уровня. Let's Encrypt выдаёт их бесплатно, но только через DNS-верификацию (не через HTTP). Это требует либо ручного добавления TXT-записи, либо автоматизации через DNS API.
Получение Wildcard через Certbot (ручной DNS)
certbot certonly --manual --preferred-challenges=dns -d example.com -d "*.example.com"
# Certbot попросит добавить TXT-запись:
# _acme-challenge.example.com → "значение"
# Добавьте запись в DNS-панели и нажмите Enter
Автоматизация через Cloudflare API (рекомендуется)
pip install certbot-dns-cloudflare
# Создать файл с API-токеном Cloudflare
mkdir -p /etc/letsencrypt/cloudflare
cat > /etc/letsencrypt/cloudflare/credentials.ini << 'EOF'
dns_cloudflare_api_token = ВАШ_CLOUDFLARE_API_TOKEN
EOF
chmod 600 /etc/letsencrypt/cloudflare/credentials.ini
# Получить Wildcard сертификат
certbot certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini -d example.com -d "*.example.com" --preferred-challenges dns-01
Настройка автопролонгации
systemctl status certbot.timer
systemctl list-timers | grep certbot
# Тест пролонгации (без реального обновления)
certbot renew --dry-run
# Принудительное обновление
certbot renew --force-renewal
# Просмотр всех сертификатов
certbot certificates
acme.sh как альтернатива Certbot
>curl https://get.acme.sh | sh -s email=admin@example.com
export CF_Token="ВАШ_CLOUDFLARE_API_TOKEN"
acme.sh --issue --dns dns_cf -d example.com -d "*.example.com"
acme.sh --install-cert -d example.com --key-file /etc/ssl/example.com.key --fullchain-file /etc/ssl/example.com.pem --reloadcmd "systemctl reload nginx"
Мониторинг истечения сертификатов
openssl s_client -connect example.com:443 -servername example.com < /dev/null 2>&1 | grep "notAfter"
certbot certificates | grep -E "Expiry|Domains"
--staging.
Частые ошибки при выпуске Wildcard
| Сообщение | Что означает |
|---|---|
| Incorrect TXT record found at _acme-challenge.example.com | DNS ещё не обновился (старое значение TTL) либо запись добавлена не в ту зону |
| urn:ietf:params:acme:error:rateLimited | Превышен недельный лимит запросов Let's Encrypt на домен — нужно подождать окно сброса лимита |
| Cloudflare API error: Invalid request headers | Используется Global API Key вместо ограниченного API Token, либо у токена нет прав Zone:DNS:Edit |
| certbot: command not found после установки | Пакет ставился не тем менеджером (snap вместо apt) или не обновлён PATH в текущей сессии оболочки |
Certbot vs acme.sh: что выбрать
| Критерий | Certbot | acme.sh |
|---|---|---|
| Зависимости | Python и системные пакеты | Только Bash и curl |
| Хранение ключей аккаунта | /etc/letsencrypt | В домашней директории пользователя |
| Плагины DNS-провайдеров | Официальные и сторонние пакеты pip | Встроенные shell-скрипты для десятков DNS API |
| Права на установку | Обычно требует root | Может работать без root |
Когда wildcard-сертификат не нужен
- На сервере всего 1-2 поддомена — проще и быстрее выпустить обычный SAN-сертификат на конкретные имена
- DNS домена управляется третьей стороной без доступа к API — ручное продление TXT-записи каждые 90 дней превращается в постоянную рутину
- Перед origin уже стоит прокси вроде Cloudflare, который терминирует TLS для посетителей — часто достаточно Origin-сертификата между Cloudflare и сервером
- Нужен EV или OV сертификат с проверкой организации — Let's Encrypt выпускает только DV-сертификаты
Проверка автопролонгации
# Логи последних попыток продления
journalctl -u certbot.timer --since "7 days ago"
# Свежесть TXT-записи глазами внешнего DNS
dig TXT _acme-challenge.example.com +short @1.1.1.1
Если journalctl показывает успешные запуски таймера, но сертификат не обновился — проверьте историю через certbot certificates и сравните дату Expiry с сегодняшней. Смежная тема — SSL и Certbot в Nginx и Origin-сертификат Cloudflare как альтернатива для сайтов за прокси.
Хранение API-токена: как не подставить домен
Файл с Cloudflare API-токеном, использованный в примерах выше, физически лежит на диске сервера и его нужно защищать так же, как приватный ключ сертификата. Токен с правами Zone:DNS:Edit позволяет управлять всеми DNS-записями зоны — если он утечёт, злоумышленник сможет не только читать записи, но и подменять их, включая MX-записи почты. Ограничивайте токен конкретной зоной при создании в панели Cloudflare, а не выпускайте токен с доступом ко всем зонам аккаунта сразу.
Частые вопросы
Будет ли работать автопролонгация, если wildcard-сертификат получен через ручной DNS-вызов, а не через API Cloudflare?
Нет, ручной режим требует вручную добавлять новую TXT-запись при каждом продлении, поэтому автоматический таймер certbot не сможет пройти проверку без участия человека. Для настоящей автопролонгации нужен способ, который сам добавляет и удаляет TXT-запись в DNS, то есть плагин вроде dns-cloudflare или аналогичный скрипт в acme.sh, а не ручной режим challenge.
Как не попасть под лимит запросов Let's Encrypt во время тестирования настройки?
Нужно тестировать выпуск сертификата с флагом staging, который использует отдельную тестовую среду с собственными, гораздо более мягкими ограничениями и не расходует лимит боевых запросов. Переключаться на настоящий (production) выпуск стоит только тогда, когда весь процесс через staging прошёл без ошибок — иначе неудачные попытки на боевом окружении быстро упрутся в недельный лимит.
Безопаснее ли отдельные сертификаты для каждого поддомена, чем один wildcard?
С точки зрения приватного ключа риск скорее выше у wildcard: один и тот же приватный ключ покрывает сразу все поддомены, и его утечка на любом из серверов, где он установлен, компрометирует защиту для всех них одновременно. Отдельные сертификаты по поддоменам изолируют такой риск — компрометация одного ключа не задевает остальные поддомены.
Можно ли одновременно использовать Certbot и acme.sh на одном сервере?
Технически можно, но лучше выбрать что-то одно: оба инструмента независимо выпускают и обновляют сертификаты, хранят ключи аккаунта в разных местах и не знают друг о друге, поэтому легко получить путаницу, какой именно сертификат реально подключён в конфиге веб-сервера. Проще держать для домена единственный инструмент автопролонгации.