Uncategorized

Google WorkspaceやZendeskから送信されるメールが迷惑メールとならないようにする: SPF、DKIM、DMARCの設定の覚書

神奈川県の入試出願システムからのメールがGmailで弾かれてしまうという問題が最近話題になりました。
高校入試の出願システム、Gmailにメール届かず……神奈川県、受験生に「@gmail.com以外のアドレス使って」

メールを配信する仕組みは当初性善説に基づいて設計されたため、送信元や時刻を偽ったり、途中で文面が改善されていたりしても検証する仕組みがありませんでした。
現在はSPF、DKIM、DMARCといった技術で、送信元の詐称や改竄を防ぐことが出来るようになっており、これらの設定をしていないと迷惑メールとして弾かれたり、受信が拒否されたりといったことが起こりやすくなります。
中でもSPFは最低限設定しておかないと簡単に迷惑メールに振り分けられます。

SPF、DKIM、DMARCについて詳しくは世の中にいくらでも解説がありますが、自分の理解のために簡単にまとめました。

SPF

第三者が勝手なサーバからメールを配信したものを検出できるようにする仕組み。

紫外線をどれくらい防げるかの度合い、”Sun Protection Factor”、とは別で”Sender Policy Framework”の略。特定のドメインのメールがどのサーバから配信されるのかをDNSで事前に設定しておく。
ドメインで事前に設定されていないサーバから送られてくるメールは詐欺だろうと検出できる。
設定はdigコマンドでTXTレコードを引くと確認できる。

% dig samuraism.com TXT
<略>
samuraism.com.          300     IN      TXT     "v=spf1 include:_spf.google.com include:mail.zendesk.com ~all"

この例では具体的な送信サーバはGoogleやZendeskが設定しているものを引用するようになっている。

DKIM

メールの改竄を検出する仕組み。

送信元でメール内容を秘密鍵を使って署名を生成し、ヘッダ “Dkim-Signature”に記し、受信者はDNSから公開鍵を取得して署名を検出することで改竄を検出できる。

DKIMの鍵の作り方、設定方法

秘密鍵、公開鍵は以下のようなopensslコマンドで生成できる。

% openssl genrsa -out private.pem 2048
% openssl rsa -in private.pem -out public.pem -pubout -outform PEM

公開鍵(public.pem)—–BEGIN PUBLIC KEY—– / —–END PUBLIC KEY—–を除く部分を[セレクタ]._domainkey.[ドメイン]というTXTレコードに設定する。
DNSのレコードは255文字を超える場合は以下のように、255文字以内に区切ってダブルクオートで囲い、スペースで区切った形で設定する必要がある。
“255文字までの文字列1” “255文字までの文字列2”

設定した公開鍵は、例えば鍵のセレクタがgmaildkim、ドメインがsamuraism.comであれば以下のdigコマンドで確認できる。

dig gmaildkim._domainkey.samuraism.com TXT

SendGridにおけるDKIMの設定方法

覚書をまとめるまでも無くSendGrid/構造計画研究所のページを見るのが一番!
SendGrid ユーザマニュアル > Domain Authentication(SPF/DKIM設定)の設定方法

DNSレコードさえ正しく指定しておけば、SendGridのSMTPサーバが署名を行ってくれるので、アプリケーションでDkim-Signatureヘッダを指定する必要はありません。

メール回りの疑問は構造計画研究所のサイトを見れば間違いなく解決します。

Google WorkspaceにおけるDKIMの鍵の作り方、設定方法

Google Workspaceの管理画面の[アプリ>Gmail>メールの認証]から設定する。

「新しいレコードを生成」を押して表示される「新しいレコードを生成」ダイアログで、DKIMの鍵長(現在は2048ビットが推奨されるらしい)を選び、任意のプレフィックス(セレクタ)を指定して生成する。

生成された鍵をDNSで指定(255文字を超えているのでダブルクオートやスペースで区切る必要がある)して、「認証を開始」を押すと有効になる。
Gmailから送るメールも、アプリケーションからGoogleのSMTPサーバ smtp.gmail.com を使って送る場合も自動的に署名(Dkim-Signature)が付加されるようになります。
つまりアプリケーションでDkim-Signatureヘッダを生成/設定する必要はありません。

ZendeskにおけるDKIMの設定方法

zendesk1._domainkey.[ドメイン名] → zendesk1._domainkey.zendesk.com
zendesk2._domainkey.[ドメイン名] → zendesk2._domainkey.zendesk.com
というCNAMEレコードを設定する。
管理画面の[Talkとメール>メールアドレス>DKIMのカスタムドメイン>有効にする]にチェックを入れる。
Zendesk – DKIMを使用したメールのデジタル署名

DKIMの設定確認方法

DNSの設定確認

DKIM Record Checkerでドメインとセレクタ名を入れてチェックできる。

DMARCとは

DMARCはメールの認証に失敗した場合にどのように処理するか(none:なにもしない、quarantine:隔離する≒迷惑メールフォルダに振り分けられる、reject:受信を拒否する)を指定したり、認証に失敗した集計レポートを送るメールアドレスの送信先を指定したりできる。
DMARCはDNSに _dmarc.[ドメイン名] というTXTレコードで設定する。
digコマンドではこう確認する

% dig txt _dmarc.samuraism.com              

; <<>> DiG 9.10.6 <<>> txt _dmarc.samuraism.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32891
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;_dmarc.samuraism.com.          IN      TXT

;; ANSWER SECTION:
_dmarc.samuraism.com.   3600    IN      TXT     "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@samuraism.com; pct=20"

;; Query time: 78 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Thu Jan 18 18:08:08 JST 2024
;; MSG SIZE  rcvd: 132

この場合は p= で、認証に失敗した場合は隔離、rua= で集計レポートはdmarc-reports@samuraism.comに送信、pct= でDMARCによる認証は全体の20%に適用、という設定になっている。
pctは1〜100(%)を指定でき、何も指定しない場合はデフォルトの100が適用される。設定に問題があり、メールが拒絶されまくってしまうような事態を防ぎたければ低い値を設定し、最終的に100か、指定なしにする。

DMARCの確認

DMARC Record Checkerで確認できる。

これはあくまでDNSレコードの設定内容を確認するだけで、SPFやDKIMが適用されてメールが正しく認証されていることを確認しているわけではない。

署名の確認

メールを外部に送信し、Authentication-Resultsヘッダを見る。
SPF、DKIM、DMARC、それぞれ検証に成功していれば以下のように spf=pass、dkim=pass、dmarc=passと書かれている。

Authentication-Results: bimi.icloud.com; bimi=skipped reason="insufficient dmarc"
Authentication-Results: arc.icloud.com; arc=none
Authentication-Results: dmarc.icloud.com; dmarc=pass header.from=samuraism.com
Authentication-Results: dkim-verifier.icloud.com; dkim=pass (2048-bit key) header.d=samuraism.com header.i=@samuraism.com header.b=Q9wPckpv
Authentication-Results: spf.icloud.com; spf=pass (spf.icloud.com: domain of sales@samuraism.com designates 209.85.210.45 as permitted sender) smtp.mailfrom=sales@samuraism.com

また、Dkim-Signatureヘッダの d= にfromアドレスのドメインが記載されていることも確認。つまりFrom:sales@samuraism.comであれば d=samuraism.com となっているべき。

Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samuraism.com; s=gmaildkim;

d=のドメインがGoogleとかZendeskとかのドメインになっている場合はfromアドレスのドメインの保有者が作成したメールとは判断できない「第三者認証」と呼ばれる物になる。改竄されていないことは検証できるが、ドメインを所有している人からのメールだとは検証できない状態。

総合的な確認

mail testerでは、送られたメールを検証して10点満点でスコアをつけてくれます。
トップページを開くと、先方が検証に使うための専用のメールアドレスを用意してくれているので、メールを送ります。
メール文面もスコアリングの対象なので、(個人情報をマスクなどした上で)実際にシステムから送られる文面を使いましょう。

メールを送ったら”Then check your score”を押すと、スコアをつけてくれます。DMARCはスコアの対象外ですが、SPFとDKIMIについては見てくれているようです。
何が問題でスコアが下がっているかも表示されます。改善を施した上で、同じメールアドレスに再送したら、再度スコアをつけて貰うことも出来ます。

BIMI

先のAuthentication-Resultsヘッダに”insufficient dmarc”という文字列があってドキッとさせますが、これはBrand Indicators for Message Identificationという、メール送信者のブランドロゴを表示させる、いわばメール版のfaviconみたいな仕組みの仕様を満たしていないよ、という意味です。
例えば楽天はグループ全体で対応させているようで、以下のようにメーラで確認ができます。分かりやすくていいですね!

default._bimiというDNSレコードで設定状況を確認できます:

 % dig default._bimi.rakuten.com TXT

; <<>> DiG 9.10.6 <<>> default._bimi.rakuten.com TXT
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31023
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;default._bimi.rakuten.com.	IN	TXT

;; ANSWER SECTION:
default._bimi.rakuten.com. 21600 IN	TXT	"v=BIMI1; l=https://r.r10s.jp/com/bimi/r_crimsonred/r_crimsonred.svg;a=https://r.r10s.jp/com/bimi/r_crimsonred/r_crimsonred_177085657.pem;"

;; Query time: 39 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Fri Jan 19 13:34:12 JST 2024
;; MSG SIZE  rcvd: 204

Gmailでも表示させるには、VMCという仕組みを利用するために年間数十万の費用をかけて認証してもらう必要があるようです。
自分の会社で送るのはほぼトランザクションメールで、受信者は読む動機があるので今のところはいいかな、と思っています。
マーケティングメールを頻繁に送る組織ではお金をかけてBIMIに対応させるのもいいかもしれません。