Loading...

Безопасность · 11 мин чтения

Certbot: как правильно получать и продлевать сертификаты Let's Encrypt

Certbot — бесплатный ACME-клиент от EFF: он запрашивает сертификаты у Let's Encrypt, доказывает, что вы контролируете домен, устанавливает сертификат в nginx или Apache и продлевает его автоматически. Установите его через snap, выпустите сертификат командой certbot --nginx или --apache, используйте DNS-01 для wildcard и проверяйте продление командой certbot renew --dry-run.

Обновлено

Certbot: как правильно получать и продлевать сертификаты Let's Encrypt

Что такое certbot и что он на самом деле делает

Certbot — бесплатный ACME-клиент с открытым исходным кодом, который поддерживает Electronic Frontier Foundation. ACME — это протокол, которым Let's Encrypt (и всё больше других CA) выпускает сертификаты без участия человека. Certbot говорит на нём за вас: создаёт ключ аккаунта, запрашивает у CA сертификат, доказывает, что вы контролируете домен, сохраняет сертификат и ключ на диск и, если вы позволите, редактирует конфигурацию вашего веб-сервера и продлевает всё до истечения срока.

Доказательство контроля — это challenge, и certbot поддерживает два вида. HTTP-01: CA запрашивает случайный токен по адресу http://example.com/.well-known/acme-challenge/<token> на порту 80, а certbot следит, чтобы этот файл отдавался. DNS-01: CA ищет TXT-запись на _acme-challenge.example.com, а certbot (или вы сами) её публикует. HTTP-01 — простой вариант по умолчанию; DNS-01 — единственный способ получить wildcard и способ выпустить сертификат для сервера, недоступного из интернета.

Кто что делает, определяют два вида плагинов. Authenticator отвечает на challenge (--nginx, --apache, --webroot, --standalone, --manual или DNS-плагин вроде --dns-cloudflare). Installer помещает сертификат в конфигурацию сервера (nginx или apache). certbot --nginx делает и то, и другое; certbot certonly ... только получает сертификат, оставляя конфигурацию вам.

Всё оказывается в /etc/letsencrypt. Файлы, на которые вы направляете сервер, находятся в /etc/letsencrypt/live/<cert-name>/: fullchain.pem (ваш сертификат плюс промежуточный) и privkey.pem. Это симлинки на archive/, поэтому пути никогда не меняются при продлении. Если нужна база о том, что такое сертификат и почему он бесплатный, читайте бесплатные SSL-сертификаты; это руководство — про инструмент.

Установка certbot: сначала snap, затем пакеты дистрибутива

Проект certbot рекомендует пакет snap на Linux. Он отслеживает текущий релиз (5.x в 2026 году), несёт собственный Python и устанавливает systemd-таймер для продления. Сначала удалите копию из дистрибутива, чтобы два certbot не конфликтовали из-за /etc/letsencrypt: sudo apt remove certbot, sudo dnf remove certbot или sudo yum remove certbot.

Пакеты дистрибутива работают и уже есть на многих серверах: sudo apt install certbot python3-certbot-nginx (или python3-certbot-apache) на Debian и Ubuntu, те же имена пакетов из EPEL на RHEL, Rocky и Alma. Компромисс — возраст: LTS-дистрибутив может поставлять certbot на несколько major-версий позади, а это важно теперь, когда Let's Encrypt сокращает срок жизни сертификатов (см. раздел про продление). Certbot также опубликован на PyPI и как Docker-образы (certbot/certbot и по одному образу на каждый DNS-плагин), если вам так удобнее.

После установки certbot --version показывает, что у вас установлено, а sudo certbot certificates выводит список всех сертификатов, которыми он управляет, с доменами, датой истечения и путями к файлам.

Рекомендуемая установка на Linux (snap)

# remove an OS-packaged certbot first, if present
sudo apt remove certbot

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/local/bin/certbot

certbot --version
sudo certbot certificates

Выпуск сертификата для nginx и Apache

Плагины nginx и Apache — самый короткий путь. sudo certbot --nginx -d example.com -d www.example.com находит блок server, чей server_name совпадает, отвечает на HTTP-01 через него, записывает ssl_certificate и ssl_certificate_key в этот блок и перезагружает nginx. Последние версии по умолчанию добавляют редирект с HTTP на HTTPS; --no-redirect это отключает. --apache делает то же самое с виртуальными хостами. Обоим нужен server_name / ServerName, совпадающий с доменом, иначе certbot не поймёт, какой блок редактировать. Только знакомитесь с самим сервером? Начните с что такое nginx.

Webroot — вариант для тех, кто хочет, чтобы certbot не трогал конфигурацию: он записывает файл challenge в каталог, который уже отдаёт ваш запущенный сервер. certonly означает, что две строки ssl_ вы добавляете сами один раз; продления просто заменяют файлы по тем же путям.

Standalone запускает собственный крошечный веб-сервер на порту 80. Это для машин без веб-сервера или с сервером, который не nginx и не Apache. Порт 80 должен быть свободен во время выпуска и каждого продления, поэтому останавливайте другой сервер в хуке: --pre-hook "systemctl stop haproxy" --post-hook "systemctl start haproxy".

Каждый -d добавляет имя к одному и тому же сертификату, а первое становится именем сертификата. Чтобы добавить имя позже, запустите команду снова с полным списком плюс --cert-name example.com; certbot заменит старый сертификат, а не создаст второй.

Четыре распространённых способа выпуска (выберите один)

# nginx: issue and install
sudo certbot --nginx -d example.com -d www.example.com

# Apache: issue and install
sudo certbot --apache -d example.com -d www.example.com

# webroot: issue only; your server keeps serving /.well-known/acme-challenge/
sudo certbot certonly --webroot -w /var/www/example -d example.com -d www.example.com

# standalone: certbot listens on :80 itself
sudo certbot certonly --standalone -d example.com

# then, in nginx, for the webroot/standalone case:
#   ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
#   ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

Wildcard-сертификаты через DNS-01

Let's Encrypt выпускает *.example.com только через DNS-01. Wildcard покрывает один уровень (shop.example.com, но не a.shop.example.com) и не покрывает «голый» домен, поэтому запрашивайте оба: -d example.com -d '*.example.com'. Возьмите звёздочку в кавычки, чтобы её не развернул шелл.

С DNS-плагином certbot создаёт и удаляет TXT-записи через API вашего DNS-провайдера, и именно это делает продление автоматическим. Есть официальные плагины для Cloudflare, Route 53, Google Cloud DNS, DigitalOcean, Linode, OVH, серверов RFC 2136 и других, а сторонних плагинов — ещё больше. Со snap сначала нужно разрешить плагинам работать от root (sudo snap set certbot trust-plugin-with-root=ok), затем установить snap-пакет плагина. Держите файл с учётными данными с правами 600 и выдавайте API-токену минимально необходимый доступ, какой позволяет провайдер (для Cloudflare — *Zone: DNS: Edit* на эту одну зону).

С --manual certbot печатает значение TXT и ждёт, пока вы добавите его вручную. Запрос example.com и *.example.com вместе требует два значения TXT под одним и тем же именем _acme-challenge.example.com; опубликуйте оба как отдельные записи. Проверьте с dig +short TXT _acme-challenge.example.com перед тем, как нажать Enter. Подвох: сертификат, выпущенный вручную, не продлевается автоматически, если вы не подадите скрипты --manual-auth-hook и --manual-cleanup-hook, которые сами делают работу с DNS, так что для чего-то долгоживущего используйте плагин.

Если у вашего DNS-провайдера нет API, можно направить _acme-challenge.example.com на зону, которую вы контролируете, через CNAME-запись; CA пройдёт по CNAME и прочитает там TXT-запись.

Wildcard плюс apex через DNS-плагин Cloudflare (snap)

sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare

# /root/.secrets/cloudflare.ini  (chmod 600)
#   dns_cloudflare_api_token = <token with Zone:DNS:Edit>

sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
  -d example.com -d '*.example.com'

# by hand (no automatic renewal without hooks)
sudo certbot certonly --manual --preferred-challenges dns \
  -d example.com -d '*.example.com'

Автоматическое продление: таймеры, хуки и --dry-run

Вам не нужно писать cron-задачу для certbot — это уже сделал пакет. Snap устанавливает systemd-таймер snap.certbot.renew.timer, пакеты Debian и Ubuntu — certbot.timer, а некоторые пакеты используют файл в /etc/cron.d/. Задача запускает certbot renew два раза в день, которая продлевает только те сертификаты, у которых подошёл срок, а остальные тихо пропускает. Посмотреть это можно командой systemctl list-timers | grep certbot.

Когда сертификату пора продлеваться? Начиная с certbot 4.0 — когда осталось меньше трети срока жизни (половина — для сертификатов на 10 дней и меньше), а также certbot учитывает подсказки ACME Renewal Info (ARI) от CA. Это важно, потому что Let's Encrypt сокращает срок жизни сертификатов: профиль по умолчанию переходит с 90 на 64 дня 10 февраля 2027 года и на 45 дней в феврале 2028 года. Настройка, которая продлевает по жёстко прописанному правилу «каждые 60 дней» в cron, сломается; та, что запускает certbot renew ежедневно, — не сломается. Let's Encrypt также перестала присылать письма-напоминания об истечении срока в 2025 году, так что никто не предупредит вас, если продление незаметно не сработает: следите за датой истечения сертификата сами.

Перезагружайте сервер после продления. Инсталляторы nginx и Apache делают это за вас. С webroot, standalone или DNS-плагином добавьте deploy-хук — он запускается только тогда, когда сертификат действительно был продлён. Укажите его в команде при выпуске (--deploy-hook, сохраняется в /etc/letsencrypt/renewal/<name>.conf) или положите исполняемый скрипт в /etc/letsencrypt/renewal-hooks/deploy/.

Всегда проверяйте командой sudo certbot renew --dry-run. Она прогоняет полное продление против тестового окружения Let's Encrypt (staging), с настоящими challenge, не трогая ваши рабочие сертификаты и не расходуя лимиты продакшена.

Проверить таймер, протестировать продление, перезагрузить nginx после каждого продления

systemctl list-timers | grep certbot

sudo certbot renew --dry-run

# reload nginx whenever any certificate is renewed
sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh >/dev/null <<'EOF'
#!/bin/sh
systemctl reload nginx
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

# when does each certificate expire?
sudo certbot certificates

Лимиты Let's Encrypt, в которые реально можно упереться

Лимиты Let's Encrypt щедрые для обычного использования и болезненные во время отладки. Вот те, что чаще всего задевают:

5 сертификатов на точный набор имён за 7 дней. Выпуск example.com + www.example.com пять раз за неделю — например, при повторном запуске скрипта провижининга или очистке /etc/letsencrypt при каждом старте контейнера — блокирует этот точный набор на несколько дней. Ошибка говорит *too many certificates already issued for this exact set of identifiers* и указывает время повтора. Для этого лимита нет обхода. Изменение набора имён (добавление ещё одного имени) получает новый лимит, но настоящее решение — держать /etc/letsencrypt на постоянном хранилище.

5 неудачных проверок на имя хоста на аккаунт в час. Неправильная запись DNS плюс цикл повторов расходует этот лимит за несколько минут.

50 сертификатов на зарегистрированный домен за 7 дней, считается по всем поддоменам example.com, и 300 новых заказов на аккаунт за 3 часа. Хостинговые платформы с множеством поддоменов сталкиваются с этим первыми.

К продлениям относятся снисходительно: продление, использующее ARI, как делает текущий certbot, освобождено от всех лимитов, а обычное продление того же набора имён освобождено от лимитов на домен и на заказы.

Правило для экспериментов: добавляйте --test-cert (псевдоним --staging) или используйте --dry-run. У staging лимиты намного выше, а выпущенные сертификаты браузеры не доверяют — это именно то, что нужно, пока вы настраиваете challenge.

Частые ошибки certbot и как их исправить

Timeout during connect / connection refused на порту 80. HTTP-01 всегда начинается на порту 80, даже если ваш сайт отдаёт только HTTPS. Откройте порт 80 в файрволе и security-группе облака; редиректить его на HTTPS нормально, потому что CA следует по редиректам. Если порт 80 открыть нельзя, переходите на DNS-01.

Invalid response / 404 на /.well-known/acme-challenge/. Запрос дошёл до какого-то сервера, но не того или не в тот каталог. Типичные причины: запись A ещё указывает на старый хост, балансировщик отправляет запрос на другой узел, блок location или rewrite перехватывает путь, либо -w указывает на неправильный webroot. Проверьте сами: создайте файл в .well-known/acme-challenge/ и запросите его curl по обычному HTTP снаружи.

Запись AAAA, указывающая не туда. Если у имени есть адрес IPv6, Let's Encrypt сначала проверяет по IPv6. Устаревшая AAAA-запись, отвечающая с другого сервера, ломает проверку, даже если IPv4 в порядке. Исправьте или удалите AAAA-запись; dig AAAA example.com покажет её.

DNS problem: NXDOMAIN / no valid A records. Имя ещё не резолвится. Дождитесь распространения и проверьте запись на внешнем резолвере, а не только на своей машине.

CAA record prevents issuance. Запись CAA на домене (или родительском домене) перечисляет CA, которым разрешено выпускать сертификаты, и Let's Encrypt там нет. Добавьте example.com. CAA 0 issue "letsencrypt.org", и issuewild тоже, если вы настроили его для wildcard. Подробнее в что такое DNS.

Incorrect TXT record / no TXT record found. DNS-01 проверился раньше, чем запись распространилась, или опубликовано только одно из двух значений для wildcard. Увеличьте --dns-<provider>-propagation-seconds у плагина или дольше подождите в ручном режиме.

Could not automatically find a matching server block. Плагину nginx нужен server_name, равный запрошенному имени. Добавьте его, выполните nginx -t и повторите.

Too many certificates already issued. Лимит на дубликаты, описанный выше. Используйте уже имеющийся сертификат (certbot certificates) и с этого момента тестируйте через --staging.

Certbot в Windows: используйте ACME-клиент для Windows

Certbot прекратил поддержку Windows. Последний установщик для Windows вышел с certbot 2.9.0 в феврале 2024 года, и сайт certbot теперь отправляет пользователей Windows к альтернативам из сообщества. Старые установщики, которые ещё можно найти на сайтах с загрузками, отстали на годы и не получат изменений по продлению, которые сейчас внедряет Let's Encrypt, так что не стройте на них ничего.

Что использовать вместо этого, зависит от сервера:

IIS или любой сервер Windows: обычным выбором был win-acme — инструмент командной строки, который привязывает сертификат в IIS, записывает его в хранилище сертификатов Windows или в файлы PEM/PFX и создаёт задачу планировщика для продления. Его разработчик теперь ведёт simple-acme, описанный как обратно совместимая прямая замена, так что перед новым развёртыванием проверьте этот проект.

Автоматизация в PowerShell: Posh-ACME — модуль PowerShell с большим набором DNS-плагинов для wildcard.

Предпочитаете GUI: Certify The Web — графический клиент для IIS.

Вам действительно нужен certbot: запустите его внутри WSL 2 для выпуска, затем экспортируйте файлы в Windows. Это практично для сертификатов DNS-01, которые вы копируете в другое место, и менее практично для сайта IIS, которому нужна автоматическая привязка.

Ничто из этого не является рекомендацией: все это сторонние проекты, так что читайте их текущую документацию, прежде чем на них рассчитывать.

Отзыв и удаление сертификатов

Отзывайте, когда приватный ключ мог утечь, или когда вы больше не контролируете домен. Certbot нужно либо имя сертификата, либо файл сертификата, и причина: keycompromise, superseded, cessationofoperation, affiliationchanged или unspecified (по умолчанию). После отзыва certbot предложит удалить локальные файлы; соглашайтесь, иначе он продолжит пытаться продлить отозванный сертификат. Если ключ утёк, выпустите замену с новым ключом — certbot делает это по умолчанию.

Удаляйте без отзыва, когда просто перестаёте использовать сертификат, например после переноса сайта: certbot delete --cert-name example.com убирает его из /etc/letsencrypt и из продления. Сначала удалите соответствующие строки ssl_ из конфигурации сервера, иначе nginx не запустится при следующей перезагрузке.

Let's Encrypt перестала поддерживать OCSP; браузеры узнают об отзывах через CRL, поэтому отзыв не становится виден всем мгновенно. Это ещё одна причина держать приватные ключи доступными только для root.

Отзыв скомпрометированного сертификата или удаление ненужного

sudo certbot revoke --cert-name example.com --reason keycompromise

sudo certbot delete --cert-name example.com

За CDN: кто держит сертификат

Как только сайт оказывается за CDN или другим обратным проксом, посетители больше не видят сертификат вашего origin-сервера. Edge завершает TLS собственным сертификатом, а соединение от edge к вашему origin — отдельный хендшейк. Можно оставить certbot на origin, чтобы защитить это второе соединение, но сертификат, который проверяет браузер, — это сертификат edge.

На CDN.com.tr сертификатом на edge занимается Auto SSL: каждый сертификат — это домен-валидированный сертификат Let's Encrypt без отдельной платы. Направьте имя хоста на edge через CNAME, и это имя получит собственный сертификат, проверяемый по HTTP. Делегируйте DNS CDN.com.tr, и корневой домен получит wildcard, покрывающий корень и каждый поддомен первого уровня, проверяемый через DNS-запись. Сертификат запрашивается сразу после того, как домен верифицирован и его DNS указывает на нас, и продлевается автоматически за 30 дней до истечения, так что следить за таймером certbot не нужно.

Переносите действующий сайт? Мастер переноса без простоя выпускает wildcard через TXT-запись у вашего текущего DNS-провайдера ещё до переключения — почти как запуск certbot --manual с DNS-01, и, как и такой запуск, он не продлевается автоматически, пока DNS остаётся за пределами CDN.com.tr. А если у вас есть сертификат OV или EV от другого CA, его можно загрузить и привязать к имени хоста; он получит ту же политику TLS, что и автоматический. Руководство по TLS объясняет, что именно согласует edge, а HSTS — следующий шаг, когда HTTPS уже надёжно работает.

Частые вопросы о certbot

Certbot бесплатный?

Да. Certbot — программа с открытым исходным кодом от EFF, а сертификаты Let's Encrypt ничего не стоят. Вы не платите ни за сертификат, ни за продление; единственные ограничения — лимиты Let's Encrypt.

Как продлить сертификат certbot вручную?

Выполните sudo certbot renew. Это продлит каждый сертификат, у которого подошёл срок, и пропустит остальные. Чтобы принудительно продлить один сертификат раньше срока, используйте sudo certbot renew --cert-name example.com --force-renewal, но не делайте это привычкой: принудительные продления засчитываются в лимит на дубликаты сертификатов. Сначала протестируйте командой sudo certbot renew --dry-run.

Где certbot хранит сертификаты?

В /etc/letsencrypt/live/<cert-name>/. Направьте сервер на fullchain.pem и privkey.pem. Это симлинки на самые новые файлы в /etc/letsencrypt/archive/, поэтому пути остаются одинаковыми после каждого продления. Делайте резервную копию всего каталога /etc/letsencrypt, а не только live/.

Может ли certbot выпустить wildcard-сертификат?

Да, но только через DNS-01: используйте DNS-плагин для вашего провайдера либо --manual --preferred-challenges dns. Запрашивайте и example.com, и '*.example.com', потому что wildcard не покрывает «голый» домен. Ручные wildcard-сертификаты не продлеваются сами, если не добавить скрипты-хуки.

Работает ли certbot в Windows?

Уже нет. Certbot прекратил поддержку Windows в феврале 2024 года; 2.9.0 была последней версией с установщиком для Windows. Используйте ACME-клиент для Windows, такой как win-acme (или его преемник simple-acme), Posh-ACME или Certify The Web, либо запускайте certbot внутри WSL 2.

В чём разница между certbot --nginx и certbot certonly?

certbot --nginx получает сертификат и редактирует вашу конфигурацию nginx, чтобы использовать его, добавляя редирект, если вы разрешите. certbot certonly только получает сертификат и сохраняет его в /etc/letsencrypt/live/; строки ssl_certificate вы добавляете сами, а также deploy-хук для перезагрузки nginx после продлений.

Нужен ли мне certbot, если сайт за CDN?

Не для сертификата, который видят посетители: его отдаёт сам CDN на edge. На CDN.com.tr Auto SSL выпускает и продлевает сертификат Let's Encrypt для каждого подключённого домена. Certbot на origin всё ещё можно использовать, если edge подключается к нему по HTTPS.