===== Настройка автоматического обновления SSL сертификатов Let's Encrypt в NGINX с помощью Certbot на Debian Linux 13 ===== {{.:pasted:20250905-134232.png }} Базовую настройку веб-сервера **NGINX** для поддержки **HTTPS** мы рассматривали ранее в заметке [[web-server-nginx:how-to-install-lemp-web-server-on-ubuntu-14-04:how-to-install-ssl-certificate-for-https-on-nginx-for-wordpress-phpbb-dokuwiki-sites|Настройка веб-сервера на базе стека LEMP в Ubuntu Server 14.04 LTS. Часть 11. Настройка поддержки HTTPS в Nginx, Wordpress и phpBB]]. В этой заметке мы немного расширим эту тему и рассмотрим то, как можно автоматизировать процесс регулярного обновления SSL сертификатов, привязанных к сайтам nginx. Бесплатные криптографические сертификаты **X.509** будем получать в центре сертификации [[https://letsencrypt.org/ru/|Let's Encrypt]], а с помощью пакета **certbot** настроим автоматизацию обновления этих сертификатов с интеграцией в конфигурацию веб-сервера nginx. ---- ==== Установка Certbot ==== Устанавливаем пакет **certbot** из стандартных репозиториев Debian Linux
# apt install certbotСоздаём каталог для временных файлов Let's Encrypt и делаем его владельцем пользователя и группу, в контексте которых работает веб-сервер:
# mkdir /var/www/letsencrypt # chown www-data:www-data /var/www/letsencrypt---- ==== Подготовка NGINX ==== Выносим текущую конфигурацию SSL из /etc/nginx/nginx.conf в отдельный файл /etc/nginx/snippets/ssl.conf
# nano /etc/nginx/snippets/ssl.conf
# nano /etc/nginx/snippets/letsencrypt.conf
# nano /etc/nginx/sites-available/mydomain.conf
# certbot register -m petya@mydomain.ru Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please read the Terms of Service at: https://letsencrypt.org/documents/LE-SA-v1.5-February-24-2025.pdf You must agree in order to register with the ACME server. Do you agree? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: Yes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Would you be willing, once your first certificate is successfully issued, to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: No Account registered.Регистрационные файлы попадут в подкаталог ''/etc/letsencrypt/accounts'':
# tree /etc/letsencrypt/ /etc/letsencrypt/ ├── accounts │ └── acme-v02.api.letsencrypt.org │ └── directory │ └── 4f50a3d608bead7e9ae31a15b605af4a │ ├── meta.json │ ├── private_key.json │ └── regr.json ├── cli.ini └── renewal-hooks ├── deploy ├── post └── pre 9 directories, 4 files---- ==== Запрос сертификатов ==== Перед тестированием следует убедиться в том, что сайты, для которых будут запрашиваться сертификаты, доступны из Интернета. Тестируем работу certbot без фактической генерации сертификатов Let's Encrypt ("холостой" запуск):
# certbot certonly --dry-run --webroot -w /var/www/letsencrypt -d mydomain.ru \ -d blog.mydomain.ru -d forum.mydomain.ru Saving debug log to /var/log/letsencrypt/letsencrypt.log Simulating a certificate request for mydomain.ru and 2 more domains The dry run was successful.Фактически запрашиваем сертификаты Let's Encrypt:
# certbot certonly --webroot -w /var/www/letsencrypt -d mydomain.ru \ -d blog.mydomain.ru -d forum.mydomain.ru Saving debug log to /var/log/letsencrypt/letsencrypt.log Requesting a certificate for mydomain.ru and 2 more domains Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/mydomain.ru/fullchain.pem Key is saved at: /etc/letsencrypt/live/mydomain.ru/privkey.pem This certificate expires on 2025-11-15. These files will be updated when the certificate renews. Certbot has set up a scheduled task to automatically renew this certificate in the background. ...---- ==== Конфигурация NGINX ==== Добавляем полученные сертификаты в ''ssl.conf'', закомментировав ссылки на используемые ранее сертификаты длительного срока действия:
# nano /etc/nginx/snippets/ssl.conf
# systemctl restart nginx---- ==== Автоматизация обновления ==== Срок действия SSL сертификатов Let's Encrypt - 3 месяца. Настроим автоматическое обновление сертификатов, чтобы не следить за истечением срока и не обновлять вручную каждый раз эти сертификаты. Выполним проверку обновления ("холостой" запуск):
# certbot renew --dry-run Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Processing /etc/letsencrypt/renewal/mydomain.ru.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Simulating renewal of an existing certificate for mydomain.ru and 2 more domains - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Congratulations, all simulated renewals succeeded: /etc/letsencrypt/live/mydomain.ru/fullchain.pem (success) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Если проверка прошла без ошибок, то можем выполнить фактическое обновление:
# certbot renewЕсли срок действия сертификата не близок к окончанию, то он обновлён не будет. Если требуется выполнить форсированное обновление, безотносительно строка действия сертификата, то выполняем такой запуск:
# certbot renew --force-renewalВ конфиг ''/etc/letsencrypt/renewal/mydomain.ru.conf'' можно добавить хук для перезапуска веб-сервера после обновления сертификатов
renew-hook = systemctl reload nginx.service
Но более простым вариантом передачи хука является запуск certbot с передачей хуков в качестве параметра.
Этим мы и воспользуемся для того, чтобы настроить автоматическое применение обновлённых сертификатов службой веб-сервера.
В нашем случае после установки пакета **certbot** в системе появляются два новых юнита **systemd**, поэтому создавать собственные юниты, как это описано, например, [[https://internet-lab.ru/certbot_debian|здесь]], у нас необходимости нет.
Проверим наличие этих юнитов:
# systemctl list-unit-files | grep certbot UNIT FILE STATE PRESET ... certbot.service static - certbot.timer enabled enabled ...Как видим, есть два юнита: * Юнит **certbot.service** отвечает за конфигурацию запуска certbot * Юнит **certbot.timer** отвечает за автоматический запуск юнита certbot.service по определённому расписанию. По умолчанию юниты сконфигурированы следующим образом:
# systemctl cat certbot.service # /usr/lib/systemd/system/certbot.service [Unit] Description=Certbot Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html Documentation=https://certbot.eff.org/docs [Service] Type=oneshot ExecStart=/usr/bin/certbot -q renew --no-random-sleep-on-renew PrivateTmp=true
# systemctl cat certbot.timer # /usr/lib/systemd/system/certbot.timer [Unit] Description=Run certbot twice daily [Timer] OnCalendar=*-*-* 00,12:00:00 RandomizedDelaySec=43200 Persistent=true [Install] WantedBy=timers.targetТаким образом, в конфигурации по умолчанию этими двумя юнитами настроен запуск команды "''certbot -q renew --no-random-sleep-on-renew''" с расписанием дважды в сутки с рандомизированным сдвигом (RandomizedDelaySec) чтобы избежать DDoS Let's Encrypt. Если по какой-то причине таймер не включен, то включаем и запускаем его
# systemctl enable --now certbot.timerУбедимся в том, что таймер появился в списке активных таймеров:
# systemctl list-timers NEXT LEFT LAST PASSED UNIT ACTIVATES ... 2025-08-22 20:43:01 10h 2025-08-22 09:58:30 2min 42s ago certbot.timer certbot.service ...В такой конфигурации обновление сертификатов с помощью certbot произойдёт автоматически тогда, когда до окончания срока действия сертификата останется меньше 30 дней. И всё что нам остаётся - настроить применение новых сертификатов в конфигурации ngix. В Debian пакетный certbot кладёт хуки в каталог ''/etc/letsencrypt/renewal-hooks/deploy/''. Создадим хук в виде простого скрипта:
# nano /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
# chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.shСозданный нами хук ''reload-nginx.sh'' не должен срабатывать при каждом запуске службы **certbot.service** инициированном таймером **certbit.timer** (в нашем случае ~ каждые 12 часов), но должен сработать только в момент, когда Let’s Encrypt реально выпустит новый сертификат (раз в ~60–90 дней, если срок жизни стандартный). Обратите внимание на то, что созданный нами хук в каталоге ''/etc/letsencrypt/renewal-hooks/deploy/'' имеет глобальный характер. То есть он будет выполняться при каждой процедуре обновления certboot вне зависимости от того, каким приложением внутри нашей системы эти сертификаты используются. В некоторых случаях в рамках одного сервера могут работать разные приложения, использующие разные сертификаты Let’s Encrypt. В таких ситуациях можно использовать иной подход к управлению хуками и конфигурация перезапуска приложений может настраиваться не глобально в ''/etc/letsencrypt/renewal-hooks/deploy/'', а персонально для каждого сайта через редактирование файлов вида ''/etc/letsencrypt/renewal/mydomain.ru.conf''. В этом файле можно добавить директиву перезапуска нужного приложения в секцию ''[renewalparams]''
# tree /etc/letsencrypt/live/ /etc/letsencrypt/live/ ├── mydomain.ru │ ├── cert.pem -> ../../archive/mydomain.ru/cert2.pem │ ├── chain.pem -> ../../archive/mydomain.ru/chain2.pem │ ├── fullchain.pem -> ../../archive/mydomain.ru/fullchain2.pem │ ├── privkey.pem -> ../../archive/mydomain.ru/privkey2.pem │ └── README ├── mydomain.ru-0001 │ ├── cert.pem -> ../../archive/mydomain.ru-0001/cert1.pem │ ├── chain.pem -> ../../archive/mydomain.ru-0001/chain1.pem │ ├── fullchain.pem -> ../../archive/mydomain.ru-0001/fullchain1.pem │ ├── privkey.pem -> ../../archive/mydomain.ru-0001/privkey1.pem │ └── README └── READMEИ если мы забыли откорректировать конфигурацию SSL в nginx, то могут возникнуть проблемы с работой сайта. В этом случае, может потребоваться удаление неиспользуемых сертификатов. Однако, руками просто так удалять подкаталог в ''/etc/letsencrypt/live/'' не следует. Certbot устроен так, что ''live/'' содержит лишь символические ссылки на файлы из ''archive/'', а ещё есть метаданные в ''renewal/''. Если удалить только в ''live/'', то конфигурация поломается. Как же правильно удалить более ненужные сертификаты в Certbot? Посмотрим список сертификатов:
# certbot certificates Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Found the following certs: Certificate Name: mydomain.ru-0001 Serial Number: 674520824f3d4bf6c2f3125899466351d8f Key Type: ECDSA Domains: mydomain.ru blog.mydomain.ru forum.mydomain.ru wiki.mydomain.ru Expiry Date: 2025-11-20 06:24:03+00:00 (VALID: 89 days) Certificate Path: /etc/letsencrypt/live/mydomain.ru-0001/fullchain.pem Private Key Path: /etc/letsencrypt/live/mydomain.ru-0001/privkey.pem Certificate Name: mydomain.ru Serial Number: 5010a32577f823b796c290d3192cf898642 Key Type: ECDSA Domains: mydomain.ru blog.mydomain.ru forum.mydomain.ru Expiry Date: 2025-11-15 11:25:20+00:00 (VALID: 85 days) Certificate Path: /etc/letsencrypt/live/mydomain.ru/fullchain.pem Private Key Path: /etc/letsencrypt/live/mydomain.ru/privkey.pem - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Удалим ненужный сертификат, указав в параметре ''--cert-name'' значение из ''Certificate Name'' в выводе предыдущей команды:
# certbot delete --cert-name mydomain.ru Saving debug log to /var/log/letsencrypt/letsencrypt.log - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The following certificate(s) are selected for deletion: * mydomain.ru WARNING: Before continuing, ensure that the listed certificates are not being used by any installed server software (e.g. Apache, nginx, mail servers). Deleting a certificate that is still being used will cause the server software to stop working. See https://certbot.org/deleting-certs for information on deleting certificates safely. Are you sure you want to delete the above certificate(s)? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: Y Deleted all files relating to certificate mydomain.ru.Такой метод удаления сертификата безопасный, так как certbot уберёт ссылки из ''live/'', файлы из ''archive/'' и соответствующий .conf в ''renewal/''. После этого проверяем список сертификатов повторно:
# certbot certificatesПри необходимости можно удалить все ранее запрошенные сертификаты, после чего запросить заново свежий сертификат. ---- Проверено на следующих конфигурациях: ^ Версия ОС ^ Версия certbot ^ Версия NGINX ^ | Debian GNU/Linux 13.0 (Trixie) | certbot 4.0.0-2 | nginx 1.26.3-3 | ---- {{:user:blogroot.png?50&nolink |}} Автор первичной редакции:\\ [[user:blogroot|Алексей Максимов]] \\ Время публикации: 05.09.2025 11:50 {{tag>"Let's Encrypt" "Debian 13" "Debian Trixie" NGINX certbot }} ~~DISCUSSION~~