DMARCの受信結果を読む

# 初めに
2024年2月以降のGoogleの迷惑メール対策強化でDMARCの導入も進んでいます。
送信側の対応についての記事は良く見ますが、受信側についての情報が少ないのでまとめてみました。
# 前提
メールサーバーとして postfix を使っており openDMARC(Ver1.4.1) を当初導入しました。
その後、Rspamd(version 3.8.4)に変更してます。
その経緯についても説明します。
そもそも「**DMARCとは何か**」ということや、これらのインストールや設定は他の解説しているサイトを参照して下さい。
# 概要
送信ドメイン認証(SPF/DKIM/DMARC)の送信側は一生懸命対応しているようですが、それを見る受信側の対応については関心が薄いようです。
実際に受信したメールの解析を通じてDMARCの特性を理解していきたいと思います。
GmailやYahoo!MailのようなWEBメールでは参照が可能ですが、IMAPやPOPを使うメールソフト側の対応が出来ていません。
メールを読むユーザーがどのようにメリットを享受できるかが今後の課題です。
# 解析してみよう
ここではopenDKIM/openDMARCをpostfixに連携したもので見ています。
メールプロバイダの多くはDMARCに対応しているはずなので環境の無い方はそれらでも同様な情報が見られるはずです。
Gmailから受信した結果をメールのエンベロープで確認した例です。

![dmarcサンプル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3834038/b87fc9d1-38d4-9cd5-8949-f132136f9471.png)

postfixで受信したメールはopenDKIM/openDMARCに連携され、検証された結果がヘッダーに追加されます。
「**spf=pass**」「**dkim=pass**」「**dmarc=pass**」という情報が確認でき、それぞれに対応していることが解ります。
SPF/DKIM/DMARCで送信側から送られてきているのはDKIMの署名(Signature)だけです。
それ以外は対象ドメインのDNSの設定だけで行われている点に注目して下さい。

# openDMARCは必要か？
上記の解析結果から言えるのは、**送信側の対応だけならopenDMARCは不要**ということです。
テスト方法は簡単でpostfixのopenDMARCへの連携(milter)を一時的に解除してあげれば良いだけです。
これで、Gmailに送信してみます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3834038/80592693-6cf3-cdb2-a72f-3d3f75fc1de6.png" width=75%" />


ほら、ちゃんとDMARCは**pass**してます。
DMARCの送信側は自身のDNSに登録し受信側の対応を指示するものなんですね。
DMARCの真価は受信側がどう情報を利用するかにあるようです。
# さらなる解析
手身近なQiitaの例です
```
Authentication-Results: openDMARC; dmarc=fail (p=none dis=none) header.from=qiita.com
    Authentication-Results: openDMARC; spf=pass smtp.mailfrom=us-west-2.amazonses.com
DKIM-Filter: OpenDKIM Filter v2.11.0 ****.com CBF37180009
Authentication-Results: ****.com;
	dkim=pass (1024-bit key) header.d=qiita.com header.i=@qiita.com header.b="SnWcl7EQ";
	dkim=pass (1024-bit key) header.d=amazonses.com header.i=@amazonses.com header.b="TC/FQ5rd"
```
あれ！？<font color="red"><b>dmarc=fail</b></font> になっています。
<font color="blue"><b>spf=pass、dkim=pass</b></font> です。
**header.from ≠ smtp.mailfrom**( qiita.com ≠ us-west-2.amazonses.com ) 
となっているからですかねえ？
いやいや、そうではないでしょう。
RFC7489によれば、
>「複数のDKIM署名の１つでもイン・アライメントであると検証された場合には、DMARCの結果は「成功」とみなす。」

とあります。
「アラインメント」(調整)とは何か？
SPFとDKIMのそれぞれにあり、DKIMだけについて言えば **header.d=** のドメインと **header.from=** のドメインを比較し正当性を検証します。

:::note info
アラインメントには**厳密**と**緩和**の２通りあり緩和ではサブドメインも正しいと判断します
:::
上記の例では１つの署名は「qiita.com」で一致してます。
また、DMARCではSPF/DKIMどちらかがpassしてアラインメントも合格していれば**pass**と判断します。
つまり、openDMARCの判定が間違いです。
# アラインメントを理解する
一番特徴的なのが、DMARCを**pass**するには、SPF/DKIMのどちらか一方だけでも良いという点です。
試しに、SPFだけにしてGmailに送信してみましょう。(openDKIMのmilterを外す)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3834038/a6281217-cb96-ed60-b678-31c67d2f93e9.png" width="75%"/>

ほら、SPFだけでもちゃんとDMARCは**pass**したでしょう。
もちろんこの場合、DMARCのDNS設定やFromと送信元のドメイン名が一致している場合です。
同様にDKIMだけでも良いです。
DKIMの場合は、送信ドメイン名が違っていても許される点が大きいです。
(qiitaの例がまさにそうです)

# openDMARC の問題点
さて、良くありがちなのが header.from に素直に親ドメイン(つまり会社のドメイン)を設定していれば良いですが、往々にしてサブドメインにしている会社を見かけます。
例えば、**mail**.yahoo.co.jp のように。
もちろん使っても問題は無いのですが、openDMARC では
```
Authentication-Results: openDMARC; dmarc=none (p=none dis=none) header.from=emails.****.jp
Authentication-Results: openDMARC; spf=pass smtp.mailfrom=em7420.emails.****.jp
```
のように **dmarc=none** を返す場合があります。
**none** という値は定義されておらず **pass** か **fail** でなければなりません。
これはどう解釈すべきなのでしょう？
DMARCのポリシーは特別にサブドメインの指定が無ければ親ドメインの設定が継承されます。
どうも、openDMARC の GitHub の過去の issue を見る限り、サブドメインへの継承が出来ておらず、結構な修正が必要なようで先送りされているようです。
実際に開発も３年前からほとんど進んでいないようでこの先も期待が持てそうもない状況です。
送信側についてはopenDMARCを使わなくても問題無い事は書きましたが、このように受信側で正しい判定をしてくれないのでは使う意味がありません。
# Rspamdに変える
今も開発が継続しているという観点からRspamdを代替に検討してみました。
Rspamdは高機能なスパムフィルタとして有名で、解説するサイトもその観点で書かれている場合がほとんどです。
RsmapdはSPF/DKIM/DMARC/ARCの機能も持っておりここではDMARCに必要な機能だけ利用することにしました。
スパムフィルタやWEBのUIによる設定や分析機能がありますが設定が大変です。
今回利用する予定が無いので最小限の設定を行いました。
# Rspamd のDMARCだけを利用する為の設定
openDKIM/openDMARCの代替だけに必要な設定に絞って説明します。
インストール方法等の詳しい手順は他のサイトを参照して下さい。
要点は、
* **Redisのインストールは不要**
* スパムフィルタの設定は不要
* WebUIの設定は不要
* **Milterの設定が必要**

Redisはデータベースシステムです。

:::note warn
DMARCのレポートを送るならRedisも必要になります。
:::

また管理や分析の為のWEBインターフェースも必要ありません。
初期設定の際、最初にRedisの使用を聞いてくるので"n"で答えます。
```
# rspamadm configwizard
   ：
Do you wish to set Redis servers?[Y/n]:n
```
SPFはデフォルトで有効なので設定不要です。
DKIMはキーを dkim_keygen で作成する事が出来ますが、openDKIMで作ったキーをそのまま使えます。

:::note warn
Rspamdの設定ポリシーは少し変わっていて、設定ファイル(*.conf)を直接書き換えず差分を追加（または上書き）します。
多くは、/etc/rspamd/local.d/ に追加設定ファイルを置きます。
:::
openDKIMで作ったキー(秘密鍵)を利用する場合は、ファイルをコピーし
/etc/rspamd/local.d/dkim_signing.conf を開き修正します。
```
allow_hdrfrom_mismatch_sign_networks = true;
allow_username_mismatch = true;
domain {
    ドメイン名 {
        selector = "セレクタ名";
        path = "/var/lib/rspamd/dkim/秘密鍵のファイル名";
    }
}
sign_authenticated = true;
use_esld = false;
use_domain = "header";
allow_hdrfrom_mismatch = true;
```
こうすることで、DNSに設定したレコード(公開鍵)をそのまま使えます。

次に、postfixと連携する為に main.cf に milter を設定します。
考え方は openDKIM/openDMARCと同じです。
私の場合は簡単にコメントで切り替えできるようにしています。
```
# smtpd_milters = inet:127.0.0.1:8891, inet:127.0.0.1:8893
smtpd_milters = inet:127.0.0.1:11332
```
以上で、送信側はうまくSPF/DKIM/DMARCに対応しますが、このままでは受信側のメールヘッダーには何も載りません。
/etc/rspamd/local.d/milter_headers.conf
を作成して、必要とするヘッダー情報を追加します。
詳細はRspamdの[公式ドキュメント](https://rspamd.com/doc/modules/milter_headers.html)を参照して下さい。
デフォルトで良ければ１行だけ書きます。
```
use = ["authentication-results"];
```
これで追加されるようになります。
再び Qiita からのメールを受信して見てみましょう。
```
Authentication-Results: ****.com;
	dkim=pass header.d=qiita.com header.s=ykosyy7esjatwnwqjaghjxf3c5e6b7ej header.b=OigRdk5H;
	dkim=pass header.d=amazonses.com header.s=7v7vs6w47njt4pimodk5mmttbegzsi6n header.b=CCJyHnda;
	spf=pass (****.com: domain of 01010190af7b90a9-87514781-d595-483b-a7a5-bf65a1af779b-000000@us-west-2.amazonses.com designates 54.240.27.23 as permitted sender) smtp.mailfrom=01010190af7b90a9-87514781-d595-483b-a7a5-bf65a1af779b-000000@us-west-2.amazonses.com;
	dmarc=pass (policy=none) header.from=qiita.com
``` 
ちゃんとdmarc=passになっている事が判ります。
# Thunderbird でのDMARC利用例
いちいちメールの詳細（エンベロープ）を確認するのは面倒です。
メールソフトで簡単にDMARCの結果を見る例として、Thunderbird にフィルタを作ってみました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3834038/cbb4966f-7d56-dd26-b886-4526cef0f0bd.png" width="75%"/>

直接迷惑フォルダに移動しても良いですが、今のところはタグを付ける位が良いのではと思います。
SPF/DKIMの判定を加えても良いですが**成りすまし検知**という意味では、あくまでDMARCの判定が頼りです。
# 最後に
DMARC をいくら送信側が対応してもメールを受ける側が対応し、利用者に正しく理解してもらわないと結局宝の持ち腐れです。
その為にはメールソフト（メーラー）もデフォルトで対応して欲しいところです。
それまでは自分でフィルタを作る等して活用しましょう。
**DMARC**の次に**BIMI**(企業ロゴの表示)があるように言う人がいますが、利用者側の視点に立つと私はちょっと方向性が違うんじゃないの？と思ってしまいます。