Я получил уведомление от Redsift о том, что мои сертификаты истекут через неделю. Обычно Discourse обновляет сертификаты задолго до истечения срока действия. В этот раз всё иначе: прежде чем я начну пересборку (которая, как ожидается, решит проблему), @Falco, есть ли что-то, что мне стоит проверить и сообщить здесь, чтобы помочь выявить причину, по которой сертификаты не были обновлены?
Корневой сертификат — ISRGX1, а вот информация об истекающем сертификате:
Если память мне не изменяет, сертификаты действительны в течение 3 месяцев, и теперь они попытаются автоматически продлить срок действия до истечения этого срока.
Но с момента обновления программного обеспечения форума прошло уже больше суток, и сертификат, похоже, так и не обновился. До его истечения осталось 5 дней, поэтому его срочно нужно продлить.
Я использую стабильную ветку Discourse, если это имеет значение. Возможно, исправление конечной точки еще не было перенесено в эту ветку?
У нас возникла та же проблема с невозобновлением SSL.
Будет здорово, если кто-нибудь проверит, корректно ли работает web.ssl.template в discourse-docker. Мне показалось, что порт 80 не обслуживает URL-адреса в формате /.well-known/, используемые Let’s Encrypt: все запросы перенаправлялись на SSL, включая тестовые файлы, которые я вручную разместил в /var/www/discourse/public/.well-known/. Пришлось напрямую отредактировать файл /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf внутри контейнера приложения.
У меня то же самое. Я не получил предупреждения о сроке действия сертификата. Перезапуск сервера и запуск пересборки /var/discourse % ./launcher rebuild помогли.
При тестировании на чистой установке nginx (версия 1.18.0, но, думаю, то же самое для 1.26.3) строка конфигурации nginx return 301 https://thehostname$request_uri;, расположенная вне блока location, полностью перекрывает любой предшествующий блок location, вместо того чтобы работать как универсальный обработчик. Мне кажется, что /.well-known/ просто не обслуживается на порту 80, если перенаправление 301 явно не настроено для другого расположения, например /, в конце блока server. Возможно, это та же проблема, что и в этом посте на Stack Overflow?
Рад, что пересборка работает, но поскольку сертификат уже был продлён для меня, я не мог подтвердить, что пересборка позволит серверам валидации Let’s Encrypt получить доступ к нужным ресурсам, если бы сертификат истёк. Возможно, пересборка запускает процесс продления сертификата до того, как в шаблоне появится соответствующая строка, или что-то подобное, а не исправляет сами шаблоны, но я не могу подтвердить, что именно поэтому пересборка позволяет продлению сработать.
Могу подтвердить, что обновление сертификата Let’s Encrypt не выполняется. Я уже несколько лет использую самохостинговую установку Discourse, и очень странно, что за последние пару месяцев обновление не сработало дважды подряд. Второй раз это произошло сегодня утром, и я начал расследование.
Во-первых, return 301 https://${DISCOURSE_HOSTNAME}$request_uri; преобразуется в return 301 https://<МОЁ ИМЯ СЕРВЕРА> без $request_uri в конце. Я проверил это на своей самохостинговой установке, а также на установке друга, настроенной на прошлой неделе. Я не понимаю, как работают шаблоны Discourse, поэтому не знаю, почему $request_uri теряется.
Во-вторых, как отметил @lessLost, 301-редирект находится вне блока location. Я считаю, что редирект на уровне server переопределяет все блоки location. Let’s Encrypt использует HTTP для обновления сертификатов. Однако любая попытка выполнить curl -I http://ВАШ_ДОМЕН/.well-known/acme-challenge/test возвращает 301-редирект на HTTPS вместо 404 (что является ожидаемым поведением; нам нужен 404, а не 301).
Я исправил это вручную на своей самохостинговой установке, но ожидаю, что любое обновление перезапишет мои изменения. К сожалению, я недостаточно хорошо понимаю шаблоны, чтобы отправить pull request @pfaffman — иначе я бы это сделал.
Дополнено:
Я считаю, что это ошибочно —
Я почти уверен, что Let’s Encrypt по умолчанию использует HTTP (по очевидным причинам: если сертификат истёк, он не может обновиться!). Однако размещение 301-редиректа на уровне блока server заставляет все запросы перенаправляться на HTTPS, что противоречит этой стратегии обновления.
Сегодня утром, примерно через 10 минут после пробуждения, я зашёл на свой форум и обнаружил, что сертификат снова истёк. (Последний раз, когда это произошло со мной — примерно 3 месяца назад — обновление было выполнено путём пересборки.)
Похоже, что с тех пор были внесены изменения, которые исправляют эту проблему, но поскольку на проверку уходит 3 месяца, окончательного вердикта ещё нет. Возможно, стоит установить напоминание за пару недель до истечения текущего сертификата.
Установка нового сайта моего друга была сделана неделю назад. Строка 37 шаблона выше содержит: return 301 https://${DISCOURSE_HOSTNAME}$request_uri;, но в контейнере Discourse Docker как у неё, так и у меня файл /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf содержит return 301 https://<our_discourse_site>;. Обратите внимание, что $request_uri удалён. Что-то вызывает его исчезновение! (Я не знаю, что именно).
Сегодня утром я провёл симуляцию принудительного обновления в рамках расследования. Оно не удалось. Затем я изменил файл /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf. После этого обновление прошло успешно!
На самом деле это не проблема; я просто буду вручную редактировать 20-redirect-http-to-https.conf каждый раз при обновлении Discourse. Для тех, кто наткнулся на этот комментарий, команда для выполнения:
Я не полностью уверен, что вызывает эту ошибку, но знаю, что изменение конфигурации выше решает проблему. Однако я также модифицировал уведомления, чтобы обновления letsencrypt больше не завершались неудачей без предупреждения — теперь у меня будет заблаговременное оповещение. Просто хотел, чтобы вы знали!