SMTP 设置在使用 GMail 的 smtp-relay 时不起作用

虽然我相信 @kvsf 的错误已经修复,或者你们的配置中已经发生了一些根本性的变化,但我还是想继续这个帖子,发布我自己的配置、我的进一步尝试以及我在同一问题领域寻求帮助。

基本配置

  • Google Workspace Business Starter
  • 配置 Gmail 路由 > SMTP 中继,使用 i) 仅限域内注册用户,ii) IP 白名单(我的论坛托管服务器 IP)并强制执行 SMTP 身份验证,iii) 强制执行 TLS
  • discourse docker 安装,遵循 discourse 文档
  • app.yml 配置如下:
expose:
  - "80:80"   # http
  - "443:443" # https

env:
  DISCOURSE_HOSTNAME: "forum.mydomain.com"
  DISCOURSE_DEVELOPER_EMAILS: 'dev@mydomain.com'

  DISCOURSE_SMTP_ADDRESS: "smtp-relay.gmail.com"
  DISCOURSE_SMTP_PORT: 587
  DISCOURSE_SMTP_USER_NAME: "user@mydomain.com"
  DISCOURSE_SMTP_PASSWORD: "mypass"
  DISCOURSE_SMTP_ENABLE_START_TLS: true
  DISCOURSE_SMTP_AUTHENTICATION: login
  DISCOURSE_SMTP_OPEN_TIMEOUT: 25
  DISCOURSE_SMTP_READ_TIMEOUT: 25
  DISCOURSE_SMTP_DOMAIN: "mydomain.com"
  DISCOURSE_NOTIFICATION_EMAIL: "noreply@mydomain.com"
  LETSENCRYPT_ACCOUNT_EMAIL: dev@mydomain.com

我的测试

运行 ./discourse-doctor 时,此配置会导致以下错误:

Testing sending to ...
SMTP server connection successful.
Sending to artificial.testadress@gmail.com. . .
Sending mail failed.
end of file reached

我首先通过 discourse 和邮件日志 检查了不同的日志。
通过 docker exec -it <CONTAINER_ID> bash 从 docker 内部手动测试相同的过程,使用:

openssl s_client -starttls smtp -crlf -connect smtp.gmail.com:587

没有遇到任何问题,运行正常。所以我认为要么是我的 app.yml 中的参数配置有问题,要么是 discourse 内部存在脚本通信错误,或者……有太多可能性了。^^
为了在测试不同设置时不必每次更改 app.yml 后都运行 ./launcher rebuild app,我开始直接编辑 /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/mail-2.8.1/lib/mail/network/delivery_methods/smtp.rb,将现有代码更改为:

class SMTP
  attr_accessor :settings

  DEFAULTS = {
    :address              => 'smtp-relay.gmail.com',
    :port                 => 587,
    :domain               => 'mydomain.com',
    :user_name            => 'user@mydomain.com',
    :password             => 'mypass',
    :authentication       => 'login',
    :enable_starttls      => nil,
    :enable_starttls_auto => true,
    :openssl_verify_mode  => 'peer',
    :ssl                  => nil,
    :tls                  => nil,
    :open_timeout         => 25,
    :read_timeout         => 25
  }

  def initialize(values)
    self.settings = DEFAULTS #.merge(values)
  end

这会导致与上述情况相同的行为(给定自定义的 app.yml 设置)。

寻求帮助

我现在卡住了。当然,我可以尝试更多剩余的设置(甚至可以切换回仅使用 SSL,尽管 discourse 已弃用此功能),但我想:

  1. 学习如何更深入地分析这个问题
  2. 从而理解真正发生的事情以及问题所在
  3. 修复它,并能够顺利使用所有功能(+最终让论坛正常运行)

提前感谢您的帮助。