Допустим, вы не девопс. Вы — вполне себе фронтендер, бэкендер, может даже мобильщик. Но вот беда: у вас сервер, и ему нужен SSL. А девопс уехал в отпуск. Или вообще не нанят. И вот вы стоите, глядите на терминал и думаете: «Ну всё, теперь я — DevOps». ?
Пугаться не стоит. Сегодня расскажу, как быстро и автоматически настроить SSL-сертификаты от Let’s Encrypt с помощью Certbot на Ubuntu. С шутками, примерами и bash-магией.
? Зачем нужен Certbot и Let’s Encrypt?
Let’s Encrypt — это бесплатный центр сертификации. Он позволяет выпускать SSL-сертификаты для HTTPS. Certbot — это утилита для автоматического получения и обновления этих сертификатов.
Комбо для тех, кто не хочет возиться с ручной генерацией ключей и походами в коммерческие CA.
? Установка Certbot
sudo apt update
sudo apt install certbot
Важно: Certbot нужно запускать на том же сервере, для которого вы хотите выпустить сертификат.
? Получение сертификата (и вывод информации о текущих сертификатах)
sudo certbot certonly --standalone -d project.com -d www.project.com
sudo certbot certificates
--standalone
означает, что Certbot временно поднимет собственный сервер на 80 порту для валидации домена.-
Проверьте, что порт 80 не занят! Иначе ничего не заработает.
Если там ваш Nginx или Docker — остановите его на время выполнения команды:
sudo systemctl stop nginx
Альтернатива: можно использовать плагин webroot
— он не требует остановки сервиса и просто создаёт специальный файл в директории сайта.
Подробнее про плагины — в официальной документации.
⏱ Автоматическое обновление через systemd
После установки Certbot автоматически добавляет systemd-таймер:
systemctl list-timers | grep certbot
Пример вывода:
Mon 2025-03-10 03:12:00 UTC 10h left Mon 2025-03-09 03:12:00 UTC certbot.timer certbot.service
Проверить, что автообновление работает:
sudo certbot renew --dry-run
Если всё хорошо:
Certbot dry-run was successful.
Логи последних обновлений:
journalctl -u certbot.service --no-pager --since "2 days ago"
Напоминание: Certbot обновляет сертификаты только если до их окончания < 30 дней.
?️ Альтернатива: обновление через Cron
Иногда systemd-таймеры неудобны, особенно если вы настраиваете всё через Ansible или shell-скрипты. В этом случае можно использовать Cron.
Отключаем таймер:
sudo systemctl stop certbot.timer
sudo systemctl disable certbot.timer
Добавляем Cron-задачу:
sudo crontab -e
Пример:
0 0 1 * * /usr/bin/certbot renew --standalone --quiet
Чтобы узнать точный путь к certbot
, используйте:
which certbot
⚙️ Хуки для перезапуска сервисов
Certbot умеет выполнять действия до, после или только при успешном обновлении сертификата. Это удобно, если нужно остановить сервис, скопировать сертификаты или перезапустить сервер.
# /etc/letsencrypt/renewal/project.com.conf
pre_hook = systemctl stop my-project.service
deploy_hook = systemctl reload my-project.service
post_hook = systemctl start my-project.service
?️ Скрипт на все случаи жизни
Вместо описания всего в кроне, можно создать bash-скрипт, который будет:
Останавливать сервис
Обновлять сертификаты
Копировать файлы в нужное место
Ставить права
Запускать сервис обратно
#!/bin/bash
APP_PATH="/home/projects/project"
DOMAIN="project.com"
FULL_CHAIN_SRC="/etc/letsencrypt/live/${DOMAIN}/fullchain.pem"
PRIVATE_KEY_SRC="/etc/letsencrypt/live/${DOMAIN}/privkey.pem"
FULL_CHAIN_DIST="${APP_PATH}/volumes/etc/ssl/certs/project_com.full.crt"
PRIVATE_KEY_DIST="${APP_PATH}/volumes/etc/ssl/private/project_com.key"
echo "Starting script execution: $(date "+%Y-%m-%d %H:%M:%S")"
echo "Stopping the service..."
systemctl stop my-project.service
echo "Renewing the certificates..."
/usr/bin/certbot renew --standalone --quiet
/usr/bin/certbot certificates
echo "Copying the certificates to the project..."
cp -f "$FULL_CHAIN_SRC" "$FULL_CHAIN_DIST"
cp -f "$PRIVATE_KEY_SRC" "$PRIVATE_KEY_DIST"
echo "Setting correct permissions for the certificates..."
chmod 644 "$FULL_CHAIN_DIST"
chmod 644 "$PRIVATE_KEY_DIST"
echo "Running the service..."
systemctl start my-project.service
echo "End of script execution: $(date "+%Y-%m-%d %H:%M:%S")"
А в кроне вызываем его так:
0 0 1 * * sh /home/projects/project/cert-renew.sh >> /var/log/project-cert-renew.log 2>&1
? Заключение
Иногда даже разработчику приходится немного быть девопсом. Главное — не бояться терминала и знать, где гуглить. А ещё — не забыть проверить через полгода, что автообновление всё ещё работает. ?
Если вы нашли ошибку или хотите поделиться своим способом автоматизации — велком в комментарии!
Комментарии (12)
NotSlow
13.05.2025 19:23Если "фронтендер, бэкендер, может даже мобильщик" заходит на сервер и под root запускает что-то из статей в интернетах или по советам gpt, то...
Скрытый текст
Интересно, многие ли заметили, что с мая let's encrypt завязал с OCSP. И теперь кто использовал в nginx ssl_stapling столкнутся с:
pae174
13.05.2025 19:23он не требует остановки сервиса и просто создаёт специальный файл в директории сайта
Он создает файл в директории .well-known (имя директории начинается с точки). У веб серверов часто запрещено отдавать директории и файлы с именами, ничинающимися с точки - это делается на случай когда в директории с сайтом есть всякие там .git, .svn, .htaccess и тому подобные служебные штуки. Так что надо заблаговременно проверить конфиг вашего Apache или Nginx на предмет таких запретов.
Кроме того для получения wildcard сертификата необходимо не только размещать файл но еще и добавлять запись в DNS.
ki11j0y
13.05.2025 19:23Достаточно просто разместить txt запись без .well-known для wildcard
Метод называется dns challenge, а ещё есть dns alias mode когда для проверки используется другой домен, тогда в случае слива токена ни чего не произойдёт с основным доменом.
ki11j0y
13.05.2025 19:23В случае stateless режима acme и например haproxy, то ни чего не создаётся, не обязательно иметь даже веб сервер за обратным прокси для получения сертификатов
RomanKu
13.05.2025 19:23Для пет проекта сойдет, в продакшин такое выпускать - сомнительно, очень сомнительньно.
За долгие годы работы с certbot убедился, что не все так просто с ним и приходится изворачиваться местами, новичкам (не смотря на то, что этот проект ориентирован на простоту) не всегда удается сделать нормально, а при запихивании во всякие докеры легче не становится.
Для фронтендеров и бекендеров, не девопсов всегда рекомендую Nginx Proxy Manager - это реверс прокси с cert bot из коробки. Если не надо перегонять петабайты данных, то проще поставить NPN в одном месте, а потом в нем уже прописать нужные сервисы. Как минимум
Меньше проблем с сертификатами
Не будет даунтайма на время перевыпуска и проверки сертификатов.
С этим скриптом получается, что сервис будет останавливаться каждый раз перед проверкой сертификата, даже если время перевыпуска еще не наступило, если упадет во время работы, то сервис может и не подняться
FSA
13.05.2025 19:23Из всей статьи разве что может быть полезно для кого-то информация про хуки. Всё остальное вообще не имеет никакого смысла, ибо просто ставишь certbot, даёшь команду на получение сертификата, пользуешься. Ничего вообще трогать не надо ни в Ubuntu, ни в Debian, ни в Fedora.
А вот чего реально не хватает в статье - информации о челленджах по получение сертификата. Есть про webroot, есть про standalone, но совершенно нет информации о получении сертификата через dns, которые позволяют получить в том числе и в wildcard сертификаты, не требуют остановки веб-сервера и вообще установку certbot и получение нужного сертификата можно хоть через ansible сделать.
А вот вся эта маета с настройкой таймеров и крона нужна для acme.sh и lego.
Lazhu
13.05.2025 19:23как-то все чрезмерно сложно у вас
cat /usr/local/etc/letsencrypt/renewal/mydomain.ru.conf # renew_before_expiry = 30 days version = 2.3.0 archive_dir = /usr/local/etc/letsencrypt/archive/mydomain.ru cert = /usr/local/etc/letsencrypt/live/mydomain.ru/cert.pem privkey = /usr/local/etc/letsencrypt/live/mydomain.ru/privkey.pem chain = /usr/local/etc/letsencrypt/live/mydomain.ru/chain.pem fullchain = /usr/local/etc/letsencrypt/live/mydomain.ru/fullchain.pem # Options used in the renewal process [renewalparams] account = acc8b9bfe080d37449336cdgh6048b5d authenticator = webroot webroot_path = /usr/local/www/mydomain.ru, server = https://acme-v02.api.letsencrypt.org/directory key_type = ecdsa post_hook = /root/bin/certbot-posthook.sh [[webroot_map]] mydomain.ru = /usr/local/www/mydomain.ru
cat /root/bin/certbot-posthook.sh #!/bin/sh postmap -F hash:/usr/local/etc/postfix/vmail_ssl.map service postfix reload service dovecot reload apachectl graceful
1nt
13.05.2025 19:23Пока админ в отпуске, откроем 80 порт или выключим все что на нем висит или bind9 настроим. Кстати я думал уже 80 порт все закрывают.
DaemonGloom
13.05.2025 19:2380 порт обычно доступен, но отдаёт переадресацию на https/443. Ну и для прохождения челленджа, если dns способ невозможен.
ki11j0y
Есть acme.sh и выдача сертификатов без перезагрузки сервиса.