Как стать автором
Обновить

Комментарии 29

$ echo | openssl s_client -connect mx.yandex.ru:25 -starttls smtp 2>&1 | openssl x509 -noout -dates

function showcert(){
    echo | openssl s_client -connect ${1} -starttls smtp 2>&1 | openssl x509 -noout -dates
}

Просто добавить в bashrc. Если уж написали эту строчку, то сделать ее переиспользуемой не сложно.

Атеперь, представьте, что мы хотим не просто увидеть дату, а еще и как-то что-то сделать, если до истечения останется меньше 20 дней... как будет выглядеть команда?

Зачем это делать через какие-либо скрипты? Если вы используете LE, то у вас должна в кроне стоять задача на замену сертификата, как это рекомендуется создателями этой системы. И там все за вас уже сделано.

Ну и должен быть мониторинг, а любой мониторинг умеет в проверку сертификатов.

Т.е. showcert без сомнения хорошая, удобная вещица для ad-hoc проверок. Но при чем здесь shell, флот и триггер скриптов мне не понятно.

Еще сделать showcert_imap, showcert_pop3, showcert_https. Сделать удобный общий showcert, который будет вызывать нужный из них (будет догадываться, что для smtp нужна --starttls, а для https или pop3s - не нужна). Добавить туда выгрепывание "Verify return code" (т.к. он выдается на stdout). И showcert_file конечно. Добавить опцию показа всей цепочки. Еще может пару мелочей (та же проверка на "осталось больше N дней") - но ничего невозможного. И получим в итоге замечательный showcert с тем же функционалом, написанный на шелле и живущий в .bashrc.

А когда надоест его устанавливать на новые сервера через vim .bashrc, можно переписать его на чем-нибудь и оформить в виде deb или rpm пакета, или питоновского wheel, и тогда получим полный аналог! :-)

letsencrypt не отменяет мониторинга сертификатов.

Сейчас вот, например, что-то поменялось в API и перестали продляться/выписываться сертификаты через dns+cloudflare на debian 11 пакетом из main

Как по мне: вообще ничто не отменяет мониторинга чего-угодно. Из нескольких сотен "ненужных" индикаторов. которые я добавил "ну пусть будут", для внушительности, с уверенностью, что они никогда не сработают - несколько таки сработали.

Ожидаемое может и никогда не случиться, непредсказуемое случится обязательно.

Да это понятное дело, я про конкретный случай -)

У меня LE примерно 20% доменов не может продлить.

Да, certbot renew в теории должен обновлять их, но сайты живые, постоянно разрабатываются, причем разными людьми и с ними иногда происходят разные чудеса. То поменяется DocumentRoot, то появятся правила rewrite/redirect, которые блокируют проверку, то доменное имя куда-то уедет... В общем, обновления иногда фейлятся и сертификаты протухают. А когда сайтов много, что-то проблемное случается регулярно.

Ааа. Вот в чем проблема. Ну pip install в вашей жизни ничего не решит толком. Надо исправлять саму возможность возникновения подобных проблем, а не отказываться от certbot renew.

От него никто не отказывается (Что же, по вашему, мы руками что ли обновляем каждый сертифика?). Certbot в кроне каждое утро обновляет что может. А мониторинг - следит, чтобы все было обновлено. Ну и добавлять в мониторинг каждый раз новый сайт неудобно, а так у нас вместо тысячи проверок на тысячу сайтов всего одна проверка с сутью "все LE сертификаты свежи".

Ну и добавлять в мониторинг каждый раз новый сайт неудобно, а так у нас вместо тысячи проверок на тысячу сайтов всего одна проверка с сутью "все LE сертификаты свежи".

Любая система мониторинга умеет в шаблоны.

А не проще зайти с другого конца: инфа о всех полученных сертификатах заносится в единую базу и по ней уже отслеживаются даты протухания, без перезапросов к серверам?

А вы сами-то так делаете?

У меня самого нет столько серверов под началом, чтобы специальную инфраструктуру под их мониторинг мутить, потому и интересуюсь.

Если проверяется локально (через файлы в /etc/letsencrypt/....) - то вот этот каталог и есть "база" своего рода, и это showcert и делает (не используя сеть). Не самая быстрая база, согласен, но оптимизировать скрипт, который работает три секунды, да еще и фоном по крону - не слишком острая потребность. А если держать отдельную базу - то надо ее держать в соответствии, отслеживать все новые создания-удаления - сложно, и +1 точка отказа.

Я скорее про принцип: push вместо pull. Получен сертификат - о нем рапортуется в базу. А не скрипт регулярно опрашивает сервера: или ви таки получили новый серт?

Бывает форс-мажор: сервер сдох, восстановили вчерашний из бэкапа. А сертификат там еще старый, хотя в базе написано что новый.

Логично.

Автор молодец и затея, конечно, полезная. В базу занести, кронтаб настроить, напоминалку настроить - это все тоже нужно, но проверять не помешает.

Однако, на фоне недавней статьи про "вымогатель" хочется напомнить, что предлагается установить на сервер незнакомый пакет, запустить его, практически, под root-правами (ну или кто там у вас владеет правами на эти файлы) и скормить ему все сертификаты с ключами на сервере. Я пробежался глазами по исходнику в гитхабе - вроде все невинно. Но хз что там в PyPI и что будет через час с новой версией.

(просто напоминание о здоровой паранойе, автор не примите лично)

Понимаю :-). И в pypi может новая версия любая оказаться, и в git. Сам параноик.

В целом с showcert все просто и безопасно - ему "ничего такого" не требуется:

  1. Он не пишет файлы (даже вот для сохранения сертификата используется перенаправления stdout)

  2. Он работает с сертификатами (они публичные, раздаются всему миру), но не с приватными ключами.

Так что, заизолировать можно как угодно. Пример заведомо безопасного использования:

# sudo -u nobody showcert habr.com 
Names: *.habr.com habr.com
notBefore: 2021-11-12 00:00:00 (277 days old)
notAfter: 2022-12-12 23:59:59 (118 days left)
Issuer: C=GB ST=Greater Manchester L=Salford O=Sectigo Limited CN=Sectigo ECC Domain Validation Secure Server CA

# sudo -u nobody showcert habr.com -o pem -c > /tmp/habr-fullchain.pem
# sudo -u nobody showcert /tmp/habr-fullchain.pem 
Names: *.habr.com habr.com
notBefore: 2021-11-12 00:00:00 (277 days old)
notAfter: 2022-12-12 23:59:59 (118 days left)
Issuer: C=GB ST=Greater Manchester L=Salford O=Sectigo Limited CN=Sectigo ECC Domain Validation Secure Server CA

Безопасен как юзер nobody под sudo! :-)

А вот с letsencrypt - чуть сложнее - он хранит и сертификат и ключ рядом - в /etc/letsencrypt/archive/*/. И даже сертификат - world readable (0644), а ключ, как и полагается, 0600. Но сам каталог arсhive - доступен только для рута :-(. Поэтому, или ставить +x на каталоги, чтобы проверять от юзера, или использовать от рута.

Безопасный воркэраунд для параноиков - скопировать все fullchain.pem куда-нибудь в /tmp и проверять от nobody.

Простой приятный способ проверить, что все LetsEncrypt сертификаты еще свежи:

# showcert :le -qw/etc/letsencrypt/live/example.com/fullchain.pem expires in 19 days

По моему, скромному мнению, не надо так.

Лучше чекать именно то что отдает сервис (для примера):

curl -Iv https://habr.com 2>&1 | grep "expire date" |  дальше по вкусу awk и прочее

Т.к. в этом случае вы проверяете именно то что получит пользователь. Чекая /etc/letsencrypt/live/example.com/fullchain.pem вы проверяете валидность файла.. но не то что отдает NGINX\Apache\Node\etc.

А что если LE оставили, но сервис перевели на ZeroSSL или вообще wildcard вставили? Или (ну вот так случилось) доступ к каталогам с сертификатами закрыли всем кроме рута\скрипту проверки. Или клиент\админ закрыл сайт через cloudflare и выпускает серт через него...

Кстати, да. А еще можно поменять файл сертификата, но забыть перезагрузить nginx, чтобы он его перечитал.

Согласен, внешняя проверка больше случаев покрывает. Ну и вместо curl + grep + awk я бы сделал showcert habr.com -qw 20 :-)

Сделать то вы сделаете, только следующая проверка должна быть о том, что сайт отдает нужную страничку (не 50*\не 40*\не дефейснут) т.е. что-ндь в духе:

curl -L https://habr.com 2>&1 | grep "habr-version"

Т.е. курл... ну и нафига вам два инструмента, если можно использовать один?

Эту проверку curl замечательно сделает. Но как им проверить сертификат на pop3 или smtp сервере, или посмотреть серт из файла и как им проверить что сертификат не на грани экспирейшна?

Так мы же вроде определились, что проверять файл немного бессмысленно и надо чекать конечный сервис

Что касается почты. Допустим у вас нет веб-морды (хотя в 2022 это странно), допустим у вас там чистый МТА, для рассылок, так в чем проблема:

curl smtps://smtp.gmail.com:465 -v

добавляем grep бла-бла-бла if expire date < date +3d do echo error и все становится шоколадно (синтаксис поправьте сами)

Почему я топлю за curl - он есть везде из коробки и не требует прав на установку. Запомнить надо ровно два ключа -Iv и 2>&1. И то последнее не ключ а перенаправление вывода. То что grep и awk сложны... ну вы же наверное и логи как-то парсите и там те же греп/авк...так что знать их все равно придется.

проверять файл немного бессмысленно
Смотря что нам хочется сделать. Если нам интересно что в файле - то только это и имеет смысл. Если мониторинг сервиса (проверяем действующий эффективный сертификат) - то да, надо смотреть, что сервис предоставляет. Но в жизни же есть разные задачи.

Допустим у вас нет веб-морды (хотя в 2022 это странно),
Более вероятны могут быть другие причины. Например, вебморда есть, но на другом сервере. Или есть, но у нее сертификат на mail.example.com, а у почтовика может быть на mx.example.com (вполне разумная схема). Так что, заменить проверку почтового сертификата проверкой https'ного может и не выйти.

curl smtps://smtp.gmail.com:465 -v
А можете подобным образом проверить сертификат на pop.yandex.ru:110 или
gmail-smtp-in.l.google.com:25 ? Мне кажется, нет - потому что это потребует уже STARTTLS, который curl не умеет (Но благодаря вам, я сейчас удивился, что curl умеет письма слать... куда мир катится? ). Тут нужен уже starttls, как в openssl или showcert.

синтаксис поправьте сами
А отчего вы не написали его? :-) Это возможно, конечно, но нужно немного голову поломать, время потратить. Да и задачка не столь уж тривиальная, в красивый, простой, понятный one-liner может уже и не поместиться. А через две недели, вы забудете, как это сделали и где лежит тот скрипт, и над аналогичной задачей снова придется думать заново, распарсивая даты из одного формата в другой. Если делать решение один раз и на века - можно и потратить на это время, но если нужно быстро и просто - то над тем, как это сделать через showcert даже и думать не надо, задача решается со скоростью печатания короткой команды, несколько секунд.

Curl хорош и стандартен, тут я с вами согласен, и много что можно делать. Например, вот для частного случая проверки, что сертификат действующий на TLS порту (smtps, https) - он вполне себе удобен (пара ключей - не проблема). Может быть, кстати, что существует какой-то простой почтовый клиент, скажем, fetchmail или аналог, которые могут и для pop3/imap выдать основную информацию о сертификате. Но зачем сложно, если можно просто? Без showcert можно выжить, я не спорю (сам же как-то обходился вот), но мне кажется, с ним проще и быстрее. Мелкая задача "посмотреть-проверить сертификат" возникает и тут же решается, над ней вообще не приходится думать, гуглить, смотреть заметки, тратить хоть какое-то время на нее.

Но в жизни же есть разные задачи. ...

А можете подобным образом проверить сертификат на pop.yandex.ru:110 или gmail-smtp-in.l.google.com:25 ?

Очень хочу услышать историю о том как потребовалось ковырять LE'шный серт. Вы же в статье про LE говорите, так ведь.

А отчего вы не написали его? :-)

Сложно писать с мобилки код сидя на совещании, но раз вы просите:

#!/bin/bash
TESTDATE=$(date "+%d-%b-%Y" --date="2 weeks")
CURLDATE=$(curl smtps://smtp.gmail.com:465 -v 2>&1 | grep "expire date" | awk {'print $5 "-" $4 "-" $7}')

if [[ $(date -d $TESTDATE +%s) < $(date -d $CURLDATE +%s) ]];
then
  echo "It's ok!"
else
  echo "ERROR!!!"
fi

Хотя, по-моему, с такой задачкой должен справляться джун-админ минут за 15, ну максимум 20. Свернуть в однострочник думаю опять таки сможете сами.

И да мы тут в контексте проверок, проверки очевидно запускаются с мониторинга... зачем их куда-то таскать? Положил в гит пусть лежит... по-моему все так делают.

последний Иф можно вообще чуть подменить для удобства:

[[ $(date -d $TESTDATE +%s) > $(date -d $CURLDATE +%s) ]] && echo "ERROR!!!"

Тег "я пиарюсь" пропущен?)

Не знаю. Это не коммерческий проект, а опен-сорсный, скорее обзор на утилиту. Мне кажется, "Я пиарюсь" больше для немного другого. Хотя, вот посмотрел статьи которые там, и вообще не понимаю, о чем они - на пиар своих коммерческих-некоммерческих проектов-сайтов вообще не похожи, но в том хабе.

По крайней мере пару лет назад один мой пост был распубликован за "рекламу" и в переписке с администрацией они пояснили, что стоило дать ссылку на гитхаб, тогда бы было лучше. (иначе выглядит как реклама). Сейчас вот ссылка есть и вроде все норм.

Извините, если Вы восприняли это в негативном ключе. Такого не было и в мыслях.

Имхо разницы опен-соурс или коммерческий нет. И там, и там нужен пиар, что бы развивать/развиваться. Коммерческий - это продажа продукта, не коммерческий - это "продажа себя".

PS: на проектах у меня подобных "улучшайзеров" за десятки наверное, для ssl в том числе, но они нужны лишь тогда, когда это действительно нужно, т.к. экономит время и/или упрощает процесс.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории