行動すれば次の現実

テック中心の個人ブログ

ActionMailerでOpenSSL::SSL::SSLErrorが発生してメールが送れない

ActionMailerで別ドメインのSMTPサーバー経由でメール送信しようとしたらOpenSSL::SSL::SSLErrorが発生してエラーになりました。

※接続情報等は架空の値になっております。

ERROR -- : OpenSSL::SSL::SSLError
ERROR -- : hostname "smtp.example.com" does not match the server certificate

ActionMailer側の設定は以下の通りです。

config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  user_name: 'test@example.com',
  password: 'hogehoge',
  address: 'smtp.example.com',
  domain: 'smtp.example.com',
  authentication: :plain,
  port: 587,
}

エラーの内容は「証明書と送信元ドメインが一致しない」ということです。

別ドメインからのメール送信ですので、本来はDKIM認証/SPF設定をするのが望ましいのですが、 今回はシステム要件の都合上、別の方法を試したいと思います。

証明書チェックを省いて強引にメールを送信する

今回は強引に送りたいので、STARTTLSを有効にしつつ不正な証明書を受けるけるように設定する方法を取ります。

config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  user_name: 'test@example.com',
  password: 'hogehoge',
  address: 'smtp.example.com',
  domain: 'smtp.example.com',
  authentication: :plain,
  enable_starttls_auto: true, # STARTTLSに自動接続する
  openssl_verify_mode: 'none', # 証明書の妥当性はチェックしない
  port: 587
}

authenticationがloginかplainはSMTPサーバーによって違いますので、それぞれで試して使用できる方を採用します。

それ以外の接続エラー

上記の設定をしてもサーバーによっては別のエラーで送信できないことがありました。

No route to host - connect(2) for "smtp.example.com" port 587

「宛先ホストへの送信経路が存在しない」という内容ですので、ファイアウォールで弾かれている可能性が高いです。

$ telnet smtp.example.com 587
telnet: Unable to connect to remote host: No route to host

telnet等で疎通確認をして、接続出来ない場合は宛先ホストのファイアウォール設定を見直すことで解決するかと思います。

国内レンタルサーバーやVPSを使用している場合、海外IPからの接続が拒否されているケースがありますので、全て許可するようにするか、ホワイトリストで対応するなどの考慮が必要になります。

参考

rails/configuring.md at 481343ed91a66a112f7d929a73214f42ffb38dfc · rails/rails · GitHub

ruby - rails email error - 530-5.5.1 Authentication Required. - Stack Overflow