Certbot для Apache на Ubuntu 24.04: встановлення
Одна команда налаштовує сертифікат Let's Encrypt для Apache на Ubuntu 24.04. apt містить Certbot 2.9.0 без snap, але ServerName може зупинити видачу.
Що ви налаштовуєте
Сайт Apache на Ubuntu 24.04, доступний через HTTPS із безкоштовним сертифікатом Let's Encrypt, якому довіряють браузери. Сертифікат видає Certbot, а systemd timer автоматично поновлює його без подальшого втручання. Команда, яка виконує всю роботу, складається з одного рядка. Усе, що може піти не так, зазвичай виникає до виконання цього рядка: vhost без ServerName, закритий порт 80 у firewall провайдера або DNS, який досі вказує на старий сервер. Тому в цьому посібнику більшість уваги приділено попереднім умовам. Також наведено точний текст помилки, який виводить кожна з цих помилок.
Два уточнення щодо сфери застосування. Якщо ваш вебсервер — nginx, процес має таку саму загальну структуру, але plugin і конфігурації відрізняються. У такому разі скористайтеся версією цього посібника для nginx. Якщо ж сервіс, для якого потрібне шифрування, доступний лише всередині мережі — наприклад, це панель адміністратора на приватній адресі або staging-сервер, до якого ніхто більше не підключається, — certificate authority вам не потрібен. Самопідписаний сертифікат потребує менше налаштувань і працює без доступу до мережі.
Передумови та три способи, через які все не працює ще до запуску Certbot
- Apache уже обслуговує ваш сайт через звичайний HTTP. Плагін Apache для Certbot змінює наявний сайт, але не створює його. Якщо ви починаєте з чистого VPS, спочатку розгорніть LAMP stack в Ubuntu 24.04, а потім поверніться до цього матеріалу: це відсутній розділ про TLS.
- Публічний домен із записом A, який указує на адресу вашого VPS. Перевірка Let's Encrypt через HTTP-01 означає, що їхні сервери валідації підключаються до вашого сервера через інтернет: домашня лабораторія за NAT не підходить без перенаправлення порту, імена
.localне підходять, як і самі IP-адреси.dig +short example.comмає повертати адресу вашого VPS. Якщо ви змінювали DNS протягом останньої години, перед отриманням сертифіката дочекайтеся завершення дії TTL старого запису. - Якщо існує запис AAAA, він має бути правильним. Якщо опубліковано запис AAAA, Let's Encrypt надає перевагу IPv6. Тому застарілий AAAA спричинить помилку валідації, навіть якщо
curlіз вашого ноутбука, імовірно через IPv4, працює належним чином. Опублікуйте правильний AAAA або не публікуйте його взагалі.
Порти 80 і 443 мають бути відкриті в ufw та в мережевому firewall вашого провайдера. У більшості панелей керування хостингом є додатковий 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 — не необов’язкове оформлення.
Віртуальний хост, який редагує Certbot, уже має існувати; вирішальне значення має ServerName
certbot --apache знаходить віртуальний хост для порту 80, у якому ServerName або ServerAlias відповідає кожному домену -d, який ви передаєте. Потім він підтверджує контроль над доменом через цей віртуальний хост і створює його SSL-версію. Якщо відповідного 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 -Sconfigtest має вивести Syntax OK. Якщо також виводиться AH00558: apache2: Could not reliably determine the server's fully qualified domain name, це попередження про глобальний ServerName, а не про ваш віртуальний хост. У цьому випадку воно не є критичним. Його можна вимкнути за допомогою 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 і вказати, чи дозволяєте ви передавати свою адресу електронної пошти EFF. Запитання про редирект більше немає: починаючи з Certbot 2.0 інсталятор Apache за замовчуванням перенаправляє HTTP на HTTPS, що саме й потрібно. Передайте --no-redirect, лише якщо вам справді потрібно й надалі обслуговувати вміст через звичайний 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 виконав чотири дії: увімкнув модуль Apache ssl, якщо його ще не було ввімкнено; створив example.com-le-ssl.conf — копію вашого vhost у *:443 із SSLEngine on і шляхами до сертифіката; увімкнув його; і додав блок RewriteRule до початкового vhost для порту 80, який перенаправляє весь трафік на HTTPS кодом 301. Початковий файл vhost редагується, а не замінюється. Окремий SSL-варіант розташований поруч, і в ньому можна прочитати кожен доданий рядок.
Де насправді зберігається сертифікат і чому його не можна копіювати
Усе зберігається в /etc/letsencrypt/live/example.com/: fullchain.pem (сертифікат разом із проміжним ланцюжком, на який мають посилатися сервери), privkey.pem (закритий ключ, доступний лише для читання користувачу root), а також cert.pem і chain.pem для програм, яким потрібні ці компоненти окремо. Це символічні посилання на /etc/letsencrypt/archive/, і саме ця непряма схема забезпечує поновлення: під час поновлення нові файли записуються в archive/, а символічні посилання перемикаються на них. Вкажіть для іншого програмного забезпечення шляхи live/, і воно автоматично використовуватиме поновлені файли. Якщо скопіювати файли в інше місце, через 90 days ви самі створите причину простою.
Ще один важливий файл — /etc/letsencrypt/renewal/example.com.conf. У ньому записано, як було видано цей сертифікат, authenticator = apache, installer = apache, а також домени, щоб поновлення могло повторити процес без участі користувача, зокрема перезавантажити Apache після цього.
Поновлення вже заплановано: перевірте його, а не налаштовуйте повторно
Сертифікати Let’s Encrypt за задумом дійсні 90 днів, а пакет apt уже встановив необхідні компоненти: таймер systemd, який запускає Certbot двічі на день у випадковий час і поновлює всі сертифікати, до завершення дії яких залишилося не більше 30 днів. Не додавайте cron job: другий планувальник лише створить зайві записи в журналах і збільшить ризик досягнення rate limit.
systemctl list-timers certbot.timer
sudo certbot renew --dry-runПерша команда показує, що таймер активний. Значення NEXT має вказувати на час у наступні 24 години. Розклад передбачає два запуски на день із випадковою затримкою, тому точний час навмисно непередбачуваний. У разі встановлення через snap замість цього таймером буде snap.certbot.renew.timer. Тестовий запуск виконує повну репетицію поновлення в staging-середовищі Let's Encrypt: використовується справжня перевірка, але сертифікат не видається і rate limit не витрачається. У разі успіху результат завершується так:
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/example.com/fullchain.pem (success)Якщо тестовий запуск завершується помилкою, фактичне поновлення приблизно через 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 без повідомлення curl про помилку TLS. Третя виводить видавця, рядок O = Let's Encrypt із коротким CN, наприклад R12 або E7, і notAfter приблизно через 90 днів. У браузері відображається значок замка. Якщо натиснути його, буде показано того самого видавця. Якщо curl працює, а браузер показує попередження, майже напевно відкривається кешована сторінка або використовується неправильне ім’я хоста, а не виникла проблема із сертифікатом.
Кілька сайтів: один 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.comCertbot виявить зміну набору доменів і попросить підтвердити розширення. Після цього він замінить сертифікат на місці за тим самим шляхом live/, тому більше нічого змінювати не потрібно. Зверніть увагу: цей список замінює попередній, а не доповнює його. Якщо не вказати www у цій команді, новий сертифікат непомітно втратить його.
Для wildcard потрібен DNS-01, але зазвичай wildcard вам не потрібен
HTTP-01 не може видати *.example.com: розміщення файлу на вебсервері підтверджує контроль над одним іменем хоста, а не над усім простором імен. Для wildcard потрібна перевірка DNS-01: Certbot створює TXT-запис у _acme-challenge.example.com. На практиці це означає використання плагіна certbot-dns-* з обліковими даними API вашого DNS-провайдера або ручне редагування TXT-записів під час кожного поновлення за допомогою --manual (це незручно, тому не плануйте рішення на його основі). Повний опис — від механізму TXT-записів до плагіна, який автоматично поновлює сертифікат без втручання, — наведено в розділі wildcard-сертифікати з Certbot через DNS-01. Практична порада: якщо ви маєте чотири відомі субдомени, SAN-сертифікат із переліком усіх чотирьох буде простішим за wildcard і не потребуватиме зберігати ключі DNS API на сервері.
Режими відмови та повідомлення, які ви побачите
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.
Час очікування перевірки минув.
Certbot failed to authenticate some domains (authenticator: apache).
...
Detail: ...: Timeout during connect (likely firewall problem)Let’s Encrypt не зміг встановити TCP-з’єднання з портом 80 за адресою, яку оголошує ваш DNS. Найімовірніші причини, у порядку ймовірності: мережевий firewall вашого провайдера, окремий від ufw і налаштований у панелі хостингу; набір правил ufw, який дозволяє лише 443 або лише SSH; DNS усе ще вказує на попередній сервер; застарілий запис AAAA — сервери Let’s Encrypt спробували підключитися через IPv6, але ваш сервер відповідає лише через IPv4. Перевірте з’єднання ззовні VPS: curl -I http://example.com на вашому ноутбуці відтворить те, що бачить їхній валідатор.
Повторні спроби призвели до перевищення ліміту.
Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/Let’s Encrypt дозволяє 5 невдалих перевірок одного hostname для одного облікового запису протягом години. Після зміни системи rate limit у 2025 році це поповнюваний ліміт: приблизно одна повторна спроба відновлюється кожні 12 хвилин. Часті повторні спроби з неправильно налаштованим firewall швидко вичерпують цей ліміт. Очікування допоможе, але правильне рішення полягає у зміні підходу: після будь-якої помилки виконуйте діагностику в 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. Тестовий запуск виконує перевірку через staging, де діють окремі щедрі ліміти й не видаються реальні сертифікати, тому там можна безпечно отримувати помилки протягом усього дня. Запускайте реальну команду лише після успішної перевірки у staging. Інші ліміти — 50 сертифікатів для зареєстрованого домену на тиждень і 5 дублікатів одного набору імен на тиждень — ви перевищите лише в разі, якщо скрипт зациклено перевидає сертифікат.
Після ввімкнення HTTPS пам’ятайте: сертифікат захищає транспорт, а не сервер. Порт 22 і далі щодня приймає спроби вгадати пароль. Логічним наступним кроком на 30 хвилин буде налаштувати 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. Якщо переходите на 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 повертає адресу цього 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-сертифікат із їхнім явним переліком. Це також дає змогу не зберігати ключі DNS API на сервері.