Upgrade to Pro — share decks privately, control downloads, hide ads and more …

はてなにおけるメール基盤とDMARC対応

Mitsuru Takigahira
April 19, 2024
5.7k

 はてなにおけるメール基盤とDMARC対応

https://platformengineering.connpass.com/event/310994/ で発表させて頂いた内容になります。

Mitsuru Takigahira

April 19, 2024
Tweet

Transcript

  1. 自己紹介 • id: MysticDoll / 瀧ヶ平 充 • 株式会社はてな (2023/4~)

    ◦ システムプラットフォームチーム所属 Platform SRE • 社内基盤の運用とかやり続けて7年目 ◦ 前職ではGHE運用やCI/CDツールの開発・運用とか ◦ Screwdriver.cd Most Valuable Contributer (2021 CD Foundation Project Awards) 2
  2. DKIM(RFC 6376) DKIMでは以下の方法でメールの送信者を認証する 送信者はメール本文・ヘッダの内容を元に • 電子署名を作成 • DKIM-Signatureヘッダに記録 ◦ 署名に使用した秘密鍵に対応するセレクタ、署名に利用したヘッダなどを記録

    受信者はメールのDKIM-Signatureヘッダの内容から • 対応する公開鍵をDNSレコードから取得 ◦ <selector>._domainkey.<domain> のTXTレコードを参照する • 署名を検証 10
  3. DMARCの対応でやるべきこと SPF: • 把握した送信元IPをSPFレコードに全て追加する ◦ SaaSの場合は各社のサポートページ等に設定内容がある ◦ 独自システムの場合はシステムの利用しているIGWを追加する DKIM: •

    把握した送信元でに対応するDKIMレコードを追加する ◦ SaaSの場合、設定ページなどから設定項目を取得する ◦ 独自システムの場合はMTA毎に設定方法が異なる 13
  4. はてなのメール送信システム • ECS Anywhereで管理・運用 ◦ さくらのクラウド上のコンテナ実行基盤を利用 • サービスからはNLBを経由してSMTPでアクセス ◦ さくらのクラウドとAWS

    VPCはTGWで疎通可能となっている ◦ コンテナからNLBのtarget groupへの登録の話は今回は割愛 • ECS TaskとしてPostfixが稼動 17
  5. OpenDKIM PostfixでのDKIM対応にはOpenDKIMを利用する • Postfixとはmilter APIを利用して連携する • milter APIでの通信は以下どちらかで行う ◦ Unix

    Domain Socket ◦ TCP Socket • 今回はsidecarとしてOpenDKIMコンテナを起動した ◦ 以下の点を考慮しsidecarとして起動することにした ▪ Postfixと同居させる場合コンテナ起動スクリプトが煩雑化する ▪ 個別のタスクとLBを立てる場合アクセス制御を考える必要がある 21
  6. OpenDKIM sidecar ECS Anywhereでは以下の点に注意が必要 • プロセス間でTCP通信する際はlinksの設定が必要 ◦ Fargateならこの問題はない ◦ 厳密にはポートマッピングをすれば通信可能ではある

    ▪ 外部のMTAから署名されたくないため今回はlinks設定を使用 ◦ linksを使う場合ネットワークモードがbridgeである必要がある 23
  7. OpenDKIMの設定 • 送信ドメインのDNSにDKIMのレコードを追加しておく • opendkim.confに以下を設定する ◦ 署名すべきドメイン (Domain) ◦ 使う鍵ファイルのパス

    (KeyFile) ◦ ListenするSocketの設定 (Socket) ◦ Postfixへの送信元IPレンジ (InternalHosts) • Postfixの main.cf で non_smtpd_milters にopendkimのSocketを指定 これらの設定はdocker-compose等でメール送受信環境を作って検証できる • 仮にDNSを設定していなくてもDKIM署名ができていることは確認できる ◦ その場合意味の無い署名ではあるが、DKIM署名の設定の確認には便利 24
  8. バウンスメールのDKIM署名 バウンスメールはデフォルトではmilterが適用されない → main.cf で internal_mail_filter_classes を設定 • bounceを指定する •

    迷惑メール率を下げるために考慮する必要がある ◦ 不特定多数に送るシステムではバウンスメールが大量発生しうる ▪ 受信側からレポートが送信されないことが保証できれば必要ない ◦ はてなではバウンスメールをAmazon SESに送っている ▪ Amazon SESからのDMARCレポートで発覚した 25
  9. ログからのエラー判別 Postfixのログには以下が含まれている、これらでエラーが判別可能 • SMTP Reply Code ◦ 3桁の数値 210とか ◦

    RFC5321で定義 • Delivery Status Notification(以下DSN) ◦ RFC3464で定義 ◦ 判別に使うのは status field で 「.」 区切りの3つの数値の組 ▪ 5.7.26 みたいなやつ ▪ RFC3463で定義 ▪ RFC3463で書かれているコード以外は IANA.org に一覧がある (RFC 5248) • https://www.iana.org/assignments/smtp-enhanced-status-codes/smtp-enhanced-status-codes.xhtml 30
  10. Postfixのログ形式 CloudWatch Logs Insightsで調べてみると • SMTP Reply Codeは接続先MTAからのメッセージ中 ◦ said:

    550 ….のような形 • DSNは以下2パターン、どちらかしかないこともある ◦ dsn=2.0.0 のような形式のパラメータ ◦ 接続先MTAが返すメッセージ中の 「said: 550-4.7.1 …」など 31
  11. 実際のログ形式 Feb 05 04:54:08 mailoutbound-fb postfix/smtp[1285887]: 38E2AC2616: to=<****@gmail.com>, relay=alt1.gmail-smtp-in.l.google.com[142.250.141.26]:25, delay=974719,

    delays=974661/55/2.3/0.22, dsn=4.2.2, status=deferred (host alt1.gmail-smtp-in.l.google.com[142.250.141.26] said: 452-4.2.2 …(省略)) 赤字の部分がエラー判別に必要 32
  12. cloudwatch-logs-aggregatorの設定 ログ集計用のクエリを作成 注意点としては以下 • DSNはパラメータ・メッセージのどちらかにしかないことがある ◦ →coalesce でどちらかを取る • メッセージ中のDSNの区切りは「-」「

    」(空白)のいずれか ◦ →正規表現で頑張る… • SMTP Reply Codeとの組で監視する ◦ Reply CodeとDSNをconcatしてハイフンで繋ぐ • メトリクス名の「.」は別の字に置換したほうが良い ◦ → replace関数で「.」を「_」に置換 ◦ そのままだとメトリクスが同じグラフに入ってくれなくて見辛い 35
  13. まとめ • DMARC対応には以下が必要 ◦ メール送信元の把握 ◦ SPF/DKIM 認証の設定など ▪ 独自システムでDKIMを設定するためにはOpenDKIMを使う

    ◦ DMARCのレコード設定・レポート送信先の作成 • レポートから設定漏れを潰していく必要がある ◦ 可視化はparsedmarc + OpenSearch + grafana での構築が簡単 ◦ DMARCを可視化してくれるSaaSに頼るのも良い 42
  14. まとめ • メールのログ監視は難しい ◦ 独自基盤でやる場合は避けられない ◦ 完璧にやるなら各メールサービス毎にエラーの対応の把握が必要 • DMARC対応はちゃんとやろう! ◦

    Gmailを使っている顧客に重要なメールが届かないと大変 ◦ 今後ガイドライン適用範囲が変更される可能性もあるため… 43