DMARCを整理してみた

# 背景・目的
以前、SESを使用してDMARCの設定を行いました。さらに理解を深めるために整理します。

https://qiita.com/zumax/items/22a7bbc975a86afcb07a

# まとめ
下記に特徴を整理します。

|パラメータ名|必須/任意|説明|
|:--|:--|:--|
|v	| 必須|バージョン。常に「DMARC1」固定|
|p	|必須|ポリシー。認証失敗時にどうするか<BR>・none: 何もしない（モニタリング）<BR>・quarantine: 迷惑メール扱い<BR>・reject: 受信拒否|
|sp	|任意|サブドメインに対するポリシー<BR>親ドメインと別のポリシー指定可。<BR>例: sp=quarantine|
|rua|任意|集計レポート送信先（mailto形式）|
|ruf|任意|フォレンジックレポート送信先（mailto形式）|
|rf|任意|メッセージ固有の障害レポートに使用される形式|
|ri|任意|集計レポート間の要求された間隔<BR>デフォルトは 86400|
|fo|任意	|フォレンジックレポート送信条件<BR>・0: SPF/DKIM両方失敗<BR>・1: SPFかDKIMのどちらか失敗<BR>・d: DKIM失敗のみ<BR>・s: SPF失敗のみ|
|pct|任意|ポリシー適用率（%）。段階導入に適している<BR>例: pct=50なら半分だけ適用|
|adkim|任意|DKIM整合性チェックモード<BR>・r: Relaxed（緩い）<BR>・s: Strict（厳格）|
|aspf|任意|SPF整合性チェックモード<BR>・r: Relaxed（緩い）<BR>・s: Strict（厳格）|


# 概要
## 6.3.  General Record Format
下記の記事を基にレコードフォーマットを整理します。

https://datatracker.ietf.org/doc/html/rfc7489#section-6.3

### v

>   v: Version (plain-text; REQUIRED).  Identifies the record retrieved
      as a DMARC record.  It MUST have the value of "DMARC1".  The value
      of this tag MUST match precisely; if it does not or it is absent,
      the entire retrieved record MUST be ignored.  It MUST be the first
      tag in the list.

- バージョン
- 必須
- 取得されたレコードをDMARCレコードとして識別する
- 値は、DMARC1とする必要がある
- 指定されていない場合は、レコード全体が無視される可能性がある
- リストの最初のタグである必要がある

### p
   > p: Requested Mail Receiver policy (plain-text; REQUIRED for policy
      records).  Indicates the policy to be enacted by the Receiver at
      the request of the Domain Owner.  Policy applies to the domain
      queried and to subdomains, unless subdomain policy is explicitly
      described using the "sp" tag.  This tag is mandatory for policy
      records only, but not for third-party reporting records (see
      Section 7.1).  Possible values are as follows:

   >   none:  The Domain Owner requests no specific action be taken
         regarding delivery of messages.

   >   quarantine:  The Domain Owner wishes to have email that fails the
         DMARC mechanism check be treated by Mail Receivers as
         suspicious.  Depending on the capabilities of the Mail
         Receiver, this can mean "place into spam folder", "scrutinize
         with additional intensity", and/or "flag as suspicious".

   >   reject:  The Domain Owner wishes for Mail Receivers to reject
         email that fails the DMARC mechanism check.  Rejection SHOULD
         occur during the SMTP transaction.  See Section 10.3 for some
         discussion of SMTP rejection methods and their implications.

- 要求されたメール受信者ポリシー
- ドメイン所有者の要求に応じて受信者が施行するポリシーを示す
- サブドメイン ポリシーが「sp」タグを使用して明示的に記述されていない場合、ポリシーはクエリされたドメインとサブドメインに適用される
- このタグはポリシーレコードにのみ必須。しかしサードパーティのレポートレコードには必須ではない
    - サードパーティのレポートレコードとは、ドメイン所有者が第三者に対してDMARCレポートを送信するよう依頼する際に使用するレコード
    - ruaやrufといったタグが主に使用され、pタグは必須ではない
- 指定可能な値は下記の通り
    - none
        - ドメイン所有者は、メッセージの配信に関して特別な措置を講じない
    - quarantine
        - ドメイン所有者は、DMARC メカニズム チェックに失敗したメールをメール受信者が疑わしいメールとして扱うように希望する
        - メール レシーバーの機能に応じて、下記として処理される
            - スパム フォルダーに配置する
            - さらに厳しく精査する
            - 疑わしいとしてフラグを付ける
    - reject
        - ドメイン所有者は、メール受信者が DMARC メカニズム チェックに失敗したメールを拒否することを希望する
        - 拒否はSMTPトランザクション中に発生する想定

### sp
>    sp:  Requested Mail Receiver policy for all subdomains (plain-text;
      OPTIONAL).  Indicates the policy to be enacted by the Receiver at
      the request of the Domain Owner.  It applies only to subdomains of
      the domain queried and not to the domain itself.  Its syntax is
      identical to that of the "p" tag defined above.  If absent, the
      policy specified by the "p" tag MUST be applied for subdomains.
      Note that "sp" will be ignored for DMARC records published on
      subdomains of Organizational Domains due to the effect of the
      DMARC policy discovery mechanism described in Section 6.6.3.

- すべてのサブドメインの要求されたメール受信ポリシー
- ドメイン所有者の要求に応じて受信者が施行するポリシーを示す
- クエリされたドメインのサブドメインにのみ適用され、ドメイン自体には適用されない
- 構文は、上で定義した「p」タグの構文と同じ
- 存在しない場合は、「p」タグで指定されたポリシーをサブドメインに適用する必要がある



### rua
>    rua:  Addresses to which aggregate feedback is to be sent (comma-
      separated plain-text list of DMARC URIs; OPTIONAL).  A comma or
      exclamation point that is part of such a DMARC URI MUST be encoded
      per Section 2.1 of [URI] so as to distinguish it from the list
      delimiter or an OPTIONAL size limit.  Section 7.1 discusses
      considerations that apply when the domain name of a URI differs
      from that of the domain advertising the policy.  See Section 12.5
      for additional considerations.  Any valid URI can be specified.  A
      Mail Receiver MUST implement support for a "mailto:" URI, i.e.,
      the ability to send a DMARC report via electronic mail.  If not
      provided, Mail Receivers MUST NOT generate aggregate feedback
      reports.  URIs not supported by Mail Receivers MUST be ignored.
      The aggregate feedback report format is described in Section 7.2.


- 集計フィードバックを送信するアドレス
- 任意の有効なURIを指定できる
- メール受信者は、「mailto:」URI のサポート、電子メール経由で DMARC レポートを送信する機能を実装する必要がある
- 提供されていない場合、メール受信者は集計フィードバックレポートを生成してはならない
- メール受信者によってサポートされていない URI は無視する必要がある

### ruf
>    ruf:  Addresses to which message-specific failure information is to
      be reported (comma-separated plain-text list of DMARC URIs;
      OPTIONAL).  If present, the Domain Owner is requesting Mail
      Receivers to send detailed failure reports about messages that
      fail the DMARC evaluation in specific ways (see the "fo" tag
      above).  The format of the message to be generated MUST follow the
      format specified for the "rf" tag.  Section 7.1 discusses
      considerations that apply when the domain name of a URI differs
      from that of the domain advertising the policy.  A Mail Receiver
      MUST implement support for a "mailto:" URI, i.e., the ability to
      send a DMARC report via electronic mail.  If not provided, Mail
      Receivers MUST NOT generate failure reports.  See Section 12.5 for
      additional considerations.

- メッセージ固有の障害情報が報告されるアドレス（DMARC URI のコンマ区切りのプレーンテキスト リスト、オプション）
- 存在する場合、ドメイン所有者は、特定の方法で DMARC 評価に失敗したメッセージに関する詳細な失敗レポートを送信するようにメール受信者に要求する (「fo」タグを参照)
- 生成されるメッセージの形式は、「rf」タグに指定された形式に従う必要がある
- メール受信者は、「mailto:」URI のサポート、電子メール経由で DMARC レポートを送信する機能を実装する必要がある
- メール受信者によってサポートされていない URI は無視する必要がある

### rf
>    rf:  Format to be used for message-specific failure reports (colon-
      separated plain-text list of values; OPTIONAL; default is "afrf").
      The value of this tag is a list of one or more report formats as
      requested by the Domain Owner to be used when a message fails both
      [SPF] and [DKIM] tests to report details of the individual
      failure.  The values MUST be present in the registry of reporting
      formats defined in Section 11; a Mail Receiver observing a
      different value SHOULD ignore it or MAY ignore the entire DMARC
      record.  For this version, only "afrf" (the auth-failure report
      type defined in [AFRF]) is presently supported.  See Section 7.3
      for details.  For interoperability, the Authentication Failure
      Reporting Format (AFRF) MUST be supported.

- メッセージ固有の障害レポートに使用される形式 
- このタグの値は、ドメイン所有者が要求した 1 つ以上のレポート形式のリストであり、メッセージが [SPF] と [DKIM] の両方のテストに失敗した場合に、個々の失敗の詳細を報告するために使用される
- このバージョンでは、現在「afrf」（[AFRF]で定義されている認証失敗レポートタイプ）のみがサポートされていいる

### ri
>    ri:  Interval requested between aggregate reports (plain-text 32-bit
      unsigned integer; OPTIONAL; default is 86400).  Indicates a
      request to Receivers to generate aggregate reports separated by no
      more than the requested number of seconds.  DMARC implementations
      MUST be able to provide daily reports and SHOULD be able to
      provide hourly reports when requested.  However, anything other
      than a daily report is understood to be accommodated on a best-
      effort basis.

- 集計レポート間の要求された間隔 
- デフォルトは 86400
- 要求された秒数以内で区切られた集計レポートを生成するよう受信者に要求することを示す
- DMARC 実装は、毎日レポートを提供できる必要があり、要求に応じて時間ごとのレポートを提供できる必要がある



### fo
   > fo:  Failure reporting options (plain-text; OPTIONAL; default is "0")
      Provides requested options for generation of failure reports.
      Report generators MAY choose to adhere to the requested options.
      This tag's content MUST be ignored if a "ruf" tag (below) is not
      also specified.  The value of this tag is a colon-separated list
      of characters that indicate failure reporting options as follows:

   >    0: Generate a DMARC failure report if all underlying
         authentication mechanisms fail to produce an aligned "pass"
         result.

   >   1: Generate a DMARC failure report if any underlying
         authentication mechanism produced something other than an
         aligned "pass" result.

   >   d: Generate a DKIM failure report if the message had a signature
         that failed evaluation, regardless of its alignment.  DKIM-
         specific reporting is described in [AFRF-DKIM].

   >   s: Generate an SPF failure report if the message failed SPF
         evaluation, regardless of its alignment.  SPF-specific
         reporting is described in [AFRF-SPF].

- 障害レポート
- デフォルトは「0」
- 障害レポートの生成に必要なオプションを提供する
- レポート生成者は、要求されたオプションに従うことを選択できる
- 「ruf」タグも指定されていない場合は、このタグの内容は無視されなければならない
- 下記の値を指定する
    - 0:
        - すべての基礎となる認証メカニズムが一致した「合格」結果を生成できない場合は、DMARC 失敗レポートを生成
        - SPF／DKIM両方失敗した場合
    - 1:
        - 基盤となる認証メカニズムが、整合された「合格」結果以外の結果を生成した場合は、DMARC 失敗レポートを生成する
        - SPFまたは、DKIMが失敗した場合
    - 2:
        - メッセージの署名がアライメントに関係なく評価に失敗した場合には、DKIM 失敗レポートを生成
    - 3:
        - メッセージが SPF 評価に失敗した場合は、その配置に関係なく SPF 失敗レポートを生成

### pct
   > pct:  (plain-text integer between 0 and 100, inclusive; OPTIONAL;
      default is 100).  Percentage of messages from the Domain Owner's
      mail stream to which the DMARC policy is to be applied.  However,
      this MUST NOT be applied to the DMARC-generated reports, all of
      which must be sent and received unhindered.  The purpose of the
      "pct" tag is to allow Domain Owners to enact a slow rollout
      enforcement of the DMARC mechanism.  The prospect of "all or
      nothing" is recognized as preventing many organizations from
      experimenting with strong authentication-based mechanisms.  See
      Section 6.6.4 for details.  Note that random selection based on
      this percentage, such as the following pseudocode, is adequate:

>   if (random mod 100) < pct then
         selected = true
       else
         selected = false

- DMARC ポリシーが適用されるドメイン所有者のメール ストリームからのメッセージの割合
- 0 から 100 までのプレーンテキスト整数。オプション
- デフォルトは 100
- **ただし、これは DMARC で生成されたレポートには適用してはならない。DMARC で生成されたレポートはすべて、妨げられることなく送受信される必要がある**
- 「pct」タグの目的は、ドメイン所有者が DMARC メカニズムの緩やかなロールアウトを実施できるようにすること
- 何％のメールに対してDMARCポリシーを適用するか
- テスト導入や段階的移行時に使用


### adkim
 >  adkim:  (plain-text; OPTIONAL; default is "r".)  Indicates whether
      strict or relaxed DKIM Identifier Alignment mode is required by
      the Domain Owner.  See Section 3.1.1 for details.  Valid values
      are as follows:

 >    r: relaxed mode

 >    s: strict mode

- DKIM署名のFromドメインの一致条件
- ドメイン所有者が厳密な DKIM 識別子アライメント モードまたは緩和された DKIM 識別子アライメント モードを必要とするかどうかを示す
- デフォルトは「r」
- 下記の値がある
    - r:relaxed mode
        - 緩い
    - s:strict mode
        - 厳格

### aspf
  >  aspf:  (plain-text; OPTIONAL; default is "r".)  Indicates whether
      strict or relaxed SPF Identifier Alignment mode is required by the
      Domain Owner.  See Section 3.1.2 for details.  Valid values are as
      follows:

  >    r: relaxed mode

  >    s: strict mode

- SPFの「Fromドメイン」一致条件
- ドメイン所有者が厳密な SPF 識別子アライメント モードまたは緩和された SPF 識別子アライメント モードを必要とするかどうかを示す
- default is "r"
- 下記の値がある
    - r:relaxed mode
        - 緩い
    - s:strict mode
        - 厳格

## サンプル
上記の仕様を踏まえてサンプルを考えてみます。

:::note warn
下記は、実際に試していませんのでご注意ください
:::

### モニタリング用のサンプル
まずはメールの状況を把握するための最小限の設定。レポートだけ受け取る形。

```bash
v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com; ri=86400
```

|パラメータ|説明|
|:--|:--|
|v=DMMRC1|固定|
|p=none|失敗しても何もしない（モニタリングのみ）|
|rua=`mailto:dmarc-reports@example.com`|集計レポート送信先|
|ri=86400|24時間ごとにレポート送信希望（受信サーバー次第）|

### なりすまし拒否用サンプル
DMARCを強制適用して、なりすましメールは拒否。サブドメインにも適用し、フォレンジックレポートも取得。

```bash
v=DMARC1; p=reject; sp=reject; rua=mailto:dmarc-reports@example.com; ruf=mailto:dmarc-forensic@example.com; fo=1; adkim=s; aspf=s
```

|パラメータ|説明|
|:--|:--|
|v=DMARC1|バージョン固定|
|p=reject|失敗したメールは拒否|
|sp=reject|サブドメインにもreject適用|
|rua|集計レポート送信先|
|ruf|フォレンジックレポート送信先
|fo=1|SPFかDKIMのどちらか失敗したらフォレンジックレポート送信|
|adkim=s|DKIMのドメインチェックは厳格（strict）|
|aspf=s|SPFのドメインチェックも厳格（strict）|

### 迷惑メールフォルダ送りのサンプル
まずはquarantine（迷惑メールフォルダ送り）にして様子を見る

```bash
v=DMARC1; p=quarantine; sp=quarantine; rua=mailto:dmarc-reports@example.com; ri=86400; fo=1
```

|パラメータ|説明|
|:--|:--|
|v=DMARC1|バージョン固定|
|p=quarantine|迷惑メールフォルダ送り|
|sp=quarantine|サブドメインにもquarantine適用|
|rua|集計レポート送信先|
|ri=86400|24時間ごとにレポート送信希望（受信サーバー次第）|
|fo=1|SPFかDKIMのどちらか失敗したらフォレンジックレポート送信|

### 段階的適用サンプル
まずは30%だけポリシー適用する

```bash
v=DMARC1; p=quarantine; pct=30; rua=mailto:dmarc-reports@example.com
```

|パラメータ|説明|
|:--|:--|
|v=DMARC1|バージョン固定|
|p=quarantine|迷惑メールフォルダ送り|
|pct=30|30%のメールにだけポリシー適用|
|rua|集計レポート送信先|

# 考察
今回、DMARCについてRFCを基に整理してみました。
次回以降、実際に実装し検証してみたいと思います

# 参考
https://qiita.com/zumax/items/22a7bbc975a86afcb07a

https://datatracker.ietf.org/doc/html/rfc7489