📧

独自ドメインでメールするために、DKIM/SPF/DMARCのお勉強

2024/09/28に公開

独自ドメインでメールをやりたく、メールサービスを選び始めた。さすがに自分でメールサーバをやる漢気はない。しかし、最近はGmailをはじめ厳しくなったという話はXで聞いている。実際、Gmailだけ届かずにトラブルになったニュースもよく聞く。職業柄、メールが届かないみたいな体たらくをしてしまうとまずいのもあり、メールサービスはきちんと選びたい。

で、色々調べていたんだが、結論として、DKIM/SPF/DMARCの概念を定性的に理解し、やるべきことを把握しておかないと、メールサービスを選ぶこともできんぞということがわかった。

なので、お勉強。この記事の目的は、種々の記事を読んで理解できる基礎知識をつけることである

DKIM/SPF/DMARCについてざっくり

まずDKIM、SPF、DMARCについてどんなものかをそれぞれ述べたい。ざっくりいうと、これらは「そのメールが正規のメールであることをいかにして確認できるようにするか」の仕組みである。なりすましとかじゃないよっていう。恐らくそういった仕組みは今までも各々のサービスでそれぞれ頑張っていたのではないかと思うが、仕組みとして標準化しましょう、ということだと理解している。

この仕組みのために、DNSをフル活用することになる(これは次節で詳述)。

DKIM: 改竄されていないことを確認する

DKIMは DomainKeys Identified Mail の略だ。特定のドメインから送信されたことを証明し、また内容が改竄されていないことを保証する仕組みである。

SPF: 送信元が信頼できることを確認する

SPFは Sender Policy Framework の略だ。これは送信元が信頼できることを示すための仕組みだ。具体的には、送信元と許可される情報をDNSのレコードに保持する。

転送とかあるとエラーが起きそうな気配濃厚だが実際起きるらしい。最初見た時、DKIMだけあれば十分ではないか?と思ったが、DKIMは「特定のドメインから送信された改竄されていないメール」であることしか保証しないため、その送信元があかんところでもPASSする可能性がある。たとえばFromをいじって別のところからきたように見せかけたメールを見破る仕組みにはなっていない。そのため、送信元の信頼性確認する仕組みとしてSPFがある。

つまり、基本的にはなりすまし(スプーフィング)を防ぐ機構といえる。

DMARC: DKIMとSPFを実際にどう適用するかの検証ポリシー

DMARCはDomain-based Message Authentication, Reporting and Conformanceの略だ。覚えられるか。名前で全部説明しようとするな。ラノベのタイトルじゃないんだぞ。

DKIMとSPFの設定は送信サーバと受信サーバの両方でしっかりと対応していないといけない。したがって、正規のメールであっても、その設定に瑕疵があると送受信に失敗する、ということが起きえる。なので、DKIM/SPFちゃんとしてないやつは全部ダメ!とは現実的にできない。

ということで、DKIMとSPFのそれぞれを使って、どれくらい厳格に適用するかを送信者/受信者でそれぞれ決めるポリシー。送信側の要望を加味したうえで、最終的に受信側が判断する、らしい。

もうちょっと技術的な詳細

DKIM/SPF/DMARCを使ったざっくりの仕組みはここまでのとおりだ。が、わかったようなわからんようなという感じなので、もう少し技術的な詳細に踏み込んだほうが、理解に繋がるだろう。時間をかける価値はあるはずだ。というよりかけないとわからん。

DKIMもSPFもDMARCも全体の流れは似ており、いずれも確認のための情報をDNSに保持するのがポイントになる。したがって、運用者はDNSに情報を登録するという作業が必要になるわけだ。ここでは、その作業の「何故」と「何」を理解できることを目指す。

DKIMの仕組み

DKIMは特定のドメインから送られたメールが改竄されていないことを確認する仕組みだと述べた。それは技術的にどのようにして実現されるかを説明する。

これは図示するのがわかりやすいと思う。送信クライアントが送ったメールが、送信サーバを通じて受信サーバにわたり、受信サーバで検証されるまでの流れを下図に示す。

この図を見ながら順番に説明する。

  1. 送信クライアント→送信サーバ
    • ヘッダ情報などを使って送信サーバでハッシュ値が計算される
    • ハッシュ値は秘密鍵で暗号化される
      • ペアとなる公開鍵の情報はDNSのレコードに保持される
  2. 送信サーバ→受信サーバ
    • DNSから公開鍵の情報を取得する
    • 公開鍵でハッシュ値を復号する
    • メールの内容から送信サーバと同様にハッシュ値を計算する
    • 復号したハッシュ値と比較検証して、改竄されていないことを確認する

という流れだ。

実務的には、運用者は送信サーバの公開鍵の情報をDNSのレコードに登録する、という作業が発生する。

SPFの仕組みとその存在意義

SPFも流れはDKIMと同じような感じである。送信サーバはDNSに情報を置いといて受信サーバはそれを見に行く。

SPFにおいては、受信サーバは、送信サーバの主張する送信元(Return-Pathとか)に基づいて、送信元のドメインにあるSPFレコードを参照する。SPFレコードには、IPアドレスなどで、メールを送信できるサーバについての情報が書かれている。

その条件に合致するかを見て、以下のように検証する(By ChatGPT)。

  • Pass: メールがSPFレコードで許可されたサーバから送信されました。
  • Fail (HardFail): メールがSPFレコードで許可されていないサーバから送信されました。
  • SoftFail: メールが許可されていないサーバから送信された可能性があるが、受信側で穏やかに処理されるべきです。
  • Neutral: SPFレコードが特定の評価を行わない場合。
  • None: SPFレコードが見つからない場合。
  • PermError / TempError: SPFレコードの解析に問題があった場合やDNSの問題など。

ここで言いたいことは、その細かな内容ではなく、検証結果として様々なものが用意されているということである。これはメール運用の現実の複雑さを示している。

実際、このような仕組みがあると、送信サーバを移転したり、転送メールなどをしたときに、大いに誤判定が起きることは想像に易い。

それでもSPFが必要な理由として、DKIMだけでは防げないなりすましについて考える。これについて、ChatGPTにケースを考えて貰った。

考えられるシナリオは、攻撃者が正規のドメインを偽装してメールを送信するケースです。攻撃者がexample.comというドメインを偽装しようとしていると仮定します。
攻撃者が自分自身のドメイン(たとえばmalicious.com)を設定し、DKIMを適切に構成します。
攻撃者はFromヘッダを偽り、From: user@example.comと表示させますが、実際にはmalicious.comのサーバからメールを送信します。
メールはmalicious.comのDKIM署名で正しく署名されており、DKIMの検証はパスしますが、このメールはexample.comから送信されたものではありません。
DKIMはメールがmalicious.comから正当に送信され、内容が改ざんされていないことを保証しますが、example.comを偽装していることは検出できません。
SPFの利点
example.comのドメイン所有者は、自分たちのメール送信サーバのIPアドレスのみをSPFレコードで許可しています。
攻撃者がmalicious.comのサーバからexample.comを偽ってメールを送信すると、このメールはexample.comのSPFレコードにリストされているIPアドレスから送信されたものではないため、SPFチェックに失敗します。
受信サーバはSPFチェックが失敗したと判断し、メールがexample.comからの正規の送信ではないと検出します。その結果、このメールをスパムとして扱うか、警告をつけるなどの対応を取ります。

つまり、DKIMだけだと、 malicious.com から正しくメールが送られていますね、なお返信先は example.comです、という無能な状態になってしまうわけだ。まぁそれ自体は普通の運用システムでも考えられることではあるけれど、悪意をもったなりすましとの峻別は機械的には難しい。まぁ実際にはだいたい悪意があるものかどうかはわかりそうな気はするが、その悪意を見抜くプロセスを標準化するための仕組みが、DKIM/SPF/DMARCということであろう。

DMARCの仕組み

DKIMとSPFはそれぞれ独立した機構であり、異なる目的をもっている。DMARCは、DKIMとSPFを組み合わせて、その整合性を評価し、その結果に基づいた処理方法を規定する。つまりポリシーの策定とその実施の仕組みである。また、受信の認証結果についてレポートを送受信する仕組みもある。

送信者は、DMARCの情報もDNSのレコードに保持する。たとえば、自分のドメインで送信されるメールに対して、どのように扱ってほしいか(none(何も行わない)、quarantine(隔離、例えばスパムフォルダへの移動)、reject(拒否、メールを受け取らない)といった具体に)を設定できる。

具体例があるほうが良いと思ったので、ChatGPTにTXTレコードの具体例とその解説をしてもらった。

_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:report@example.com; ruf=mailto:forensic@example.com; sp=reject; adkim=r; aspf=r"

意味は以下(By ChatGPT)

  • v=DMARC1: DMARCのバージョンを示します。これは必須タグで、DMARCのレコードであることを示しています。
  • p=quarantine: DMARCポリシーを指定します。この例ではquarantineを選択しています。これはDMARC検証に失敗したメールを隔離(例えばスパムフォルダに移動)するよう指示します。他のオプションにはnone(何もしない)、reject(メールを拒否)があります。
  • pct=100: ポリシーが適用されるメールの割合を指定します。ここでは100%のメールにポリシーが適用されることを意味します。
  • rua=mailto:report@example.com: 集約されたDMARCレポートを送信するメールアドレスを指定します。これらのレポートには、ドメインがどの程度DMARC検証に適合しているかの統計情報が含まれます。
  • ruf=mailto:forensic@example.com: フォレンジックレポート(詳細な失敗レポート)を送信するメールアドレスを指定します。これは個々の失敗事例に関する詳細情報を提供します。
  • sp=reject: サブドメインに対するポリシーを指定します。この例では、メインドメインとは異なるポリシー(ここではreject)がサブドメインに適用されています。
  • adkim=r; aspf=r: DKIMとSPFのアライメントモードを指定します。rはリラックスモード(Relaxed)で、部分的な一致が許容されます。厳格モード(Strict)を使用する場合はsを指定します。

受信者は送信者側の要求も加味しながら、最終的な決定をする。たとえば送信者側が reject と設定していたとしても、ビジネス上の影響を加味して、受信側で何もしないことは可能だ。

ここまでのことからわかるように、DKIMにせよSPFにせよ、すべてのメールサーバがきちんと対応しないと検証はできない。しかしそれは現実として難しいだろう。したがって、合わないから即棄却というわけには現実としていかないわけだ。

まとめ

正直色々思うことはあるんだが、まぁGmailがそうしろと言うなら勉強するしかあるまい。DNSの設定くらいならいいが、もうとてもとても、メールサーバを自前でやるのは無理だなぁ。

以下に本記事の内容をまとめる。

  • DKIMは送信メールが送信元ドメインから送られた改竄されていないメールであることを確認する仕組み
  • DNSには検証のための公開鍵の情報を登録する
  • SPFは送信元が信頼できることを確認する仕組み
  • DNSには信頼できる送信元を登録する
  • DMARCはDKIM/SPFを組み合わせて、実際にどれくらい厳格に処理するか決めたり、認証結果のレポートを出す仕組み
  • DNSには送信元ドメインのメールの取り扱い方や、レポートの送信先について登録する
  • DKIM/SPF/DMARCで必要な情報はDNSのレコードに登録する

ChatGPT便利。ようやくあちこちの記事が読めるようになった。

以上。

Discussion