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. Виклик HTTP-01 від Let's Encrypt означає, що сервери перевірки підключаються до вашого сервера через інтернет. Домашня лабораторія за NAT без перенаправлення порту не підійде, як і імена
.local. HTTP-01 може перевіряти безпосередню IP-адресу, але Let's Encrypt видає сертифікати для IP-адрес лише через профільshortlived, доступний за попереднім увімкненням; термін їхньої дії становить 160 годин. Certbot 2.9.0 з apt не може запитувати ні профілі ACME, ні сертифікати для IP-адрес, тому цьому посібнику потрібне доменне ім’я.dig +short example.comмає повертати адресу вашого VPS. Якщо ви змінювали DNS протягом останньої години, перед випуском сертифіката дочекайтеся завершення TTL старого запису. - Якщо існує запис AAAA, він має бути правильним. Якщо опубліковано запис AAAA, Let's Encrypt завжди спочатку використовує IPv6. Якщо це підключення завершується тайм-аутом, система повторює перевірку через IPv4, але інші помилки не дають такого другого шансу. Запис 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 — випуск від лютого 2024 року із сучасної гілки 2.x, а unattended-upgrades встановлює всі оновлення безпеки, які Ubuntu для нього публікує. Відтоді upstream перейшов до серії 5.x, але цьому посібнику вона не потрібна. Моя рекомендація для цієї ОС: використовуйте apt. Ви не встановлюєте daemon 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Під час першого запуску потрібно вказати три параметри: адресу електронної пошти (Let’s Encrypt більше не зберігає її разом із вашим ACME-обліковим записом і більше не надсилає попередження про завершення строку дії, тому контролювати поновлення потрібно самостійно), погодитися з умовами Let’s Encrypt і вибрати, чи надавати свою адресу електронної пошти EFF. Запитання про редирект більше немає: починаючи з Certbot 1.0 інсталятор Apache за замовчуванням перенаправляє HTTP на HTTPS (саме запитання прибрали у версії 1.4), і це потрібна поведінка. Передайте --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 2027-01-09.
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: другий планувальник лише створить зайві записи в журналах і підвищить ризик досягнення rate limit. Let’s Encrypt оголосив, що з February 10, 2027 для нових сертифікатів типовий строк чинності становитиме 64 дні. Вікно в 30 днів і далі працюватиме: поновлення просто відбуватиметься приблизно на 34-й день, а не на 60-й. На цьому сервері нічого змінювати не потрібно.
systemctl list-timers certbot.timer
sudo certbot renew --dry-runПерша команда показує активний таймер із часом NEXT у межах наступних 24 годин. Розклад передбачає два запуски на день із випадковою затримкою, тому точний час навмисно непередбачуваний (у разі встановлення через snap таймер має значення snap.certbot.renew.timer). Тестовий запуск виконує повну репетицію поновлення в staging-середовищі Let’s Encrypt: challenge справжній, сертифікат не випускається, а 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 на кшталт YE1 або YE2 для ключів ECDSA, чи YR1 або YR2 для ключів RSA, а також notAfter приблизно через 90 днів. Сертифікат, виданий до того, як Let's Encrypt вилучив старіші проміжні сертифікати, до наступного поновлення може містити CN на кшталт R12 або E7. Це не є помилкою. У браузері відображається замок, і після натискання на нього показується той самий видавець. Якщо 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 зазвичай не спричиняє цю помилку: коли спроба через IPv6 завершується тайм-аутом, Let's Encrypt повторює її через IPv4. Проблеми з AAAA зазвичай проявляються як Connection refused або Invalid response від іншого сервера. Виконайте перевірку ззовні VPS: curl -I http://example.com на вашому ноутбуці відтворить перевірку, яку бачить їхній валідатор.
Через повторні спроби ви досягли ліміту частоти запитів.
Error creating new order :: too many failed authorizations (5) for "example.com" in the last 1h0m0s, retry after ... UTC: see https://letsencrypt.org/docs/rate-limits/...Let's Encrypt дозволяє 5 невдалих перевірок для одного hostname, облікового запису та години. Ліміт працює як поповнюване відро: приблизно одна повторна спроба стає доступною кожні 12 хвилин. Часті повторні спроби через непрацюючий firewall швидко вичерпують ліміт. Очікування допоможе, але правильне рішення полягає у зміні підходу: після кожної помилки виконуйте діагностику в staging environment, доки перевірка не завершиться успішно.
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 environment, де діють окремі щедрі ліміти та не випускаються справжні сертифікати, тому там можна безпечно помилятися протягом усього дня. Повторно запускайте реальну команду лише після успішного проходження 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. Ця версія достатньо актуальна для всього матеріалу цього посібника, отримує всі оновлення безпеки, які Ubuntu публікує через 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 і переходить на IPv4 лише після тайм-ауту. Перевірте виправлення із зовнішньої мережі за допомогою 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 на сервері.