SSD Nodes Learn
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-07-24

Установка Certbot для Apache на Ubuntu 24.04

Узнайте, как установить Certbot 2.9.0 через apt на Ubuntu 24.04. Разбор ошибки ServerName и настройки Let's Encrypt для Apache без использования snap.

Что вы создаете

Сайт на Apache в Ubuntu 24.04, работающий по протоколу HTTPS с бесплатным сертификатом Let's Encrypt, которому доверяют браузеры. Сертификат выпускается через Certbot и автоматически обновляется с помощью таймера systemd, который не требует вашего участия. Для выполнения задачи достаточно одной команды. Любые ошибки возникают до выполнения этой команды: отсутствие ServerName в vhost, закрытый 80 порт на брандмауэре провайдера или DNS, указывающий на старый сервер. Поэтому большая часть этого руководства посвящена предварительным условиям; в тексте указаны точные строки ошибок для каждой проблемы.

Два примечания. Если вы используете nginx, алгоритм действий аналогичен, но плагин и конфигурационные файлы отличаются — используйте версию этого руководства для nginx. Если объект защиты доступен только внутри сети (например, панель администратора на приватном адресе или тестовый сервер), центр сертификации вам не требуется; самоподписанный сертификат проще в настройке и работает без доступа к интернету.

Предварительные условия и три причины сбоя до запуска Certbot

  • Apache уже обслуживает ваш сайт по протоколу HTTP. Плагин Certbot для Apache редактирует существующий конфигурационный файл сайта, а не создает новый. Если вы используете чистый VPS, сначала установите LAMP stack on Ubuntu 24.04, а затем вернитесь к этой инструкции — данный гайд является недостающим разделом по TLS.
  • Публичный домен с A-записью, указывающей на адрес вашего VPS. Проверка HTTP-01 требует, чтобы серверы Let's Encrypt подключались к вашему серверу через интернет. Это невозможно в домашних лабораториях за NAT без проброса портов, без .local имен или при использовании только IP-адресов. dig +short example.com должен возвращать адрес вашего VPS. Если вы изменили DNS в последний час, дождитесь истечения TTL старой записи перед выпуском сертификата.
  • Если существует AAAA-запись, она должна быть корректной. Let's Encrypt отдает приоритет IPv6 при наличии опубликованной AAAA-записи. Устаревшая AAAA-запись приведет к ошибке валидации, даже если curl с вашего ноутбука (скорее всего, через IPv4) проходит успешно. Опубликуйте корректную AAAA-запись или не публикуйте её вовсе.

Порты 80 и 443 должны быть открыты в ufw, а также в сетевом экране вашего провайдера — большинство панелей хостинга имеют второй firewall, который не виден операционной системе. Проверка HTTP-01 выполняется именно через порт 80; вы не сможете выполнить её, используя только порт 443.

sudo ufw allow "Apache Full"
sudo ufw status

Если все условия соблюдены, выполнение задачи займет пятнадцать минут, десять из которых уйдет на чтение.

Snap или apt Certbot? В версии 24.04 пакет apt теперь подходит

Certbot перешел на распространение через snap несколько лет назад по веской причине: пакеты в дистрибутивах устаревают. Ubuntu 20.04 поставляла Certbot 0.40 и не обновляла его, из-за чего разработчики устали исправлять пятилетние ошибки. В версии 24.04 эта проблема устранена — в архиве содержится Certbot 2.9.0 (актуальная версия), а unattended-upgrades обеспечивает своевременные обновления. Моя рекомендация для этой ОС: используйте apt. Вы не будете использовать демон snapd, плагин Apache устанавливается в рамках той же транзакции, а таймер обновления интегрируется с systemd стандартным для Debian способом.

sudo apt update
sudo apt install -y certbot python3-certbot-apache
certbot --version

Верный результат: certbot 2.9.0. Пакет python3-certbot-apache является плагином, который считывает и редактирует ваши конфигурации Apache — без него certbot --apache завершится ошибкой The requested apache plugin does not appear to be installed.

Использование snap все еще оправдано в двух случаях: если вам нужна самая новая версия Certbot в день ее выхода или если вам необходим DNS-плагин, распространяемый только через snap (некоторые плагины провайдеров certbot-dns-* распространяются именно так). Если вы выберете этот путь:

sudo apt remove -y certbot python3-certbot-apache
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Какой бы вариант вы ни выбрали, никогда не используйте оба одновременно. Две установки приведут к конфликту двух планировщиков обновления за /etc/letsencrypt, а certbot, который найдет ваша оболочка в PATH, может не быть тем инструментом, который управляет вашими сертификатами. Строка apt remove выше не является необязательным украшением.

Настройки vhost для Certbot должны быть созданы — ServerName является ключевым параметром

certbot --apache работает следующим образом: программа находит виртуальный хост на порту 80, чей ServerName или ServerAlias совпадает с каждым переданным -d доменом. Это подтверждает владение доменом. Затем Certbot создает SSL-копию этого vhost. Если совпадения по ServerName нет, поиск не удался. В стандартной конфигурации 000-default.conf в Ubuntu параметр ServerName закомментирован. Эта закомментированная строка является основной причиной ошибки при выполнении основной команды данного руководства.

Прежде чем использовать Certbot, настройте виртуальный хост для сайта на основе имени. Создайте /etc/apache2/sites-available/example.com.conf:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com
    ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>

Включите его и убедитесь, что Apache корректно считывает конфигурацию и направляет трафик на этот хост:

sudo a2ensite example.com.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
sudo apache2ctl -S

Команда configtest должна вывести Syntax OK. Если также выводится AH00558: apache2: Could not reliably determine the server's fully qualified domain name, это предупреждение о глобальном параметре ServerName, а не о вашем vhost. В данном случае это не критично, и ошибка подавляется с помощью echo "ServerName $(hostname -f)" | sudo tee /etc/apache2/conf-available/servername.conf && sudo a2enconf servername && sudo systemctl reload apache2.

Результат -S является определяющим. Вам нужна строка вида port 80 namevhost example.com (/etc/apache2/sites-enabled/example.com.conf:1) с параметром alias www.example.com под ней. Apache сообщает о символьной ссылке sites-enabled, которую он фактически прочитал, а не о файле, который вы редактировали в sites-available. Если example.com не указан для порта 80, Certbot также не сможет его найти.

Выпуск сертификата: certbot --apache

sudo certbot --apache -d example.com -d www.example.com

При первом запуске программа запросит три параметра: адрес электронной почты (используется для вашего ACME-аккаунта и важных уведомлений CA; Let's Encrypt больше не отправляет предупреждения об истечении срока действия, поэтому вы должны самостоятельно отслеживать обновления), согласие с условиями Let's Encrypt и разрешение на передачу вашего email организации EFF. Вопрос о перенаправлении (redirect) больше не задается: начиная с версии Certbot 2.0, установщик Apache по умолчанию перенаправляет HTTP на HTTPS, что является предпочтительным. Используйте флаг --no-redirect, если вам действительно необходимо оставить plain HTTP для обслуживания контента.

При успешном завершении вы увидите следующее сообщение. Рекомендуется внимательно прочитать его, а не просто просмотреть:

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/example.com/privkey.pem
This certificate expires on 2026-10-14.

Deploying certificate
Successfully deployed certificate for example.com to /etc/apache2/sites-available/example.com-le-ssl.conf
Successfully deployed certificate for www.example.com to /etc/apache2/sites-available/example.com-le-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://example.com and https://www.example.com

За этим сообщением Certbot выполнил четыре действия: включил модуль ssl в Apache, если он не был включен, создал example.com-le-ssl.conf — копию вашего vhost в *:443 с путями к SSLEngine on и сертификату, включил этот модуль и добавил блок RewriteRule в исходный vhost для порта 80, который выполняет 301-й редирект на HTTPS. Ваш исходный файл vhost редактируется, а не заменяется; SSL-копия создается рядом, чтобы вы могли просмотреть каждую добавленную строку.

Где фактически хранится сертификат и почему его нельзя копировать

Все файлы находятся в директории /etc/letsencrypt/live/example.com/: fullchain.pem (сертификат и промежуточная цепочка — то, на что должны указывать серверы), privkey.pem (приватный ключ, доступный только для чтения root), а также cert.pem и chain.pem для программного обеспечения, требующего отдельные файлы. Эти файлы являются символическими ссылками на /etc/letsencrypt/archive/. Такая косвенная адресация используется для механизма обновления: при обновлении новые файлы записываются в archive/, а символические ссылки перенаправляются на них. Если вы укажете в другом ПО пути к live/, оно будет автоматически получать обновления; если вы скопируете файлы в другое место, через 90 дней возникнет сбой в работе сервиса.

Также важно знать о файле /etc/letsencrypt/renewal/example.com.conf. В нем записаны данные о выпуске сертификата — authenticator = apache, installer = apache, домены. Это позволяет процессу обновления проходить в автоматическом режиме, включая последующую перезагрузку Apache.

Обновление уже запланировано — проверьте его, а не запускайте заново

Сертификаты Let's Encrypt по умолчанию действуют 90 дней. Пакет apt уже установил необходимый механизм: таймер systemd, который запускает Certbot дважды в день в случайное время. Он обновляет любой сертификат, до истечения срока действия которого осталось менее 30 дней. Не добавляйте дополнительные задания cron; второй планировщик создаст только лишние записи в логах и риск превышения лимитов (rate-limit).

systemctl list-timers certbot.timer
sudo certbot renew --dry-run

Первая команда показывает активный таймер со временем NEXT в течение ближайших 24 часов. Расписание предусматривает запуск дважды в сутки с рандомной задержкой, поэтому точное время намеренно непредсказуемо (при установке через snap таймер — snap.certbot.renew.timer). Команда dry run выполняет полную имитацию обновления через staging-сервер Let's Encrypt — проверка проходит с реальным challenge, но без выпуска сертификата и без расхода лимитов. Корректный результат заканчивается следующим:

Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/example.com/fullchain.pem (success)

Если dry run завершается ошибкой, то реальное обновление через ~60 дней также не удастся. Исправьте проблему сейчас, пока срок действия текущего сертификата еще не подходит к концу. Частой причиной является правило firewall, добавленное после выпуска сертификата, которое снова закрыло порт 80.

Проверка с помощью curl и состояние значка замка

curl -sI http://example.com | head -n 3
curl -I https://example.com
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -issuer -dates

Первый запрос должен вернуть HTTP/1.1 301 Moved Permanently с заголовком Location: https://example.com/ — это перенаправление, установленное Certbot. Второй запрос должен вернуть HTTP/1.1 200 OK без ошибок TLS в curl. Третий запрос выводит издателя — строку O = Let's Encrypt с коротким CN, например R12 или E7, — и notAfter примерно через 90 дней. В браузере отображается значок замка; при нажатии на него отображается тот же издатель. Если curl работает корректно, а браузер выдает предупреждение, это почти наверняка означает использование кэшированной страницы или неверного hostname, а не проблему с сертификатом.

Несколько сайтов: один SAN-сертификат или отдельный сертификат для каждого сайта

Оба варианта работают; процесс обновления идентичен. Для несвязанных сайтов на одном сервере выполняйте команду выпуска один раз для каждого сайта. Каждый сайт получит свою директорию в live/ и свой конфигурационный файл обновления. Ошибка в одном домене не препятствует обновлению остальных. Это рекомендуемый метод.

Для одного сайта с несколькими именами используйте один SAN-сертификат — один сертификат может содержать до 100 имен. Вы уже выполняли это выше с помощью example.com и www.example.com. Чтобы позже добавить имя в существующий сертификат, перевыпустите его, указав название сертификата и полный новый список имен:

sudo certbot --apache --cert-name example.com -d example.com -d www.example.com -d blog.example.com

Certbot обнаружит изменение набора доменов, запросит подтверждение расширения и заменит сертификат на месте. Путь live/ остается прежним, поэтому другие настройки менять не нужно. Учтите, что новый список полностью заменяет старый, а не дополняет его: если исключить www из команды, старый домен будет удален из нового сертификата.

Wildcards требуют DNS-01, а wildcard-сертификаты обычно не нужны

HTTP-01 не может выпустить *.example.com — размещение файла на веб-сервере подтверждает владение одним хостом, а не всем пространством имен. Для wildcard-сертификатов требуется проверка DNS-01: Certbot создает TXT-запись в _acme-challenge.example.com. На практике это означает использование certbot-dns-* плагина с API-ключами вашего DNS-провайдера или ручное редактирование TXT-записей при каждом обновлении через --manual (это неудобно — не планируйте работу таким образом). Подробное руководство — от механики TXT-записей до плагина для автоматического обновления — доступно в wildcard certificates with Certbot over DNS-01. Совет: если у вас есть четыре известных поддомена, проще выпустить SAN-сертификат со списком всех четырех имен, чем использовать wildcard. Для этого не требуются API-ключи DNS на сервере.

Режимы сбоев и сообщения об ошибках

Certbot не запускается из-за ошибки в конфигурации Apache.

The apache plugin is not working; there may be problems with your existing configuration.
The error was: MisconfigurationError('Error while running apache2ctl configtest.\n\nAction \'configtest\' failed.\nThe Apache error log may have more information.\n\nAH00526: Syntax error on line 12 of /etc/apache2/sites-enabled/example.com.conf')

Плагин выполняет configtest перед началом работы и прекращает выполнение, если в Apache обнаружены ошибки. Сообщения \n являются точными, так как Certbot выводит repr исключения. Выполните sudo apache2ctl configtest самостоятельно: команда укажет файл и строку. Обычно это опечатка при ручном редактировании, SSLCertificateFile на несуществующий путь или ссылка на неактивный модуль. Исправьте ошибку до появления Syntax OK, затем повторно запустите Certbot.

Ни один vhost не соответствует домену.

Unable to find a virtual host listening on port 80 which is currently the only challenge port.

Это ошибка отсутствия ServerName, обнаруженная на этапе выпуска сертификата. Certbot проверил все включенные vhost на порту 80 на наличие ServerName/ServerAlias, соответствующих вашему -d, и ничего не нашел. sudo apache2ctl -S показывает фактическую маршрутизацию Apache; добавьте строку ServerName в нужный vhost, перезагрузите конфигурацию и повторите попытку. Схожая проблема: проверка попадает на неверный vhost — ответ на challenge возвращается Invalid response ... 404, так как запрос перехватил другой сайт. Диагноз и инструмент те же: apache2ctl -S.

Тайм-аут проверки (Validation times out).

Certbot failed to authenticate some domains (authenticator: apache).
...
Detail: ...: Timeout during connect (likely firewall problem)

Let's Encrypt не удалось установить TCP-соединение с портом 80 по адресу, указанному в вашей DNS. Возможные причины (от наиболее вероятной к наименее): сетевой экран провайдера (отдельно от ufw, настраивается в панели хостинга), правила ufw, разрешающие только 443 или только SSH, DNS все еще указывает на старый сервер или проблема устаревших записей AAAA — серверы Let's Encrypt пытаются использовать IPv6, а ваш сервер отвечает только на IPv4. Проверьте доступность извне VPS: выполнение curl -I http://example.com с вашего ноутбука воспроизведет состояние, которое видит валидатор.

Вы исчерпали лимит попыток (Rate limit).

Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/

Let's Encrypt разрешает 5 неудачных проверок на один hostname в час для одного аккаунта. После обновления лимитов в 2025 году используется механизм «наполняемого ведра»: лимит восстанавливается примерно на одну попытку каждые 12 минут. Частые повторные запросы при неисправном брандмауэре быстро исчерпают этот лимит. Ожидание поможет, но правильный метод — отладка: после любой ошибки используйте staging-среду до успешного завершения.

sudo certbot certonly --apache --dry-run -d example.com -d www.example.com

Обратите внимание на certonly: --dry-run принимается только подкомандами certonly и renew, а при использовании команды certbot --apache --dry-run без аргументов выполнение будет отклонено с ошибкой --dry-run currently only works with the 'certonly' or 'renew' subcommands. Режим dry run выполняет проверку в staging-среде, у которой свои лимиты и которая не выдает реальные сертификаты, поэтому там можно проводить отладку сколько угодно. Запускайте основную команду только после успешного прохождения staging. Другие лимиты — 50 сертификатов на зарегистрированный домен в неделю и 5 дубликатов одного и того же имени в неделю — вы встретите только если скрипт зациклен на перевыпуске.

После настройки HTTPS помните, что сертификат защищает транспорт, а не сервер: порт 22 все еще открыт для подбора паролей. Следующим логичным шагом будет настройка Fail2ban на Ubuntu 24.04.

FAQ

Стоит ли устанавливать Certbot через snap или apt для Apache на Ubuntu 24.04?

Используйте apt. В Ubuntu 24.04 поставляется Certbot версии 2.9.0. Этого достаточно для всех задач в данном руководстве. Пакет получает обновления безопасности через unattended-upgrades и не требует наличия snapd. Выбирайте snap только если вам требуется самая новая версия немедленно или если вам нужен DNS-плагин, распространяемый исключительно через snap. Если вы решите сменить способ установки, сначала выполните apt remove certbot python3-certbot-apache, чтобы избежать одновременной работы двух планировщиков обновления.

Почему Certbot выводит ошибку "Unable to find a virtual host listening on port 80"?

Это происходит потому, что ни один включенный vhost на порту 80 не имеет ServerName или ServerAlias, соответствующих домену, указанному через -d. В стандартном vhost Ubuntu параметр ServerName закомментирован. Выполните sudo apache2ctl -S, найдите (или создайте) vhost, который должен обслуживать этот домен, добавьте ServerName example.com, перезагрузите Apache и снова запустите Certbot.

Как исправить ошибку "Timeout during connect (likely firewall problem)"?

Сервер Let's Encrypt не смог подключиться к порту 80 по адресу, опубликованному в вашей DNS. Проверьте сетевой экран (firewall) в панели управления провайдера, а также ufw. Убедитесь, что dig +short example.com возвращает IP этого VPS, и удалите или исправьте устаревшие AAAA-записи — при наличии IPv6 проверка приоритетно использует его. Проверьте исправление с внешнего устройства с помощью curl -I http://example.com, а затем выполните пробную проверку с помощью sudo certbot certonly --apache --dry-run -d example.com перед выпуском реального сертификата.

Обновляет ли Certbot сертификаты автоматически на Ubuntu 24.04?

Да. Пакет apt устанавливает certbot.timer — таймер systemd, который запускается дважды в день и обновляет любой сертификат, до истечения срока действия которого осталось менее 30 дней, после чего перезагружает Apache. Пакет snap использует snap.certbot.renew.timer для выполнения той же задачи. Проверьте статус с помощью systemctl list-timers certbot.timer и выполните пробную проверку с помощью sudo certbot renew --dry-run — не создавайте собственные задания cron дополнительно.

Как получить wildcard-сертификат с помощью Certbot и Apache?

Для wildcard-сертификатов требуется проверка DNS-01: Certbot должен разместить TXT-запись в _acme-challenge.example.com. Для этого необходим certbot-dns-*-плагин с API-учетными данными вашего DNS-провайдера (альтернатива --manual требует ручного редактирования TXT-записей при каждом обновлении). Если у вас всего несколько известных поддоменов, проще использовать сертификат SAN с их явным перечислением — это позволит не хранить API-ключи DNS на сервере.