メールドメイン認証関係で検証した結果

# はじめに
！！書いてる途中です！！

職場(某大学)でメールドメイン認証関係で色々調査した結果のメモ書きです。徒然なるままに記載してますので、文章に統一感はありません。

この調査を始めたのは、携帯のAUキャリアメール(ezweb.ne.jp)から届いたメールが職場MLサーバを介して、クラウドのoffice365に届かないという話からでした。

図示すると以下になります。

>送信者ezweb.ne.jp -> 職場MLサーバ -> クラウドoffic365

他のメールアドレスは問題ないため、調査すると、メールのドメイン認証の署名であるDKIMが壊れていました。

多くのMLサーバがSubjectに連番を追加しフッタに文字列を追加します。この作業を行うとDKIMが壊れます。

DKIMが壊れているメールをどのように扱うかはDMARCという設定で行います。

ezweb.ne.jpのDMARCはp=rejectという設定になっています。受信拒否しなさいという指示になります。そのため、職場MLサーバから送られてきたメールをoffice365が受信拒否をしていました。

>送信者ezweb.ne.jp -> 職場MLサーバ -> 受信拒否:クラウドoffic365

これを回避するにはどうしたらいいのだろうと思い、いろいろ調査を始めました。

## 調査につかったメールアドレスや環境

### 受信確認用メールアドレス
受信の確認に用いた無料アドレスは
- gmail.com
  > v=DMARC1; p=none; sp=quarantine;
- outlook.jp
  > v=DMARC1; p=none;
- icloud.com
  > v=DMARC1; p=quarantine; sp=quarantine
 
の3種類および、

- 職場アドレス(example.ac.jp): 職場内に設置されているLinux+postfixで構築した職場ドメインアドレス。rspamdでDKIM署名を行っています。
 > v=DMARC1; p=none; sp=none
 
- office365(example.jp): 某大学で有償契約しているMicrosoftのクラウドサービスのoffice365。メールアドレスは大学ドメインからacを抜いたアドレスになってます。

 DMARCは未定義です。DKIM署名はmicrosoftによる第三者署名になります。office365の挙動は職場で契約しているアドレスの挙動になりますので、他と異なる可能性あります。加えて、職場のIPアドレスはホワイトリストに登録されているため、他のIPアドレスからの受信に比べて判断が甘くなっている可能性あります。office365の契約者の一例程度にお考えください。
  
受信に用いるアドレスは上記の５個になります。

### 送信に用いるメールアドレス
送信に用いてるアドレスは、上記受信用メールアドレスに加えて、

- ezweb.ne.jp
　AUのキャリアメール。前述のようにDMARCはp=reject になっています。
   > v=DMARC1; p=reject;

### MLサーバの構成(ml.example.ac.jp)
MLサーバは以下の構成です。

- 職場MLサーバ: AlmaLinux8, postfix, rspamd-3.9.1-1.el8.x86_64導入。
  ホスト名: ml.example.ac.jp
  MLサーバソフトとしてmailman2.1.30(dnf install), mailman3(手動install.後述), fml(4系.後述)を入れてます。
  > v=DMARC1; p=quarantine; sp=none;

## メール転送についての補足(本稿のみでの定義)
転送について用語の補足。本稿のみでの定義です。一般的な定義ではありません。

- alias転送: MLサーバにて、/etc/aliaseにアドレスを直接記載して転送。原則差出人のメールにDKIM署名があっても署名は破壊されません。(/etc/aliassはPostfixやsendmail等のMTAが参照する転送設定ファイル)

- forward転送: メールサーバ・MLサーバにて ~/.forwardにアドレスを直接記載して転送。もしくは各メールサービスの個々のユーザのメール転送機能を用いて転送。原則差出人のメールにDKIM署名があっても署名は破壊されません。

- ML転送: MLサーバにてML専用ソフトを用いて転送します。
Subjectに連番を加筆や、signatureにML名を記載しますので差出人のメールにDKIM署名があった場合、署名は破壊されます。

　他の文献ではML転送にalias転送を含む場合があります。ご留意ください。

## 以上のような環境で
本稿は職場MLサーバでDKIM再署名とかARC署名追加とかいろいろやった結果を書いたものです。

# 1.Googleの MLサーバ(googlegroups)のDKIMの挙動
(2024/9/26頃の挙動)
(2024/9/26改定: 調査結果に間違いがありましたので、改定しています。X-GoogleDKIM-Signatureの説明が間違えてました。)

DKIMの調査に先立ち他のMLサーバの環境を調べてみました。

GoogleのMLサーバGoogleGroupsで仮のML(example-AT-googlegroups.com)を作成し、メールを送った時の挙動です。

結果として、googlegroupsはsubject改変やsignature追加は行ってないようですが、以下の挙動になっていました。

MLに投函されていたメールに付与されていたDKIM作成者署名は削除されています。

X-Google-DKIM-Signatureというヘッダがありましたが、DKIM作成者署名とは関係ないようです。

## 差出人がgmail.com (Ccなし)
 From: 改変なし
 DKIM-Signature: d=gmail.com. MLの配送アドレスごとに「darn=配送先ドメイン」のついた独自のDKIM-Signatureが付いている。

## 差出人がgmail.com (Ccあり)
CCがあるとDKIM-Signatureが2個付与されてMLの登録者に配送されます。

 From: 改変なし
 Cc: 外部アドレス
 DKIM-Signature (1個目): d=googlegroups.com. MLの配送アドレスごとに「darn=配送先ドメイン」のついた独自のDKIM-Signatureが付いている。
 DKIM-Signature (2個目): d=gmail.com. MLの配送アドレスごとに「darn=配送先ドメイン」のついた独自のDKIM-Signatureが付いている。

## 差出人がgmail.com以外
 From: ML名に変更(example-AT-googlegroups.com)
 DKIM: d=googlegroups.com. MLの配送アドレスごとに「darn=配送先ドメイン」のついた独自のDKIM-Signatureが付いている。

以上のような感じです。

# 2. 職場MLサーバで、送信者アドレスのDMARCがp=rejectの時の挙動(1)

はじめにで述べたようにAUのキャリアメールezweb.ne.jpのDMARCはp=rejectです。

> $ dig +short _dmarc.ezweb.ne.jp txt
> "v=DMARC1; p=reject; (以下略)"

AUのキャリアメールから職場のMLサーバ(ml.example.ac.jp)に送ってみます。

## alias転送
  Alias転送ではDKIMは壊れないため全ての受信確認用アドレスで正常受信できました。
 
## ML転送 (ARCを付与しcv=pass,DKIM破壊)
MLサーバmailman3を用いて、ARCを付与し、cv=passになるように設定しています。DKIM署名はそのままです。つまりDKIM作成者署名のみですので、DKIMは壊れています。

  - office365: 一旦受信するが、postmasterより受信拒否のメールが送られてくる。スパムフォルダにも無し。
  - outlook.jp: 受信成功。スパムフォルダに入っていた。
  - gmail: 受信成功。スパムフォルダに入っていた。
  - icloud.com: 受信拒否。スパムフォルダにも無し。/var/log/syslogに以下のログが記録されている。
   >said: 554 5.7.1 Your message was rejected due to ezweb.ne.jp's DMARC policy. See https://support.apple.com/en-us/HT204137 for info (in reply to end of DATA command))
  - 職場アドレス:　受信拒否(rspamdの設定がそうなってます)

上記の結果によりDKIMが壊れている場合はARCがcv=passであっても正常受信が出来ません。

## ML転送 (From行をMLアドレスに書き換え、DKIMを再付与、ARCを付与しcv=pass)
前述のGoogleのMLとほぼ同じ設定になります。

mailman3の設定で
「設定」→「リスト設定」→「DMARC対策」→「DMARCの緩和処理」
→「DMARCの緩和処理」→「From:をリストのアドレスに置き換える」
→「DMARC対策を無条件に実施」→「はい」

DKIM署名はezweb.ne.jpの作成者署名および MLのリストのアドレスに対する作成者署名が付与されます。ezwebのDKIM署名は壊れています。MLのリストのアドレスのDKIM署名はpassです。arcもcv=passになっています。

- office365, outlook.jp, gmail, icloud.com, 職場アドレス
 全てで成功。またスパムフォルダに入った例も無し。

上記の結果によりFrom行をMLサーバのアドレスに書き換えて、DKIMを再付与してDKIMを成功させないと、受信拒否になるようです。

## ML転送 (From行でMLアドレスに書き換え、DKIMを再付与、ARCはcv=fail)

mailman2でFrom行をMLアドレスに書き換え、DKIMを再付与します。mailman2はARCは未対応のため、cv=failになります。

設定→「全体的オプション」 →「From: ヘッダーのメールアドレスをリストの投稿アドレスに置き換え.... / from_is_list」→「Fromを書き換え」

- office365, outlook.jp, gmail, icloud.com, 職場アドレス
 全てで受信成功。ただしezwebのDKIM作成者署名はfail, MLサーバが再付与したDKIM署名はpassになります。前述のようにARCはcv=failです。

補足: mailman2では「/etc/mailman/mm_cfg.py」に「REMOVE_DKIM_HEADERS=3」と記載すればDKIM作成者は削除されます。DKIM作成者署名は「X-Mailman-Original-DKIM-Signature」に保存されます。

# 3. rspamdでrejectされたメールの調査
職場内で構築したpostfixの環境でDKIM+ARC+DMARCの設定はrspamdを用いました。rspamdがDMARCを見てrejectした場合、以下のような感じになりました。DMARCで拒否されたとは表示されず、Spamをrejectしたとしか表示されませんので、ログを確認するときは留意ください。

- rejectされてpostmaster宛てに送られてくるメール (受信設定をきちんとしてないと届きません。またmailman2/mailman3は自動処理のため、postmasterの届きません)

<PRE>
 ＜example@example.ac.jp＞: host
    mail.example.ac.jp[192.168.1.1] said: 554 5.7.1 Spam message
     rejected (in reply to end of DATA command)
</PRE>
- ログ(/var/log/maillog)の方では、 こんな感じで探せるかと思います。

<PRE>
$ sudo grep "Spam message rejected" /var/log/maillog
$ sudo grep milter-reject /var/log/maillog
</PRE>

# 4. mailman3の手動インストール (2024年8月現在)
職場MLサーバAlmaLinux8にmailman3.3.9を手動インストールしています。

AlmaLinux8にpackageとしてmailman2が入ってますのでmailman2もインストールしています。mailman2が入ってる環境にmailman3を導入するため、mailman3というログインIDを作り/opt/mailman3の下にインストールしています。(かなり面倒なのでお勧めしません。)

mailman3のインストール手順はネットで色々資料探しましたが、本家がいちばん詳しいです。

https://docs.mailman3.org/en/latest/install/virtualenv.html#virtualenv-install

補足：上記マニュアルでAlmaLinux8ではXapianの構築に失敗します。
https://docs.mailman3.org/en/latest/install/virtualenv.html#setting-up-fulltext-search-xapian

xapian_wheel_builder.shの149行目ぐらいでエラーになっています。(何も考えてない対策ですが)leadelfをコメントにしてコンパイルエラーを回避しました。
<PRE>
diff xapian_wheel_builder.sh.ORG   xapian_wheel_builder.sh
149c149
<             readelf -d "${file}" | grep RUNPATH | grep -q ORIGIN
---
>             #readelf -d "${file}" | grep RUNPATH | grep -q ORIGIN
</PRE>

次に、DesignNETさんの日本語パッチを当ててます。

https://www.designet.co.jp/ossinfo/mailman/translate_mailman3/

(2024/8現在)上記で「mailman3-japanese-web.patch」はうまくパッチが当たらないので手パッチの必要あります。面倒になったのでこのパッチはあててません。

参考文献： 
>DesignNETさんのマニュアル
>https://www.designet.co.jp/ossinfo/mailman/mailman3_user_manual/

>OSSTechさんのマニュアル（ソフトウエアは有償）
>https://www.osstech.co.jp/download/updates/docs/mailman/OSTD-Mailman3-InstallGuide.pdf
>https://www.osstech.co.jp/download/updates/docs/mailman/OSTD-Mailman3-AdminGuide.pdf

# 5. fml4の手動インストール (2024年8月現在)
(お勧めしません。古いMLの設定を温存するために入れてる感じです。)

職場MLサーバAlmaLinux8にfml4を手動インストールしています。以下のリンク先参照ください。OSが違いますが、だいたい同じ手順でインストールしてます。

https://qiita.com/qiitamatumoto/items/af319db823a2bbe58a28

次の記事も役にたちます。

>さくらレンタルサーバのメーリングリストを DKIM/DMARC に対応させる
>https://ocg.aori.u-tokyo.ac.jp/member/daigo/comp/memo/?val=all&typ=all&nbr=2024020501

概ねmailman2/mailman3のDKIMの回避策と同等の処理になりますが、From行の挙動がちょっと違います。


mailman2/3ではFrom行の差出人がMLに変換される処理でmailmanの場合はFrom行に差出人の名前が残るようになります。またReply-Toに差出人のメールアドレスがコピーされます。

具体的には
<PRE>
From: 差出人の名前 (example 経由) ＜example@ml.example.ac.jp＞
Reply-To: 差出人のメールアドレス
</PRE>
みたいに誰が出したかわかります。ですが、上記のFMLパッチはFromをmlのアドレスに書き換えるだけですので、差出人の名前や差出人のメールアドレスがわからなくなります。要改善のようです。

# 6.ARCの検証が失敗する
ARCの検証が失敗する例が多々起きまして、調査に手間取りました。

## openarcはcv=failになる事が多い
よくわかりませんがopenarcでcv=failになった場合でもrspamdではcv=passになる事が多いため、openarcはやめて、rspamdに変更しました。 openarcはopenarc-1.0.0-0.15.Beta3.el8.x86_64を用いてます。rspamdはrspamd-3.9.1-1.el8.x86_64を用いてます。rspamdは順調です。

## rspamdで特定環境でcv=failになる
受信の確認に用いるアドレスで、office365だけcv=failになり、他の環境ではcv=passになる現象が起きました。

rspamdは標準で「Authentication-Results」ヘッダを付けないため、下記のブログを参考にヘッダを付与していました。

https://psychoco.net/linux/mail-server-with-rspamd-on-rhel9

これをやめたところ、office365でもcv=passになりました。

特に理由なければrspamdでAuthentication-Resultsヘッダを付けないほうが無難です。