Почтовый клиент не доставляет письма в Discourse

Я допустил эту ошибку и оставил discourse.example.com в файле mail-receiver.yml.

Я уже исправил это, но mail-receiver, похоже, не «получает» новые данные.
Как «сбросить» mail-receiver (например, какая команда аналогична ./launcher rebuild app?).

Редактирование: Я недостаточно внимательно прочитал предыдущий пост — команда ./launcher rebuild mail_receiver.

Теперь у меня возникла ещё одна проблема: mail-receiver не доставляет письма в Discourse. Я пытался найти решение, но безрезультатно.

Логи:

Starting Postfix
Dec 14 03:12:32 forum-mail-receiver postfix/master[1]: daemon started -- version 3.5.6, configuration /etc/postfix
Dec 14 03:15:47 forum-mail-receiver postfix/smtpd[113]: connect from mail-pl1-f169.google.com[209.85.214.169]
Dec 14 03:15:47 forum-mail-receiver postfix/smtpd[113]: 821CB37A659: client=mail-pl1-f169.google.com[209.85.214.169]
Dec 14 03:15:47 forum-mail-receiver postfix/cleanup[120]: 821CB37A659: message-id=<602f2194be912e92b969eacf5eac26e2@frontapp.com>
Dec 14 03:15:47 forum-mail-receiver postfix/qmgr[98]: 821CB37A659: from=[мой личный адрес электронной почты], size=4086, nrcpt=1 (queue active)
<23>Dec 14 03:15:47 receive-mail[122]: Recipient: nobody@[мой URL форума]Dec 14 03:16:20 forum-mail-receiver postfix/smtpd[113]: disconnect from mail-pl1-f169.google.com[209.85.214.169] ehlo=1 mail=1 rcpt=1 bdat=1 quit=1 commands=5
<19>Dec 14 03:16:47 receive-mail[122]: Failed to POST the e-mail to [мой URL форума]/admin/email/handle_mail: execution expired (Net::OpenTimeout)<19>Dec 14 03:16:47 receive-mail[122]:   /usr/lib/ruby/2.7.0/net/http.rb:960:in `initialize'
  /usr/lib/ruby/2.7.0/net/http.rb:960:in `open'
  /usr/lib/ruby/2.7.0/net/http.rb:960:in `block in connect'
  /usr/lib/ruby/2.7.0/timeout.rb:105:in `timeout'
  /usr/lib/ruby/2.7.0/net/http.rb:958:in `connect'
  /usr/lib/ruby/2.7.0/net/http.rb:943:in `do_start'
  /usr/lib/ruby/2.7.0/net/http.rb:932:in `start'
  /usr/lib/ruby/2.7.0/net/http.rb:1483:in `request'
  /usr/local/lib/site_ruby/mail_receiver/discourse_mail_receiver.rb:43:in `process'
  /usr/local/bin/receive-mail:13:in `<main>'Dec 14 03:16:47 forum-mail-receiver postfix/pipe[121]: 821CB37A659: to=<nobody@[мой URL форума]>, relay=discourse, delay=60, delays=0.17/0.01/0/60, dsn=4.3.0, status=deferred (temporary failure)
Dec 14 03:17:32 forum-mail-receiver postfix/qmgr[98]: 7C67437A663: from=<[мой личный адрес электронной почты]>, size=4093, nrcpt=1 (queue active)

Есть какие-то идеи, что может вызывать эту проблему?

Файл mail-receiver.yml корректен, и я проверил его на опечатки:

Вот мои права доступа к API-ключу:

Письма доходят до mail-receiver, но просто висят в очереди mailq:

Или есть ли способ полностью удалить контейнер mail-receiver и начать заново?

Проблема может заключаться в том, что у вас не установлен ключ API

Спасибо за ответ @pfaffman… Это точно указано в моём файле конфигурации mail-receiver.yml. Нужно ли заключать это в кавычки?

 (Net::OpenTimeout)

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

Как я могу продолжить устранение неполадок?

ping forum.[mydomain].co.nz

изнутри mailq показывает:

64 байта от [ip].vultrusercontent.com ([ip]): icmp_seq=1 ttl=64 время=0.113 мс
64 байта от [ip].vultrusercontent.com ([ip]): icmp_seq=2 ttl=64 время=0.074 мс
64 байта от [ip].vultrusercontent.com ([ip]): icmp_seq=3 ttl=64 время=0.069 мс

и так далее, что подтверждает успешное подключение.
forum.[mydomain].co.nz — это адрес, где размещён форум, и этот же URL используется в MAIL_DOMAIN и DISCOURSE_MAIL_ENDPOINT.

Внимательно изучив настройки mail-receiver.yml, не забыл ли я где-то кавычки или https://, которые должны быть там?

## это шаблон контейнера для входящей почты
##
## После внесения изменений в этот файл вы ОБЯЗАНЫ выполнить
## /var/discourse/launcher rebuild mail-receiver
##
## БУДЬТЕ *ОЧЕНЬ* ОСТОРОЖНЫ ПРИ РЕДАКТИРОВАНИИ!
## YAML-ФАЙЛЫ ЧРЕЗВЫЧАЙНО ЧУВСТВИТЕЛЬНЫ К ОШИБКАМ В ПРОБЕЛАХ И ВЫРАВНИВАНИИ!
## при необходимости проверьте этот файл на http://www.yamllint.com/

base_image: discourse/mail-receiver:release
update_pups: false

expose:
  - "25:25"   # SMTP

env:
  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8

  ## Куда должна отправляться почта для вашего форума. В целом, вполне допустимо
  ## использовать здесь тот же домен, что и сам форум.
  MAIL_DOMAIN: forum.[domain].co.nz
# раскомментируйте эти строки (и том ниже!), чтобы включить поддержку TLS
#  POSTCONF_smtpd_tls_key_file:  /letsencrypt/discourse.example.com/discourse.example.com.key
#  POSTCONF_smtpd_tls_cert_file:  /letsencrypt/discourse.example.com/fullchain.cer
#  POSTCONF_smtpd_tls_security_level: may


  ## URL конечной точки обработки почты вашего форума Discourse.
  ## Это просто базовый URL вашего форума с добавленным в конце
  ## `/admin/email/handle_mail`. Будьте осторожны, если используете настройку с подпапкой — в этом случае
  ## URL должен включать подпапку!
  DISCOURSE_MAIL_ENDPOINT: 'https://forum.[domain].co.nz/admin/email/handle_mail'

  ## Главный API-ключ вашего форума Discourse. Его можно получить на
  ## вкладке "API" в панели администратора.
  DISCOURSE_API_KEY: 639[остальное API-ключа]884ef

  ## Имя пользователя для обработки входящей почты. Если вы не меняли имя
  ## пользователя `system`, оставьте это значение без изменений.
  DISCOURSE_API_USERNAME: system

volumes:
  - volume:
      host: /var/discourse/shared/mail-receiver/postfix-spool
      guest: /var/spool/postfix
# раскомментируйте для поддержки TLS
#  - volume:
#      host: /var/discourse/shared/standalone/letsencrypt
#      guest: /letsencrypt

Запускаете ли вы ping внутри контейнера, то есть после выполнения ./launcher enter mail-receiver?

Также стоит отметить, что ping (обычно ICMP) отличается от подключения по http/https (TCP) и может вести себя по-разному в зависимости от множества факторов конфигурации сети.

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

cd /var/discourse
./launcher enter mail-receiver
curl -v https://forum.[domain].co.nz

Если всё работает, выведется много HTML-кода. Если нет, появится ошибка, а флаг -v покажет подробную информацию по ходу выполнения, что может помочь понять причину сбоя.

Если команда не сработает, также стоит попробовать выполнить тот же запрос curl вне контейнера, чтобы определить, проблема ли это конкретного контейнера или же всей хост-системы в целом.

Спасибо, @Simon_Manning, ваша помощь очень ценна! Я не знал, что соединения через ping не обязательно совпадают с соединениями через curl.

Я запускал ping внутри контейнера, и он успешно выполнился.

Я последовал вашим инструкциям и запустил curl внутри контейнера, но он не сработал:

root@forum:/var/discourse# ./launcher enter mail-receiver
x86_64 arch detected.
WARNING: containers/mail-receiver.yml file is world-readable. You can secure this file by running: chmod o-rwx containers/mail-receiver.yml
bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
root@forum-mail-receiver:/# curl -v https://forum.[domain].co.nz
*   Trying [IPv4 address]:443...
*   Trying [IPv6 address]:443...
* Immediate connect fail for [IPv6 address]: Cannot assign requested address
* connect to [IPv4 address] port 443 failed: Connection timed out
* Failed to connect to forum.[domain].co.nz port 443: Connection timed out
* Closing connection 0
curl: (28) Failed to connect to forum.[domain].co.nz port 443: Connection timed out

Затем я выполнил exit, а затем снова запустил curl и получил:

root@forum:/var/discourse# curl -v https://forum.[domain].co.nz
*   Trying 127.0.1.1:443...
* Connected to forum.[domain].co.nz (127.0.1.1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: /etc/ssl/certs
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
...и так далее.

Похоже, проблема специфична для контейнера, а не для хост-системы — есть какие-либо идеи?

Я также открыл тикет в службу поддержки Vultr (провайдер VPS для этого экземпляра), чтобы проверить, не проблема ли это на их стороне!

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

Обычно это не проблема для mail-receiver, поскольку ваш контейнер Discourse имеет открытый порт 443 за пределами этой сети, и когда mail-receiver пытается подключиться к адресу 1.2.3.4, соединение выходит за пределы сети Docker. Хост-система (или какая-то внешняя сетевая инфраструктура) понимает, что соединение должно вернуться обратно, и в итоге оно попадает в контейнер Discourse извне.

Приходят на ум два возможных сценария. Первый: mail-receiver каким-то образом знает IP-адрес контейнера Discourse при разрешении доменного имени, и поэтому соединение внутри контейнера блокируется. Мне кажется, это маловероятно.

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

Вы не можете использовать HTTPS, потому что не раскомментировали следующее:

Это относится только к поддержке TLS на стороне почтового сервера, то есть для того, чтобы другие почтовые серверы могли доставлять электронные письма mail-receiver по TLS.

Стоит сделать, поскольку в контейнере Discourse, очевидно, есть сертификат, но это не должно повлиять на подключение mail-receiver к Discourse. Однако это может повлиять на пересборку, если она исправит что-то в настройках сети контейнера.

Спасибо, я раскомментировал эти строки, а также строку для тома.

Теперь мой файл mail-receiver.yml выглядит так:

root@forum:/var/discourse# cat containers/mail-receiver.yml
## это шаблон контейнера для входящей почты
##
## После внесения изменений в этот файл вы ОБЯЗАТЕЛЬНО должны выполнить пересборку
## /var/discourse/launcher rebuild mail-receiver
##
## БУДЬТЕ ОЧЕНЬ ОСТОРОЖНЫ ПРИ РЕДАКТИРОВАНИИ!
## YAML-ФАЙЛЫ ЧРЕЗВЫЧАЙНО ЧУВСТВИТЕЛЬНЫ К ОШИБКАМ В ПРОБЕЛАХ И ВЫРАВНИВАНИИ!
## при необходимости проверяйте этот файл на сайте http://www.yamllint.com/

base_image: discourse/mail-receiver:release
update_pups: false

expose:
  - "25:25"   # SMTP

env:
  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8

  ## Адрес, куда должна отправляться почта на ваш форум. В целом, вполне допустимо
  ## использовать здесь тот же домен, что и у самого форума.
  MAIL_DOMAIN: forum.[domain].co.nz
# раскомментируйте эти строки (и том ниже!), чтобы включить поддержку TLS
  POSTCONF_smtpd_tls_key_file:  /letsencrypt/forum.[domain].co.nz/forum.[domain].co.nz.key
  POSTCONF_smtpd_tls_cert_file:  /letsencrypt/forum.[domain].co.nz/fullchain.cer
  POSTCONF_smtpd_tls_security_level: may


  ## URL конечной точки обработки почты вашего форума Discourse.
  ## Это просто базовый URL вашего форума с добавленным в конце
  ## `/admin/email/handle_mail`. Будьте внимательны, если используете настройку с подпапкой — в этом случае
  ## URL должен включать подпапку!
  DISCOURSE_MAIL_ENDPOINT: 'https://forum.[domain].co.nz/admin/email/handle_mail'

  ## Главный API-ключ вашего форума Discourse. Его можно получить
  ## на вкладке "API" в панели администратора.
  DISCOURSE_API_KEY: '074[остальная часть API-ключа — да, я сгенерировал новый, ограниченный для системного пользователя]d98'

  ## Имя пользователя, используемое для обработки входящей почты. Если вы не переименовывали
  ## пользователя `system`, оставьте это значение без изменений.
  DISCOURSE_API_USERNAME: system

volumes:
  - volume:
      host: /var/discourse/shared/mail-receiver/postfix-spool
      guest: /var/spool/postfix
# раскомментируйте для поддержки TLS
  - volume:
      host: /var/discourse/shared/standalone/letsencrypt
      guest: /letsencrypt

Когда я отправляю новое письмо и выполняю ./launcher logs mail-receiver, вот что я вижу:

Dec 21 22:41:21 forum-mail-receiver postfix/smtpd[132]: connect from mail-pj1-f54.google.com[209.85.216.54]
Dec 21 22:41:23 forum-mail-receiver postfix/smtpd[132]: 16DAC379E42: client=mail-pj1-f54.google.com[209.85.216.54]
Dec 21 22:41:23 forum-mail-receiver postfix/cleanup[139]: 16DAC379E42: message-id=<94fc2bef18b410ae8b121c6af2da2df4@frontapp.com>
Dec 21 22:41:23 forum-mail-receiver postfix/qmgr[100]: 16DAC379E42: from=<[мой email адрес]>, size=5585, nrcpt=1 (queue active)
<23>Dec 21 22:41:23 receive-mail[141]: Recipient: nobody@forum.[domain].co.nzDec 21 22:41:50 forum-mail-receiver postfix/smtpd[143]: connect from mail-oa1-f50.google.com[209.85.160.50]
Dec 21 22:41:52 forum-mail-receiver postfix/smtpd[143]: 2E445379E48: client=mail-oa1-f50.google.com[209.85.160.50]
Dec 21 22:41:52 forum-mail-receiver postfix/cleanup[139]: 2E445379E48: message-id=<6b2f9d646dc46f4fec4af006de01d3ae@frontapp.com>
Dec 21 22:41:52 forum-mail-receiver postfix/qmgr[100]: 2E445379E48: from=<[мой email адрес]>, size=4100, nrcpt=1 (queue active)
<23>Dec 21 22:41:52 receive-mail[147]: Recipient: nobody@forum.[domain].co.nzDec 21 22:41:53 forum-mail-receiver postfix/smtpd[132]: disconnect from mail-pj1-f54.google.com[209.85.216.54] ehlo=2 starttls=1 mail=1 rcpt=1 bdat=1 quit=1 commands=7
Dec 21 22:41:58 forum-mail-receiver postfix/qmgr[100]: 1194937A670: from=<double-bounce@forum-mail-receiver.localdomain>, size=942, nrcpt=1 (queue active)
Dec 21 22:41:58 forum-mail-receiver postfix/smtp[149]: fatal: unknown service: smtp/tcp
Dec 21 22:41:59 forum-mail-receiver postfix/qmgr[100]: warning: private/smtp socket: malformed response
Dec 21 22:41:59 forum-mail-receiver postfix/qmgr[100]: warning: transport smtp failure -- see a previous warning/fatal/panic logfile record for the problem description
Dec 21 22:41:59 forum-mail-receiver postfix/master[1]: warning: process /usr/lib/postfix/sbin/smtp pid 149 exit status 1
Dec 21 22:41:59 forum-mail-receiver postfix/master[1]: warning: /usr/lib/postfix/sbin/smtp: bad command startup -- throttling
Dec 21 22:41:59 forum-mail-receiver postfix/error[150]: 1194937A670: to=<postmaster@forum-mail-receiver.localdomain>, orig_to=<postmaster>, relay=none, delay=1192, delays=1191/1/0/0.01, dsn=4.3.0, status=deferred (unknown mail transport error)
<19>Dec 21 22:42:23 receive-mail[141]: Failed to POST the e-mail to https://forum.sobercheck.co.nz/admin/email/handle_mail: execution expired (Net::OpenTimeout)<19>Dec 21 22:42:23 receive-mail[141]:   /usr/lib/ruby/2.7.0/net/http.rb:960:in `initialize'
  /usr/lib/ruby/2.7.0/net/http.rb:960:in `open'
  /usr/lib/ruby/2.7.0/net/http.rb:960:in `block in connect'
  /usr/lib/ruby/2.7.0/timeout.rb:105:in `timeout'
  /usr/lib/ruby/2.7.0/net/http.rb:958:in `connect'
  /usr/lib/ruby/2.7.0/net/http.rb:943:in `do_start'
  /usr/lib/ruby/2.7.0/net/http.rb:932:in `start'
  /usr/lib/ruby/2.7.0/net/http.rb:1483:in `request'
  /usr/local/lib/site_ruby/mail_receiver/discourse_mail_receiver.rb:43:in `process'
  /usr/local/bin/receive-mail:13:in `<main>'Dec 21 22:42:23 forum-mail-receiver postfix/pipe[140]: 16DAC379E42: to=<nobody@forum.[domain].co.nz>, relay=discourse, delay=60, delays=0.23/0.01/0/60, dsn=4.3.0, status=deferred (temporary failure)
Dec 21 22:42:25 forum-mail-receiver postfix/smtpd[143]: disconnect from mail-oa1-f50.google.com[209.85.160.50] ehlo=2 starttls=1 mail=1 rcpt=1 bdat=1 quit=1 commands=7
<19>Dec 21 22:42:52 receive-mail[147]: Failed to POST the e-mail to https://forum.[domain].co.nz/admin/email/handle_mail: execution expired (Net::OpenTimeout)<19>Dec 21 22:42:52 receive-mail[147]:   /usr/lib/ruby/2.7.0/net/http.rb:960:in `initialize'
  /usr/lib/ruby/2.7.0/net/http.rb:960:in `open'
  /usr/lib/ruby/2.7.0/net/http.rb:960:in `block in connect'
  /usr/lib/ruby/2.7.0/timeout.rb:105:in `timeout'
  /usr/lib/ruby/2.7.0/net/http.rb:958:in `connect'
  /usr/lib/ruby/2.7.0/net/http.rb:943:in `do_start'
  /usr/lib/ruby/2.7.0/net/http.rb:932:in `start'
  /usr/lib/ruby/2.7.0/net/http.rb:1483:in `request'
  /usr/local/lib/site_ruby/mail_receiver/discourse_mail_receiver.rb:43:in `process'
  /usr/local/bin/receive-mail:13:in `<main>'Dec 21 22:42:52 forum-mail-receiver postfix/pipe[146]: 2E445379E48: to=<nobody@forum.[domain].co.nz>, relay=discourse, delay=60, delays=0.15/0.01/0/60, dsn=4.3.0, status=deferred (temporary failure)
Dec 21 22:45:45 forum-mail-receiver postfix/anvil[135]: statistics: max connection rate 1/60s for (smtp:209.85.216.54) at Dec 21 22:41:21
Dec 21 22:45:45 forum-mail-receiver postfix/anvil[135]: statistics: max connection count 1 for (smtp:209.85.216.54) at Dec 21 22:41:21
Dec 21 22:45:45 forum-mail-receiver postfix/anvil[135]: statistics: max cache size 2 at Dec 21 22:41:50

Я действительно застрял. У кого-нибудь есть идеи, что может вызывать эту проблему? :grinning_face_with_smiling_eyes:

Ой! Да. Я перепутал TLS и HTTPS.

Это всё ещё вообще не работает: письма не передаются от mail-receiver в Discourse.

Могу ли я «откатить» mail-receiver к начальному состоянию (полностью сбросить его) и начать заново, в надежде, что тогда всё заработает?
Как это сделать?

Вы можете просто отредактировать файл и пересобрать контейнер почты.

Спасибо за совет насчёт фаервола! У меня тоже возникли проблемы, похожие на те, что были у @MathiasFoster: контейнер mail-receiver не мог подключиться к сайту форума в контейнере app. Сначала это казалось загадочным, ведь контейнеры без проблем могли принимать входящие соединения извне.

Я тоже использую Vultr как провайдера VPS с их образом Ubuntu. Похоже, какая-то комбинация настроек по умолчанию в образе ОС и Docker действительно блокирует связь между контейнерами.

В моём случае достаточно было разрешить HTTPS на хосте:

$ ufw allow https

После этого mail-receiver смог доставлять письма, как и ожидалось.