Вступление
Я пользуюсь сертификатами Let's Encrypt с незапамятных времён... ладно, с 2016 года, на самом деле. До выхода этого сервиса в "широкие массы" я использовал бесплатный сертификат, выданный сроком на год (от другой конторы). И так совпало, что Let's Encrypt
позволил мне продолжить предоставление доступа (возможно, после некоторого небольшого перерыва) к контенту по протоколу HTTPS. Но надо понимать, что я - совсем не админ, и в то время делал только свои первые шаги в мире Linux
, да и сейчас себя особо опытным пользователем не считаю. И требование обновлять сертификат каждые три месяца меня довольно сильно напрягало, несмотря на то, что уже тогда существовали многочисленные руководства. Я же просто не мог полноценно ими воспользоваться, так как, банально, не имел опыта и знаний. Поэтому, первое время, ставил себе напоминалки и вручную перевыпускал сертификат.
Как известно, лень - двигатель прогресса. Обновлять сертификат вручную надоело достаточно быстро и я принялся углубляться в тему автоматизации повторяющихся задач на Linux
. Да, речь про cron и всё такое. На самом деле, автоматизировать обновление сертификата было не самой большой проблемой, в большей степени меня смущал вопрос, как обеспечить его использование для моих серверов. Поясню подробнее.
Основным программным обеспечением, которым должен был использоваться сертификат, являлся (и является) HAProxy, работающий у меня как в качестве обратного прокси сервера (reverse proxy), так и в качестве сервера для терминирования SSL трафика (SSL termination server). Вот именно эта вторая роль и предполагает использование сертификата.
Как известно, Let's Encrypt
предлагает целый ряд клиентов. Конечно, изначально их было меньше - это сейчас в списке есть клиент для HAProxy и даже для Mako Server-а (продукт авторства той же компании, что и используемый мною FuguHub). Но основным рекомендуемым клиентом (и тогда, и сейчас) является Certbot. У Certbot
-a достаточно подробная документация, в которой можно найти ответы если не на все, то на очень многие вопросы. Основной проблемой тут является способность эти вопросы сформулировать[1]. Есть в ней и информация о том, как автоматизировать процесс перевыпуска (обновления) сертификатов[2].
Моей целью не является повторение того, что написано в документации или в разнообразных статьях, разбросанных по интернету. Я хочу описать свой опыт, который может оказаться полезным, а может и нет. Решение, которое я сейчас использую - результат развития используемого клиента, углубления (надеюсь) моих знаний и изменения набора используемого у меня софта, и, естественно, оно (решение) претерпевало модификацию и модернизацию по мере изменения этих вводных. Поэтому в данном тексте будет довольно много "воды", в которой отражаются мои метания и "путь воина", что не всегда бывает нужно и интересно читателю. Если вы пришли сюда за результатом всей этой продолжительной истории - следуйте прямиком к нему.
Первые шаги
Для начала, я решил (для себя), что буду использовать при перевыпуске сертификата простейший сценарий. И первым пунктом в этом решении шло использование рекомендуемого клиента (Certbot
), а вторым - использование плагина standalone. Эти пункты не вызвали особых затруднений: тогда, в 2016-ом, больше доверия вызывал именно рекомендуемый клиент, ну а то, что я хотел использовать сертификат с HAProxy
(и уж тем более с FuguHub
), делало невозможным использование каких бы то ни было специализированных плагинов, как в случае, если бы речь шла об Apache или Nginx (сторонний плагин для HAProxy появился позже).
Освобождение 80-го порта
Следующей задачей, которую мне пришлось решать, было обеспечение условий для работы standalone
плагина. Проблема заключалась в том, что при использовании этого плагина взаимодействие клиента (Certbot
) и сервиса Let's Encrypt
осуществляется через 80
-ый порт, который, в свою очередь, используется HAProxy
. А, как известно, один порт - одна программа. Поэтому, на время, пока производится обновление сертификата, HAProxy
надо "погасить"[3].
К счастью, практически с самого начала существования клиента Certbot
, у него есть параметры командной строки --pre-hook
и --post-hook
, которые позволяют указать действия перед и после взаимодействия с сервисом Let's Encrypt
. Как не сложно догадаться, именно ими я и воспользовался: в --pre-hook
я останавливаю HAProxy
, используя команду service haproxy stop
(позже я заменил её на systemctl stop haproxy
), а в --post-hook
вновь запускаю его при помощи service haproxy start
(эту команду я тоже позже заменил на systemctl start haproxy
). Помимо использования параметров командной строки имеется также возможность конфигурировать параметры обновления для сертификатов при помощи конфигурационных файлов в каталоге /etc/letsencrypt/renewal
. Клиент постоянно развивается, в нём происходят изменения. Так, --renew-hook
был постепенно заменён на --deploy-hook
, а сами hook
-и стало возможным настраивать, размещая нужные командные файлы в подкаталогах deploy
, pre
и post
каталога /etc/letsencrypt/renewal-hooks
.
Действия после перевыпуска сертификата
Вторая задача заключалась в том, чтобы программы, которым это нужно, могли воспользоваться перевыпущенными сертификатами. В моём случае, это были HAProxy
и FuguHub
. И надо отдать должное авторам Certbot
- они позаботились о том, чтобы дать возможность таким, как я, выполнить необходимые действия. Для этого ими был первоначально предусмотрен параметр командной строки renew-hook
, который потом, как я уже писал, был заменён на --deploy-hook
[4]. Так как действий мне надо выполнить достаточно много, я написал скрипт (командный файл), который и стал указывать в качестве значения для этого hook
-а. Поговорим немного (😏) про этот скрипт (командный файл).
Перевыпущенный сертификат и HAProxy
Я использую HAProxy
в качестве терминального сервера для SSL
/TLS
трафика. То есть, до него идет зашифрованный HTTPS
трафик, а после него, по локальной сети, идет обычный HTTP
трафик. Я поступаю так из-за того, что не все мои self-hosted сервисы умеют работать с защищённым трафиком. Конечно, постоянно выходят обновления ПО, и, в частности, у некоторых сервисов за последнее время была добавлена возможность работы по протоколу HTTPS
. Но, во-первых, это происходит совершенно непредсказуемо по времени, а во-вторых, есть ПО, которое, практически не обновляется и поддержки этого протокола для такого софта ожидать не приходится.
Важно отметить, что у меня HAProxy
и Certbot
используются на одном и том же хосте - это существенно упрощает командный файл. Итак, чтобы HAProxy
смог воспользоваться перевыпущенным сертификатом, в скрипт, который выполняется при успешном обновлении сертификата, я добавил следующие строки:
#!/bin/bash
cd /etc/letsencrypt/live/my.domain.name
cat fullchain.pem privkey.pem > my.domain.name.pem
cp my.domain.name.pem /etc/ssl/
# Далее идут команды, связанные с FuguHub
Поясню, что тут, собственно, происходит. Для того, чтобы HAProxy
мог работать с зашифрованным трафиком, ему необходимо предоставить один файл, в котором должна быть указана и полная цепочка сертификатов от конечного (выпущенного) сертификата до сертификата удостоверяющего центра (с публичными ключами, естественно) и защищенный ключ, соответствующий публичному ключу в конечном сертификате[5].
При каждом выпуске (или перевыпуске) сертификата при помощи Certbot
, на хосте, с которого запускается агент (а запускается он с правами суперпользователя), в каталоге /etc/letsencrypt/archive/CERT_NAME
(где CERT_NAME
- имя сертификата, которое, обычно, либо совпадает с доменным именем, для которого выпускается сертификат[6], либо указывается в качестве значения для параметра командной строки --cert-name
; далее в нашем примере будем считать, что CERT_NAME
равен my.domain.name
), создается несколько файлов, описывающих выпущенный (обновлённый) сертификат (в именах присутствует порядковый номер запроса на выпуск, чтобы не перетирались прошлые версии). В тоже время, в каталоге /etc/letsencrypt/live/CERT_NAME
создаются ссылки на самые свежие версии этих созданных файлов. Ссылки всегда называются одинаково. С точки зрения HAProxy
нас интересуют две ссылки. Одна из них называется fullchain.pem
, и она указывает на файл, в котором сохранена цепочка сертификатов, от выпущенного (конечного) до корневого (принадлежащего удостоверяющему центру). Другая ссылка, с названием privkey.pem
, указывает на файл с защищенным ключом той пары, для публичного ключа которой и выпущен конечный сертификат.
Первая команда скрипта:
cd /etc/letsencrypt/live/my.domain.name
выполняет переход в нужный каталог, в котором агент создал ссылки на файлы с защищенным ключом и цепочкой сертификатов с публичными ключами. Делается это только для того, чтобы не указывать полные пути для файлов в последующих командах, и, в принципе, можно обойтись и без неё.
Следующая команда скрипта:
cat fullchain.pem privkey.pem > my.domain.name.pem
предназначена для того, чтобы "слить" два файла - с цепочкой сертификатов и с приватным ключом - воедино (в файл с именем my.domain.name.pem
).
Ну и последняя команда:
cp my.domain.name /etc/ssl/
просто копирует получившийся файл в каталог /etc/ssl/
.
Сам же HAProxy
настроен (в файле конфигурации /etc/haproxy/haproxy.cfg
) на то, чтобы взять нужную ему для работы с зашифрованным трафиком информацию из файла /etc/ssl/my.domain.name.pem
:
bind *:443 ssl crt /etc/ssl/my.domain.name.pem
Перевыпущенный сертификат и FuguHub
Для того, чтобы FuguHub
смог воспользоваться новым сертификатом, надо выполнить примерно такие же действия. Но в этот раз, Certbot
и получатель сертификата находятся у меня на разных хостах. И это вносит в скрипт свои коррективы.
# Перед этим идут команды, связанные с HAProxy
openssl rsa -in privkey.pem -out bdprivkey.pem
scp bdprivkey.pem root@FUGUHUB_HOST:/home/bd/server.key
scp fullchain.pem root@FUGUHUB_HOST:/home/bd/server.cert
ssh -t -t root@FUGUHUB_HOST '/etc/init.d/bdd stop'
ssh root@FUGUHUB_HOST '/etc/init.d/bdd start < /dev/null > /tmp/mylogfile 2>&1 &'
где FUGUHUB_HOST
- хост, на котором крутится FuguHub
.
Прежде, чем мы подробнее поговорим про эти команды, надо отметить вот какой момент. Так как работа с удалённым хостом будет вестись по протоколу SSH, то, чтобы не возникало требования по вводу пароля, на которое, очевидно, нам не удастся отреагировать (скрипт будет запускаться из deploy-hook
-а, а сам hook
- из команды обновления, которая, в свою очередь, будет вызываться из задачи cron
), надо предварительно настроить соединение с использованием ключей (ну, или если хост находится под управлением Windows 10).
А теперь разберём приведённые выше команды. Первая:
openssl rsa -in privkey.pem -out bdprivkey.pem
предназначена для конвертации приватного ключа в формат, который понимает FuguHub
. Дело в том, что файл, на который ссылается privkey.pem
, создаётся Certbot
-ом в формате PKCS#8, а FuguHub
ожидает файл приватного ключа в формате RSA PEM. Отличаются они строками, обрамляющими непосредственно приватный ключ - у PKCS#8 это:
-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----
а у RSA PEM
:
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
Таким образом, приведённая выше команда просто изменяет header
и footer
в первоначальном файле, сохраняя получившийся результат под именем bdprivkey.pem
(так как это продолжение скрипта, не забудем, что находимся в подкаталоге /etc/letsencrypt/live/my.domain.name
).
Следующие две команды:
scp bdprivkey.pem root@FUGUHUB_HOST:/home/bd/server.key
scp fullchain.pem root@FUGUHUB_HOST:/home/bd/server.cert
копируют файл приватного ключа и полной цепочки сертификатов на удалённый хост с работающим FuguHub
.
Нам остаётся лишь перезапустить FuguHub
и для этого испольуются следующие команды:
ssh -t -t root@FUGUHUB_HOST '/etc/init.d/bdd stop'
ssh root@FUGUHUB_HOST '/etc/init.d/bdd start < /dev/null > /tmp/mylogfile 2>&1 &'
Надо признаться, я уже не помню, почему команды выглядят так, какие ошибки/проблемы привели к такому результату - скрипт писался и отлаживался достаточно давно ещё на MyBookLive
, но дать некоторые пояснения постараюсь.
Первая команда нужна для остановки демона FuguHub
. Использование пары ключей -t -t
, согласно документации SSH
, нужно для безусловного создания псевдо-терминала. Вот эта выдержка:
-t Force pseudo-terminal allocation. This can be used to exe‐
cute arbitrary screen-based programs on a remote machine,
which can be very useful, e.g. when implementing menu ser‐
vices. Multiple -t options force tty allocation, even if
ssh has no local tty.
Такое поведение потребовалось, по всей видимости, из-за того, что скрипт запускается из cron
, и у ssh
нет и не может быть ассоциированного с ним терминала, а команда остановки демона пытается в терминал что-нибудь, да вывести, что приводит к возникновению ошибки.
Вторая команда, как, наверное, все догадались, нужна для запуска демона FuguHub
. Тут, конечно, понакручено всевозможных редиректов, скорее всего, чтобы при вводе/выводе тоже не возникало ошибок, ну а амперсанд в конце передаваемой на хост команды говорит о том, что всё должно продолжать работать после закрытия ssh
сессии. Вроде так... 🤔😏🤨
Ну вот, со скриптом, который выполняется при перевыпуске сертификата, вроде, разобрались. Теперь следует разобраться с автоматизацией перевыпуска.
Автоматизация перевыпуска сертификатов
Автоматизация: версия 1
После самой первой установки Certbot
на Debian Jessie
и первоначального выпуска сертификата, я обнаружил в /etc/cron.d/certbot
такую вот команду:
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew
Естественно, на расшифровку её ушло какое-то время, но задачка была решена. Итак, установщик Certbot
-а запрограммировал следующую последовательность действий:
- каждые 12 часов (в 12:00 и в 24:00)
- от имени пользователя root
- в случае, если существует файл
/usr/bin/certbot
с правами на выполнение (условие выполняется, еслиCertbot
был установлен обычным в те времена способом) - и не существует каталога
/run/systemd/system
(если система используетsystemd
, то для создания периодически повторяющихся действий должен использоваться неcron
, а встроенные возможностиsystemd
) - выполнить случайную задержку в пределах одного часа (чтобы все, кто установил
Certbot
, не ломанулись на сервера в одно и тоже время) - выполнить, наконец, обновление (молча 🤐).
Как видите, никаких параметров для команды renew
не указано: ни тебе --pre-hook
, ни --post-hook
, а уж --renew-hook
(или --deploy-hook
) и подавно. Объясняется всё довольно просто: у клиента Certbot
имеется возможность конфигурировать параметры обновления для сертификатов при помощи конфигурационных файлов в каталоге /etc/letsencrypt/renewal
. Кроме того, как я отмечал ранее, клиент постоянно развивается, в нём происходят изменения. И замена --renew-hook
на --deploy-hook
- лишь одна из многих правок. Для облегчения жизни пользователей, клиент стал автоматически запоминать значения параметров --pre-hook
, --post-hook
и --deploy-hook
в конфигурации. А чуть позже, hook
-и стало возможным настраивать, размещая нужные командные файлы в подкаталогах deploy
, pre
и post
каталога /etc/letsencrypt/renewal-hooks
. Именно благодаря этим возможностям конфигурирования клиента Certbot
(а также другому полезному функционалу), команда обновления и оказывается настолько простой:
certbot -q renew
Автоматизация: версия 2
В общем, всё каким-то образом устаканилось и работало без моего вмешательства, до тех пор пока в одном из протоколов Certbot
не обнаружили уязвимость. Помню, как сейчас 😉: 27 января 2019 года получаю письмо, отправленное от имени noreply@letsencrypt.org
. В этом письме мне сообщают (как, наверное, и многим другим), что используемый мною клиент (а это certbot) при запросах на выпуск сертификатов за последние 60 дней задействовал для проверки принадлежности доменов механизм с названием ACME TLS-SNI-01. Но вот незадача, использование этого механизма с 13 февраля 2019 года планируется временно прекратить, и полностью отказаться от него с 13.03.2019, так как в этом механизме была обнаружена уязвимость, позволявшая выпустить сертификат на чужой домен.
То есть, примерно за две недели до часа Ч я понимаю, что скоро все мои запросы на обновление будут отклоняться, так как мой клиент будет пробовать подтвердить принадлежность доменов с помощью этого самого механизма, который перестанет поддерживаться центром сертификации. Мир рушится - в очередной раз и, чтобы его спасти, надо просто последовать рекомендации и обновить клиента.
Я не буду тут описывать, через что мне пришлось пройти, чтобы всё-таки обновить клиента. Возможно, когда-нибудь я напишу об этом отдельный пост, но не для того, чтобы кто-то обновлялся по моим инструкциям - они уже давно потеряли актуальность, но для того, чтобы показать истинное лицо Linux
с точки зрения простого пользователя. Скажу лишь, что, в конце концов, я обновил клиента, но после этого обновления у меня уже работал специальный скрипт с названием certbot-auto
, так как сам Certbot
для Debian Jessie
обновляться перестал.
Естественно, после, по сути, смены клиента, надо было понять, что делать с автоматическим перевыпуском сертификатов - старая задача cron
потеряла актуальность, так как клиента Certbot
сменил клиент certbot-auto
. К счастью, авторы certbot-auto
не бросили своих пользователей и предложили им в качестве примера следующую задачу cron
для автоматического перевыпуска сертификатов:
0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && /path/to/certbot-auto renew
Единственное, что надо не забыть сделать, так это заменить /path/to/
на настоящий путь к certbot-auto
.
Ну и, для порядка, разберем саму задачу. Она должна запускаться дважды в сутки: в полночь и полдень (0,12
). Первым делом выполняется скрипт для python
, который осуществляет задержку на случайное количество минут (time.sleep(random.random() * 3600)
), после которой запускается собственно certbot-auto
для перевыпуска сертификатов (ключ renew
).
Как видим, изменения есть, но они не принципиальные: чуть изменилось программирование времени срабатывания, perl
сменился python
-ом, проверки исчезли, ну и клиент теперь другой. Сама команда осталась максимально простой, так как certbot-auto
прекрасно работал с конфигурационными файлами Certbot
.
И еше: задачу я создавал при помощи следующей команды:
crontab -e
Сама же задача создалась в подкаталоге crontabs
каталога /var/spool/cron
с именем файла, соотвтетствующим имени пользователя (в моем случае это был root
).
Автоматизация: версия 3
Казалось бы, всё, отмучались, всё работает, как часы, в автоматическом режиме сертификаты перевыпускаются и делаются доступными для требующего их ПО. Но... 30-го сентября истёк срок действия сертификата, который выступал к качестве корневого для всей цепочки (ну, не совсем корневого, им был соподписан (cross-signed) корневой сертификат Let's Encrypt
). И да, мне опять пришло письмо - 14-го мая.
Решил я посмотреть, как там с моими клиентами, автоматизациями и т.д. Вот если бы не посмотрел, не узнал бы, что certbot-auto
вышел из моды и не поддерживается - если раньше обновления проверялись (и, при необходимости, осуществлялись) каждый раз при его запуске, то теперь всё, как говорится, финита ля комедия.
И решил я, что с этим надо что-то делать. Проводить upgrade операционки очень не хотелось, хотя, конечно, я понимал, что надо. Но из-за того, что много разных действий я совершал вручную, например, при обновлении клиента на certbot-auto
менял библиотеки, потом ставил более свежую версию HAProxy
, чем разрешено для Debian Jessie
, устанавливал HAProxy-WI и так далее и тому подобное, я просто боялся, что могу получить кучу проблем. Поэтому, подумав некоторое время, я решил остановиться на варианте с использованием Docker. Надо заметить, что именно сейчас пойдёт более-менее актуальная информация, которую читатель может попробовать использовать себе во благо.🙄
Итак. Почему я выбрал именно этот вариант (с Docker). Во-первых, у меня уже есть некоторый опыт работы с ним. Во-вторых, я посчитал, что раз образ - официальный, то авторы позаботятся о том, чтобы всё в нём было прекрасно, особенно о том, чтобы в нём всегда использовалась самая свежая версия клиента. Причём, я не буду больше думать о совместимости чего-то с чем-то[7].
Почему я раньше не останавливался на этом варианте? Если честно, то я не помню. Вернее, раньше на официальном сайте Certbot
такого предложения не было, и мне всё как-то попадались "пакетные" решения, при которых в контейнер упаковывается не только клиент Let's Encrypt
, но и софт, который использует сертификаты, тот же HAProxy
. А мне, почему-то[8], не хотелось переносить обратный прокси в docker
контейнер, к тому же, docker
, исходя из своих собственных представлений о добре и зле, вносит изменения в настройки межсетевого экрана, что иногда приводит, мягко говоря, к странным и не всегда желательным явлениям. Возможно, позже, когда я лучше смогу оценить и понять последствия, я и перенесу HAPRoxy
в контейнер, но пока я к этому не готов.Но продолжим...
Решение о переносе процесса перевыпуска сертификатов в docker
-контейнер естественным образом влечёт за собой изменения в механизмах взаимодействия клиента Certbot
с другим софтом и инфраструктурой. В основном, речь идёт о hook
-ах. Действительно, для того, чтобы перевыпущенный сертификат стал доступен извне контейнера достаточно к этому контейнеру примонтировать каталог хоста. А вот как заставить, например, pre-hook
, выполняемый в контейнере, остановить работающий на хосте HAProxy
?
Собственно говоря, простейшим ответом на поставленный выше вопрос будет остановка сервиса HAProxy
до вызова процедуры перевыпуска сертификата. Точно также post-hook
можно заменить на запуск сервиса после обновления сертификата. А вот с deploy-hook
-ом всё несколько хитрее. Вызываемый в нём скрипт работает с файлами, расположенными не только на локальном, но и на удалённом хосте, да ещё и с использованием SSH
. К тому же, особенностью deploy-hook
-а является то, что вызывается он только при успешном перевыпуске сертификата, поэтому отказываться от него очень не хотелось.
В общем, после некоторых раздумий, я решил остановиться на такой схеме:
- проводим предварительные работы:
- правим конфигурацию, ранее используемую
certbot-auto
, с тем, чтобы не былоpre-hook
иpost-hook
- изменяем
deploy-hook
таким образом, чтобы в нём создавался файл с именемdeployed.txt
в каталоге/etc/letsencrypt/live/my.domain.name
- правим конфигурацию, ранее используемую
- правим процедуру обновления:
- останавливаем сервис обратного прокси
- монтируем текущий каталог, используемый клиентом
certbot-auto
(/etc/letsencrypt
), в запускаемыйdocker
-контейнерCertbot
-а - после завершения выполнения
docker
-контейнера проверяем наличие файла/etc/letsencrypt/live/my.domain.name/deployed.txt
и, если он там есть, выполняем манипуляции с перевыпущенным сертификатом - запускаем сервис обратного прокси
Подумав ещё немного, я решил перед запуском контейнера удалять файл, создаваемый в при исполнении deploy-hook
-а, если он там есть - процедура-то будет периодически повторяться, и, будучи созданным на какой-то итерации, файл может привести к ложным срабатываниям на последующих итерациях, и поэтому, перед ними, его следует удалить.
В конце концов, у меня получился вот такой скрипт:
systemctl stop haproxy
FILE=/etc/letsencrypt/live/my.domain.name/deployed.txt
if [ -f "$FILE" ]; then
rm $FILE
fi
docker run --rm --name certbot \
-v "/etc/letsencrypt:/etc/letsencrypt" \
-v "/var/lib/letsencrypt:/var/lib/letsencrypt" \
-p 80:80 \
certbot/certbot renew
if [ -f "$FILE" ]; then
/usr/local/bin/certupdate.sh
echo "deployed"
else
echo "not deployed"
fi
systemctl start haproxy
где my.domain.name
- имя моего домена, а файл /usr/local/bin/certupdate.sh
содержит необходимые действия с перевыпущенным сертификатом, которые я описывал выше.
На что в этом скрипте хотелось бы обратить внимание. В инструкции клиента Certbot
для перевыпуска сертификата при помощи docker
-контейнера указаны дополнительно ключи -i -t
(вернее, -it
). Но нам они не нужны, так как вызов будет осуществляться в задаче cron
-а, а не в интерактивном режиме. Более того, если мы их оставим, то получим ошибку:
the input device is not a TTY
Приведённый выше скрипт я сохранил в файле /usr/local/bin/le-renew.sh
. Конечно, его можно улучшать. Так, например, перед тем, как перейти к процессу перевыпуска сертификата, можно проверять факт того, что сервис HAProxy
был действительно остановлен (применив, systemctl is-active
или другой механизм).
Сам deploy-hook
я описал, создав в подкаталоге /etc/letsencrypt/renewal-hooks/deploy
файл certs-deployed.sh
с таким содержанием:
touch /etc/letsencrypt/live/my.domain.name/deployed.txt
Ну и, в завершение, выполнив команду crontab -e
, я отредактировал задачу cron
-а:
0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && /usr/local/bin/le-renew.sh >> /var/log/letsencrypt/letsencrypt.log 2>&1
Практически такую же задачу я разбирал выше, за исключением редиректа вывода:
>> /var/log/letsencrypt/letsencrypt.log 2>&1
Тут тоже всё не сложно: мы перенаправляем весь вывод, осуществляемый в стандартное устройство вывода (stdout
) в нужный нам файл (/var/log/letsencrypt/letsencrypt.log
), а, заодно, в этот же файл попадёт и весь вывод, производимый в стандартное устройство вывода ошибок ( stderr
) - этот вывод мы перенаправляем в stdout
(2>&1
), который уже перенаправлен в файл.
Вот, пожалуй, и всё, что мне есть рассказать на текущий момент про перевыпуск сертификата Let's Encrypt
и про автоматизацию этого процесса.
Ведь общеизвестно, что правильно заданный вопрос - половина ответа ↩︎
Я даю ссылки на актуальные в момент написания материалы. Раньше они были другими, и, возможно, изменятся в будущем. ↩︎
Можно, конечно, поступить и иначе - сконфигурировать
HAProxy
так, чтобы он анализировал факт того, что производится обмен с сервисомLet's Encrypt
и перенаправлял в этом случае запросы клиенту (Certbot
). Но, после обновления сертификата,HAProxy
всё равно придётся перегрузить. ↩︎deploy-hook
отличается (в лучшую, на мой взгляд, сторону) отrenew-hook
тем, что срабатывает и при первичном выпуске сертификата ↩︎На самом деле, использование одного файла - не является обязательным требованием, все зависит от того, как настроен
HAProxy
↩︎Если доменных имён много, то, по умолчанию, будет использовано имя домена, указанное первым. ↩︎
Знаю-знаю,
docker
не является панацеей, и помнить о совместимости всё равно надо, да и сталкивался я уже со случаями, когда совместимость не обеспечивалась, правда, в других продуктах, но об этом - в другой раз. ↩︎Мне, чисто интуитивно, кажется, что перенос
HAProxy
в контейнер может плохо сказаться на быстродействии, но, возможно, тут я не прав ↩︎