Сайт четыре дня отдавал истёкший сертификат. Сервер работал, страницы собирались, проверка без строгой проверки сертификата получала 200. А посетитель вместо сайта видел во весь экран предупреждение браузера об опасном соединении. Заметили случайно, разбирая другую задачу.

Это девятая часть цикла «Сервер для WordPress».

Кто продлевается сам, а кто нет

  • Let’s Encrypt через traefik продлевается сам — но не у всех сайтов. Для роутера с регулярным выражением в правиле (нужен для поддоменов городов) traefik не может вывести список имён и сертификат не выпустит. Опечатка в имени резолвера в метке — и сертификат не выпускается молча;
  • покупные wildcard-сертификаты продлеваются только руками. Именно они и истекают.

Почему «напомнить за две недели» мало

Второй случай. Покупной сертификат: предупреждение за 12 дней, повторное за 6. Новый выпустили за четыре дня до срока, а до сервера он дошёл на следующий день после истечения. Сайт сутки отдавал истёкший сертификат — при том, что все знали.

Вывод: к порогу в две недели новый сертификат должен быть на руках, а не «заказан».

Проверять по сети, а не по файлам

Сертификат выбирается по имени, которое браузер передаёт при соединении (SNI). У одного сайта их бывает несколько:

  • на одном сайте корень домена отдавал истёкший покупной wildcard, а www. и тестовый поддомен — живые Let’s Encrypt. Проверка только www сказала бы «всё хорошо»;
  • на другом корень домена в один день отдавал Let’s Encrypt, через неделю — покупной wildcard. Полагаться на то, что «там же есть автоматический», нельзя;
  • файл на диске и то, что реально отдаётся, могут не совпадать.

Обход раз в неделю — корень, www и поддомены каждого сайта:

for h in site.ru www.site.ru msk.site.ru; do
  printf "%-24s " $h
  echo | timeout 12 openssl s_client -connect $h:443 -servername $h 2>/dev/null \
    | openssl x509 -noout -enddate -issuer 2>/dev/null | tr "\n" " "
  curl -s -o /dev/null -w "curl=%{http_code}\n" --max-time 15 https://$h/
done

curl без -k — самый быстрый признак: 200 или 301 значит, сертификат принят; 000 — клиент его отверг.

Неполная цепочка: в браузере не видно

Сервер обязан отдавать не только свой сертификат, но и промежуточный. Браузеры часто достраивают цепочку сами, а curl, node и python — нет. Сайт открывается у всех, а интеграции, вебхуки и мониторинг падают.

echo | openssl s_client -connect site.ru:443 -servername site.ru -showcerts 2>/dev/null \
  | grep -E '^ [0-9] s:|Verify return code'
#  0 s:CN = *.site.ru
#  1 s:CN = AlphaSSL CA ...
# Verify return code: 0 (ok)    ← 10 — истёк, 20/21 — нет промежуточного

Установка покупного сертификата: три проверки

  1. промежуточный брать по ссылке из самого сертификата (поле CA Issuers), а не «тот же, что в прошлый раз». У нас новый выпуск пришёл от другого промежуточного центра — старый файл не подошёл бы;
  2. проверить, что ключ подходит: хэши модуля сертификата и ключа должны совпасть. Дважды выпуск оказывался под новый ключ, и ставить пришлось пару целиком;
  3. собрать fullchain: свой сертификат, затем промежуточный, и проверить openssl verify.
openssl x509 -in leaf.pem -noout -text | grep 'CA Issuers'      # откуда брать промежуточный
openssl x509 -in leaf.pem -noout -modulus | openssl sha256      # должен совпасть…
openssl rsa  -in site.key -noout -modulus | openssl sha256      # …с этим
openssl verify -untrusted inter.pem leaf.pem                    # OK
cat leaf.pem inter.pem > fullchain.crt

Без перезапуска traefik

Перезапуск traefik — это несколько секунд недоступности всех сайтов сервера. Он не нужен: если сертификаты подключены файловым провайдером, достаточно заменить файлы и обновить время изменения его конфига. traefik перечитает его сам — у нас новый сертификат отдавался через 5 секунд.

cat fullchain.crt > /path/certs/site.crt   # перезапись сохраняет владельца и права
touch /path/providers/certs.yml

Не знаете, когда истекают сертификаты ваших сайтов?

Пришлите список доменов — проверю все имена и поддомены и скажу, что и когда продлевать руками.

· полезно?
АЧ
Алексей Чикун веб-разработчик, команда TRIOHEAD

Делаю сайты и сервисы целиком: от вёрстки до сервера. Пишу о том, что проверил на своих проектах.

Комментарии

// загружаю комментарии…

Комментарии публикуются после проверки. Ссылки и HTML не принимаются.