Mastodon+SendGridでSMTP_OPENSSL_VERIFY_MODEをpeerで動作させる

  • 6
    いいね
  • 0
    コメント

MastodonのメールサーバにSendGridを使った場合に少しだけハマったので解決策をメモ。

現象

MastodonのメールサーバにSendGridを使った際、以下のようなエラーが出てメール送信できない場合があります。エラーの意味は「SSL証明書の検証に失敗した」というもの。Herokuにデプロした環境で確認しました。

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed

原因

Mastodonのメール周りの設定は以下の通りです。他の設定についてはドキュメントを参照してください。

変数
SMTP_AUTH_METHOD plain
SMTP_ENABLE_STARTTLS_AUTO true
SMTP_FROM_ADDRESS 送信元メールアドレス
SMTP_LOGIN apikey
SMTP_OPENSSL_VERIFY_MODE peer
SMTP_PASSWORD Mail Sendパーミッションを与えたSendGridのAPIキー
SMTP_PORT 587
SMTP_SERVER smtp.sendgrid.net

ポイントはSMTP_OPENSSL_VERIFY_MODEpeerに設定している点。この設定にすることでSMTPサーバのSSL証明書の有効性を検証して、接続先がなりすまされていないことを確認できます。冒頭のエラーはこの検証に失敗したことを意味しています。
原因として考えられるのは次のようなものがあります。

  1. 証明書の有効期限が切れている
  2. 証明書が失効リストに登録されている
  3. クライアント側に対応するCA証明書がない、もしくは適切に設定されていない

1と2はSendGrid側で証明書の管理が適切に行われていれば発生することはないので、可能性として一番高いのは3です。

解決策

一応、前提条件として、Mastodon〜SendGrid間はTLSを使って暗号化するものとします。

1. 証明書の検証をしない方法(非推奨)
一番手っ取り早いのがSMTP_OPENSSL_VERIFY_MODEnoneにして証明書の検証をスキップする方法です。この設定にしても通信はTLSで暗号化されますが、サーバ側がなりすまされていた場合に情報が漏えいする危険性があります。とりあえずの対処と考えてください。
2. 証明書の検証をする方法(推奨)
CA証明書のパスを設定すればちゃんと検証できるようになります。こっちの方が前向きですね。MastodonはActionMailerを使ってメールを送信しています。

まず、mastodon/config/environments/production.rbを編集して、config.action_mailer.smtp_settingsに:ca_fileの設定を加えます。この変更は、production.rbと同じディレクトリ内にあるCA証明書をca_fileに指定する、という内容です。後で用意するCA証明書のパスを変更する場合は、適当に修正してください。

  # E-mails
  config.action_mailer.smtp_settings = {
    〜省略〜
    :ca_file => File.expand_path(File.dirname(__FILE__)) + '/gd_bundle-g2-g1.crt', # <=この行を加える
  }

次に、CA証明書を準備します。SendGridではGoDaddyというCAが発行した証明書を利用しているので、GoDaddyのCA証明書(ファイル名:gd_bundle-g2-g1.crt)をここからダウンロードして、先程編集したproduction.rbと同じディレクトリに保存します。

以上で完了です。再度デプロイしてユーザー登録すると以下のようなログが出てメールが送信されはずです。

Performed ActionMailer::DeliveryJob from Sidekiq(mailers) in 884.5ms