開発中のサービスからメール送信したらDKIM=FAILだったので、SPFとDKIMについて理解を深めておきたい
はじめに
開発中のサービスにはユーザーにメール送信する機能があるのですが、以前はDKIM=PASSだったメールがいつの間にかDKIM=FAILになっていました。SPFやDKIMが何なのか、薄ぼんやりとした知識しかなく、一体何が原因でDKIM=FAILになったのが当初は見当もつかなかったので、これを機にもう少しちゃんと理解することにしました。
まずSPFとDKIMを確認してみる
Gmailの場合、メールタイトルの右にある三点リーダーのメニューからメッセージのソースを表示
を選択します。
別画面で元のメッセージ
が表示されるので、SPFとDKIMが確認できます。
SPFはPASSしているけどDKIMがFAIL
スクショのとおり、SPFにはPASSと表示されていますがDKIMはFAILと表示されています。
SPF欄のIPに見覚えはありませんが、DKIM欄のドメインは確かに開発中のサービスで設定しているドメインです。
SPFって何
SendGridのブログに以下のような説明がありました。
SPFとは、メールの送信ドメイン認証のひとつで、メールが正規のサーバ(=そのドメインからの送信が許可されているサーバ)から送信されているのかどうかを判断するのに有効です。SPFがあれば、ISPはあなたのドメインを利用した悪意のあるメールを判断できます。
引用:送信ドメインを認証するためのSPFレコードに詳しくなろう
SPFの認証フローについてはSendGridからメール送信する場合のSPFとDKIMの認証の仕組み – 前編 に分かりやすい図がありました。
Domain Authenticationを設定した場合、メールのヘッダFromは kke.co.jp 、エンベロープFromは kke.co.jp のサブドメイン(例:em.kke.co.jp)になります。このサブドメインは、Domain Authentication設定を作成する際にSendGridが自動的に付与します(※ユーザが任意のサブドメインを指定することも可能)。
受信側メールサーバがメールを受け取ると、エンベロープFromのドメイン(em.kke.co.jp)を管理するDNSサーバに認証情報を問い合わせます(図3の③)。このDNSサーバにはDomain Authentication用のCNAMEレコード(エイリアス/別名)を登録しており、em.kke.co.jp の認証情報の問い合わせがあると、SendGridのDNSサーバを参照するようになっています(図3の④)。そのため、受信側メールサーバから見ると、em.kke.co.jp のDNSサーバが認証情報を返したように見えますが、実際にはSendGridのDNSサーバに登録されたレコードを参照していることになります(図2の⑤)。受信側メールサーバは認証情報をチェックします(図2の⑥)。
今回のメールはSendGridから送信しているので、この図の流れでメールが送信されているはずです。
SPFのチェック対象はエンベロープFromのドメインとのことなので、今回受信したメールのエンベロープFromドメインを確認してみます。
エンベロープFromはメールヘッダの Return-Path
のことなので、「元のメッセージ」画面でReturn-Path
を探したところ <piyo+caf_=hogehoge=gmail.com@kaisyanomeado.com>
とありました。
本当はこのエンベロープFromドメインがおかしいのですが、この時点では気づかずスルーしました。
DKIMって何
SendGridのブログを引用します。
DKIM(Domain Keys Identified Mail)は、CiscoとYahooが提唱した、送信者がメッセージに「署名」を付与できる暗号技術です。メールの受信者は、そのドメインを管理する送信者が責任を持って送信したかをチェックできます。メッセージがDKIM認証されていない場合、GmailやMicrosoftなどのメールプロバイダはメッセージをブロックして受信箱に届けないことがあります。
引用:DKIMとは?
DKIMの認証フローはSPFの認証フローと似ているようです。
ここまでSPFについて説明してきましたが、基本的な認証フローはDKIMも同じです。DKIMの認証に使う秘密鍵と公開鍵はSendGridが管理し、DKIMレコードを参照するためのCNAMEレコードを独自ドメインを管理するDNSサーバに登録します。概要は下図の通りです。
引用: SendGridからメール送信する場合のSPFとDKIMの認証の仕組み – 前編
DKIMがFAILだった原因はDNSサーバへの設定漏れ
ここでSendGridの設定画面(Domain Authentication)を確認してみます。
StatusがすべてFailed
になっています。DKIMの認証フローの図でいうと、SendGridのDNSサーバ
と差出人のドメインを管理するDNSサーバ
の矢印がつながっていないと考えられます。
設定画面にあるCNAMEやTXTを我々のDNSサーバに登録しないといけないのですが、確認したところ全て抜け落ちてました。以前はDKIMがPASSになっていたので、何かのタイミングで誤って削除してしまったと考えられます。
DNSサーバに必要な設定を行ったあと、設定画面でverify
を実行すると無事にStatusがVerified
に変わりました!
SPFがPASSしているのはおかしいのでは?と気づく
DNSサーバに諸々の設定が抜けていたので、DKIMの認証に失敗していたということは理解しました。今回設定が抜けていたのはDKIMだけではなくSPFもなので、SPFもFAILになるはずがPASSになっている??
あらためて先ほど確認したエンベロープFromドメインを確認すると、@kaisyanomeado.com
となっています。
実はこれ、開発中のサービスで設定しているドメインではなく、会社のメールアドレスのドメインでした。会社のメールアドレス宛に送信したメールをgmailアドレス宛てに転送しているのですが、転送されたメールに対してSPFやDKIMを確認していました。
つまりSPFの認証は会社のメールアドレスのドメインを管理しているDNSサーバに対して行われていたため、SPF=PASSとなっていた可能性があります。
ということで、開発中のサービスから会社のメールアドレス宛に送信されたメールのヘッダを改めて確認してみると、SPF: TEMPERROR
とあります。やはりDKIMと同様にSPFも認証に失敗していました。
Return-Pathは bounces+36613697-3c9a-hoge=kaisyanomeado.com@em801.tadashiidomain
となっていました。確かに開発中のサービスで設定しているドメインです。
SPFやDKIMの認証関連の情報はメールヘッダでも確認できる
送信ドメイン認証が正しく行われているか、メールヘッダのAuthentication-Results
で確認できるようです。
Authentication-Results: mx.google.com;
dkim=temperror (dns failure for signature) header.i=xxxxxx header.s=s1 header.b=FHo9QWh3;
spf=temperror (google.com: error in processing during lookup of xxxxxxxx: DNS error) smtp.mailfrom="xxxxxxx"
SPFはDNS error
、DKIMはdns failure for signature
と記録されています。SPFやDKIMがFAILだった場合、エラー原因を調べるのにまずはここをチェックするのが良さそうです。
参考: メールヘッダ入門
再度メールを送信しSPFとDKIMを確認してみる
SendGridの設定画面でStatusがVerifiedになったのを確認したあとメールを送信した結果、無事にSPFとDKIMがPASSになっていました。
ついでに、DKIMがFAILのときには表示されていなかったDMARCがPASSになっています。おそらくこれも、DNSサーバに設定が追加されたからだと思います。
さいごに
今回改めてエンベロープFromやヘッダーFromについて学び、なりすましメールってこういうことかと理解することができました。
ついでに、メールの転送に潜む罠(?)についても気づきを得ました。メール送信の動作確認時は転送されたメールではなく、サービスから送信されたメールで確認を行うべきでした。
転送メールはSPF:PASSになってしまう場合があるようなので、怪しそうなメールを受信したらSPFとDKIMをチェックしてみるようにします。
Discussion