Несоответствие имени хоста сертификата электронной почты вызывает перегрузку очереди Sidekiq и серьезные сбои в работе сайта

Есть ли способ «откатить» Discourse до более старой рабочей версии (например, 2.8.0 stable или 2.9.0 beta3), пока это не будет исправлено?

Я решил потратить ещё полчаса, чтобы разобраться в этом, и, думаю, нашёл причину.

Похоже, это связано с переходом на Rails 7, который обновил net-smtp с версии 0.1.0 до 0.3.1 и изменил настройки по умолчанию.

Библиотека smtp при вызове net-smtp не отключает параметры enable_starttls_auto и openssl_verify_mode, а включает их только если они уже активированы.

Связано с: SMTP: allow disabling starttls_auto since it's now true by default in Ruby 3 by jeremy · Pull Request #1435 · mikel/mail · GitHub

Отличная работа, Ричард! Мне бы это заняло два часа, а то и вдвое больше. Мне проще смириться с новыми настройками по умолчанию.

Ага. Значит, я был отчасти прав, просто, возможно, не так уж сложно сделать PR для исправления этого.

Отличная работа, @RGJ!

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

  • Сбои при отправке электронной почты, похоже, повторяются чрезвычайно быстро, из-за чего очередь Sidekiq разрастается до огромных размеров, а загрузка ЦП достигает ~100% из-за этих задач.
  • Кроме того, что-то (либо сбои, либо перезапуски) заставляло Redis записывать огромные временные файлы, которые, предположительно, содержат состояние очереди Sidekiq. Хотя эти файлы можно было безопасно удалить, они быстро заполнили диск, что вызвало новые сбои, и так далее. У меня было немного дополнительного места на диске, которое я смог освободить, чтобы перезапустить форум и разобраться в ситуации, но это может быть не так для всех. (Также довольно сложно подтвердить, что в данном случае временные файлы Redis действительно безопасно удалять.)

Мне кажется, что самое простое решение здесь — замедлить повторные попытки выполнения задач отправки электронной почты при сбоях, или хотя бы тех, у которых нет строгих требований к срочности, таких как сброс пароля. Это кажется уместным, учитывая, что проблемы с электронной почтой вряд ли быстро устранятся, и большинство (если не все) почтовые сервисы сами будут повторять попытки после получения сообщения.

В моём случае после обновления проблема возникла при использовании TLS с сервером третьей стороны: имя в сертификате совпадало с именем SMTP-сервера. У меня был только один сбой. С тех пор я не перезагружал и не обновлял систему, чтобы избежать дополнительных проблем. Как только будет выпущен патч, я попробую обновиться и посмотрю, как всё пойдёт.

Я начну с создания темы в канале bug, но поскольку технически это проблема в внешнем gem-пакете, я не уверен, какой приоритет ей будет присвоен.

+1 :worried:очень раздражающий баг

Разве нельзя откатить gem? Меня удивило бы, если бы на это не обратили внимания, поскольку это «базовая» функциональность — возможность отправки писем. Для некоторых пользователей это также вызывает сбой из-за временных файлов и перегрузки процессора, что приводит к переполнению сервера. Здесь нарушается базовая стабильность форума.

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

Насколько мне известно, мой сервер настроен правильно. Имя сертификата совпадает с именем хоста SMTP, STARTTLS на порту 587. Меня интересует, почему возникла эта проблема?

Спасибо за создание нового тикета. Учитывая ваше понимание, не могли бы вы пояснить, как следует использовать комбинации двух переменных, на которые вы указали в файле YML, для различных сценариев?

DISCOURSE_SMTP_ENABLE_START_TLS: true
DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none

Например, у меня используется только STARTTLS на порту 587, и другие порты не задействованы SMTP по соображениям безопасности. Нужно ли указывать обе переменные в файле YML или достаточно только одной?

Зависит от ситуации.
Если ваш SMTP-сервер настроен правильно, то вам не понадобятся ни одна, ни другая из них.

Но сейчас проблема в том, что они вообще ничего не делают.

Напишите мне в личные сообщения название вашего SMTP-сервера, и я посмотрю, смогу ли выяснить, почему у вас это не работает.

У меня есть локальный SMTP-сервер без поддержки TLS/SSL, и при установке StartTls=false он не работает :frowning:

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

Тем не менее, для тех, кто сталкивается с этой проблемой, одним из вариантов может быть настройка собственного почтового сервера на localhost и просто пересылка почты дальше. Тогда у вас будет контроль над почтовым сервером, с которым взаимодействует Discourse, и ваш локальный почтовый сервер можно настроить для обработки любых проблем, с которыми вы можете столкнуться на стороне провайдера. Я ранее делал это, но в какой-то момент отказался от этого, так как оказалось проще, чтобы Discourse напрямую взаимодействовал с внешним почтовым сервером. (Ой.)

Вот почему Стандартная установка рекомендует сторонних поставщиков почтовых услуг, а не попытку использовать существующее или самостоятельно размещенное решение.

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

Я выбрал Discourse, потому что, как утверждается, его легко установить и поддерживать в небольших самописных развёртываниях.

И это так, если следовать рекомендациям.

Если вы решите пойти другим путём, то гарантировать что-либо действительно невозможно.

Итак, если подытожить, вы говорите, что в Discourse больше невозможно использовать SMTP-сервер без TLS, SSL или StartTLS?

Я не думаю, что кто-то это предполагает. Это касается лишь того, как возникла проблема и сколько времени потребовалось для поиска её первопричины.

Мы видим лишь несколько случаев здесь из-за относительно небольшого числа установок с обновлённым гемом, которые также не передают почту через какой-либо защищённый транспорт.

Ричард уже создал тему об этой ошибке:

Для тех, кому нужно, чтобы это работало скорее, можно либо включить TLS на своём почтовом сервере, либо временно переключиться на почтового провайдера, предлагающего защищённый транспорт.

У меня TLS был включен с самого начала с действительным сертификатом и соответствующим именем хоста, но после обновления до BETA 4 (461936f211) возникла проблема. Я опубликовал логи в теме ниже. У другого пользователя также возникли проблемы, и, по его словам, его сертификаты в порядке:

Мне так кажется. Некоторые комментарии в этой ветке просто возмутили.

Я самостоятельно размещаю Docker-Discourse и использую свой Docker-хост в качестве почтового сервера. На протяжении шести лет, с самого начала, Discourse использовал порт 25 без TLS для отправки писем через внутренний интерфейс Docker. Это абсолютно разумная и безопасная конфигурация. Все транзакции на 100% происходили внутри моего собственного хоста. Подробнее об моей старой конфигурации можно прочитать выше в этой ветке.

Для меня обходным путём стало следующее:

Добавить внутренний IP-адрес интерфейса Docker хоста как допустимый хост в файл зоны DNS для моего домена. То есть:

discourse-mail.jag-lovers.com A 172.17.0.1

Обратите внимание: я мог придумать любое имя хоста в домене jag-lovers.com, так как у меня используется wildcard-сертификат (CN = *.jag-lovers.com). Если у вас нет wildcard-сертификата, обязательно используйте имя хоста, которое является допустимым CN или SAN в вашем сертификате.

Также обратите внимание: IP-адрес, который я использовал выше, — это внутренний IP-адрес, который мой хост использует на интерфейсе Docker для связи с контейнером Discourse-Docker. Это частный, не маршрутизируемый IP-адрес.

Далее измените конфигурацию app.yml приложения Discourse, чтобы оно подключалось к только что созданному имени хоста, использовало TLS, подключалось на порт 587 и использовало SASL для входа на хост при каждой транзакции отправки письма (иначе вы получите ошибку «отказано в ретрансляции»).

  DISCOURSE_SMTP_ADDRESS: discourse-mail.jag-lovers.com
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: REDACTED
  DISCOURSE_SMTP_PASSWORD: "REDACTED"
  DISCOURSE_SMTP_ENABLE_START_TLS: true          # (опционально, по умолчанию true)
  DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none
  DISCOURSE_SMTP_DOMAIN: jag-lovers.com

Затем пересоберите Discourse. Это решило проблему для меня.