SPF、DKIM、DMARCは実際に何をしているのか
3つは、1本の鎖をつなぐ3つの輪だと考えてください。SPFは、ドメインのメール送信を許可されたサーバーを示します。DKIMは暗号署名を付け、メッセージが途中で改変されていないことを受信側が確かめられるようにします。DMARCは、その両方を読み手が実際に目にする「From:」行のドメインに結びつけ、確認に失敗したときの扱いをポリシーとして公開します。平たく言えば、SPFは封筒を、DKIMは中身を確認し、DMARCはそのどちらかが受信者の読む名前と一致しているかを確認します。
SPF:ドメインのメールを送ってよいサーバー
SPFレコードは、v=spf1で始まる1つのDNS TXTレコードです。ドメインのメール送信を許可されたホストとincludeを列挙し、最後をallメカニズムで締めます。つまずきやすいルールが2つあります。1つ目は、1つのドメインが公開できるv=spf1レコードは1つだけということです。2つ目のレコードを置くと評価結果はpermerrorになり、認証は事実上失敗します(RFC 7208の4.5節)。2つ目は、評価中に実行できるDNSルックアップを伴うメカニズム(include、a、mx、ptr、exists、およびredirect修飾子)は最大10回までということです。10回を超えると、やはりpermerrorになります(4.6.4節)。最後の修飾子がポリシーです。~allはsoftfail(受け入れるが印を付ける)、-allはhardfail(リストにない送信元を拒否する)で、+allはすべてを通過させてしまうため、決して公開してはいけません。構造上の限界も1つ知っておいてください。SPFが認証するのは表示上のFromではなく、見えないReturn-Pathのドメインです。また、転送先のサーバーのIPはレコードに含まれていないため、転送されると機能しなくなります。DMARCがSPFだけに頼らないのは、まさにこのためです。
DKIM:誰にもこっそり書き換えられない署名
DKIMは、送信システムが保持する秘密鍵で送信メッセージごとに署名し、対応する公開鍵をDNSで公開します。署名は選んだヘッダーと本文を対象にするため、転送中に何かが変更されると、署名は検証を通らなくなります。受信側は、セレクターを使って鍵を見つけます。DKIM-Signatureヘッダーにはs=(セレクター)とd=(自社のドメイン)が含まれ、検証側はselector._domainkey.yourdomainに公開鍵を問い合わせます(RFC 6376の3.6.2.1節)。セレクターを使えば複数の鍵を同時に運用でき、鍵のローテーションもすっきり行えます。新しいセレクターを公開し、署名をそちらに切り替え、古いセレクターを廃止します(鍵の値を空にすると失効の印になります)。鍵長については、RFC 6376は長期間使う鍵に1024ビット以上のRSA鍵を求め、検証側には2048ビットまでの鍵への対応を求めています。現在の妥当な標準は2048ビットで、定期的に鍵をローテーションすれば、万一漏れたときの被害を抑えられます。
DMARC:全体をまとめるポリシー
DMARCは、SPFとDKIMを受信者が読むドメインにとって意味のあるものにするレコードです。中心となる考え方はアライメントです。メッセージがDMARCを通過するのは、SPFかDKIMがpassとなり、かつそのpassが表示上のFromドメインと一致する識別子に基づく場合だけです(RFC 7489の4.2節)。生のSPFは通過してもDMARCで失敗することがあるのは、このためです。ESPが独自のReturn-Pathドメインで送信すると、SPFはESPのドメインとして通過しますが、そのドメインは自社のFromドメインと一致しないため、DMARCのSPF側は失敗します。アライメントには2つのモードがあります。relaxedは組織ドメインが一致すれば認め(mail.yourco.comはyourco.comと一致)、strictは完全な一致を求めます。アライメントの取れたメカニズムはどちらか1つで足りるため、転送されたメッセージのようにSPFでは通らないメールは、たいていDKIMのアライメントが通します。レコード自体は、v=DMARC1、p=none、rua=mailto:reports@yourco.comといったタグをセミコロン区切りで並べたものです。pタグはポリシー(none、quarantine、reject)を決め、ruaは集計レポートの送信先を指定し、spはサブドメイン用の別ポリシーを設定します。spを省略すると、pの値がそのまま使われます。
2024年に必須になった理由
かつて認証は、任意で行う衛生管理でした。2024年2月に、それが関門に変わりました。GmailとYahooは現在、一括送信者(Googleの基準では、Gmail宛てに1日5,000通を超えて送る送信者)に対し、SPFとDKIMによる認証と、DMARCレコードの公開を求めています。DMARCはp=noneから始めて構いません。マーケティングメールや購読型のメールには、ワンクリック配信停止も必要です。List-Unsubscribeヘッダー(RFC 2369)に加えて、RFC 8058のワンクリックの仕組みであるList-Unsubscribe-Post: List-Unsubscribe=One-Clickを付け、受信者のメールクライアントが1回のHTTPS POSTで配信停止できるようにします。GmailとYahooのルールの全体は、到達率の概要ガイドで確認できます。注意点が2つあります。2024年以降、ルールの適用はさらに厳しくなっているため、1日5,000通未満でもルールに沿った設定にしておいてください。また、迷惑メール報告を低く抑えることは、認証と並ぶ要件であり、あれば望ましいという程度のものではありません。
認証を気づかないうちに壊すよくある間違い
- SPFレコードへの+allの公開。インターネット全体に自社を名乗った送信を許可することになり、目的とは正反対です。
- 同じドメインに2つ以上あるv=spf1レコード。permerrorが返り、SPFが無効になります。
- ベンダーのincludeを追加するうちに超えてしまう、DNSルックアップ10回の上限。これもpermerrorになります。
- 短すぎる、または一度もローテーションしていないDKIMの鍵。漏えいしたり総当たりで破られたりした鍵が、いつまでも署名を続けます。
- 集計レポートを1通も読まないままの、いきなりのp=reject。送っていることを忘れていた正当なメールまで止まります。
- サブドメイン用のsp=の設定漏れ。緩いサブドメインポリシーのせいで、marketing.yourco.comがなりすましに対して無防備になります。
- SPFとDKIMのアライメントに一度も組み込んでいないサードパーティの送信元(ESP、請求書発行ツール、ヘルプデスクなど)。そのメールはDMARCで失敗します。
認証はスタックのどこに位置するか
認証は、ほかのすべての土台です。セルフホストなら、DNSと署名鍵を完全に自社で所有でき、送信者としての身元を自分で管理するうえで最も確かな形になります。カスタマーエンゲージメントプラットフォームは、送信ドメインごとの認証とアライメントの状態を隠さずに表示し、どの送信元が通過しているかをひと目で確認できるようにすべきです。トランザクションメールとマーケティングメールは別々のストリームで、できれば別々のサブドメインから送り、マーケティングで迷惑メール報告が急増しても、パスワードリセットのメールが届かなくなることがないようにします。作業の順序も大切です。認証とアライメントが先で、ドメインのウォームアップはその後です。認証していないドメインでウォームアップしても、メールボックスプロバイダーに不信感を早く覚えさせるだけです。