Posted at

Postfix + OpenDKIMで送信元ドメイン認証を実装するメモ

More than 1 year has passed since last update.

個人的メモ。調べてわかったことがあれば書き足す


1. DKIM


1-1. DKIMとは


  • DKIM(Domain Keys Identified Mail)

  • 送信元ドメインを認証するための技術



1-2. 処理の流れ


  1. 送信者が送信メールのヘッダ+本文でハッシュ作成

  2. ハッシュ + 秘密鍵で電子署名作成

  3. 電子署名をDKIM-Signatureヘッダとして添付

  4. メール送信

  5. 受信者が受信メールのヘッダ+本文でハッシュ作成

  6. DKIM-Signatureヘッダの電子署名から公開鍵でハッシュを復号

  7. 受信者が作成したハッシュと比較する


2. 検証環境


  • CentOS6.8


  • Postfix


  • OpenDKIM

    ※ Postfixの設定, BINDとかの設定は事前に適切に行われているものとする
    ※ example.comは例なので適宜読み替える



3. 手順


3-1. OpenDKIMの導入

標準のレポジトリにはないので、EPELから取ってくる

# yum install -y epel-release

# yum install -y opendkim


3-2. 鍵ペア作成

opendkim-genkeyを利用

opendkim-genkey -D [出力先ディレクトリ] -b [鍵の長さ] -d [ドメイン名] -s [セレクタ名]

(例)

# opendkim-genkey -D /etc/opendkim/keys -b 2048 -d example.com -s 20170309
# ls -l /etc/opendkim/keys/
20170309.private 20170309.txt
# chown -R opendkim:opendkim /etc/opendkim/keys/*

→ セレクタ名.privateとセレクタ名.txtが出来ている


→ xxx.privateが秘密鍵、xxx.txtがDNSのDKIMレコードとなる


→ 秘密鍵は漏洩しないように留意


3-3. KeyTable、SigningTableの更新


KeyTableを更新する

※ DKIMレコードと秘密鍵の関連付け?

# vi /etc/opendkim/KeyTable

以下の書式に従う

DKIMレコード名 ドメイン名:セレクタ名:秘密鍵ファイル


/etc/opendkim/KeyTable

20170309._domainkey.example.com example.com:20170309:/etc/opendkim/keys/20130709.private



SigningTableを更新する

※ どのDKIMレコードに対応する秘密鍵で署名するか決定するテーブル?

# vi /etc/opendkim/SigningTable

以下の書式に従う

対象のメールアカウント DKIMレコード名

なお、ドメインの全てのアカウントを一括指定も可能


/etc/opendkim/SigningTable

# アカウントを指定する書き方

hoge@examle.com 20170309._domainkey.example.com

# ワイルドカードを利用する書き方
*@example.com 20170309._domainkey.example.com

# ワイルドカードを利用しない書き方
@example.com 20170309._domainkey.example.com



3-4. opendkim.confの設定

設定ファイルをバックアップして編集

# \cp -p /etc/opendkim.conf /tmp/

# vi /etc/opendkim.conf

編集結果をdiff取ると、だいたいこんな感じ

# diff /etc/opendkim.conf /tmp/

39c39
< Mode sv
---
> Mode v
91c91
< #Selector default
---
> Selector default
98c98
< #KeyFile /etc/opendkim/keys/default.private
---
> KeyFile /etc/opendkim/keys/default.private
103c103
< KeyTable /etc/opendkim/KeyTable
---
> # KeyTable /etc/opendkim/KeyTable
108c108
< SigningTable refile:/etc/opendkim/SigningTable
---
> # SigningTable refile:/etc/opendkim/SigningTable
112c112
< ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
---
> # ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
115c115
< InternalHosts refile:/etc/opendkim/TrustedHosts
---
> # InternalHosts refile:/etc/opendkim/TrustedHosts


3-5. OpenDKIM起動

# chkconfig opendkim on

# service opendkim start
# netstat -lntp | grep opendkim
tcp 0 0 127.0.0.1:8891 0.0.0.0:* LISTEN xxxxxx/opendkim


3-6. Postfixの設定を変更

OpenDKIMはmilterとして動作するので、Postfixにmilterの設定を入れる

# vi /etc/postfix/main.cf

末尾に以下を追記


/etc/postfix/main.cf

...

# smtpdプロセスが利用するmilterの定義
smtpd_milters = inet:localhost:8891

# smtpdプロセス以外が利用するmilterの定義
non_smtpd_milters = inet:localhost:8891

# milterがメールを受け取ったときの既定の動作
milter_default_action = accept



3-7. Postfixの設定確認&再起動

# service postfix check

# service postfix reload
# postconf | egrep "(smtpd_milters|milter_default_action)"
milter_default_action = accept
non_smtpd_milters = inet:localhost:8891
smtpd_milters = inet:localhost:8891


3-8. DNSサーバへのTXTレコード登録


出力されたTXTレコードをコピー

# cat /etc/opendkim/keys/20170309.txt

こんな感じのが出力される(鍵ペア作成時の鍵長が長いと結構長い)

20170309._domainkey     IN      TXT     ( "v=DKIM1; k=rsa; "

"p=xxxxpubkeyxxxxxx..." "...xxxxxpubkeyxxxxx" ) ; ----- DKIM key 20170309 for example.com


zoneファイルに追記

zoneファイルにTXTレコードを追加する

DKIMレコードとADSPレコードを追加する


BINDの場合の例


/var/named/example.com.zone

20170309._domainkey     IN      TXT     ( "v=DKIM1; k=rsa; "

"p=xxxxpubkeyxxxxxx..." "...xxxxxpubkeyxxxxx" ) ; ----- DKIM key 20170309 for example.com
_adsp._domainkey IN TXT "dkim=unknown" ; DKIMの認証結果に対する取り扱い方針を示す


Route53の場合

Route53 -> Hosted zones -> 該当するDomain Nameクリック -> Create Record Setを選択

DKIMレコードの登録

Name: 20170309._domainkey.example.com
Type: TXT - Text
Alias: No
TTL: 任意
Value: "v=DKIM1; k=rsa; p=xxxxpubkeyxxxxxx..."
Routing Policy: Simple
Save Record Setをクリック

ADSPレコードの登録
Name: _adsp._domainkey.example.com
Type: TXT - Text
Alias: No
TTL: 任意
Value: "dkim=unknown"
Routing Policy: Simple
Save Record Setをクリック


3-9. 名前解決できることを確認

# dig 20170309._domainkey.example.com txt

...
;; ANSWER SECTION:
20170309._domainkey.example.com. 3600 IN TXT "v=DKIM1\; k=rsa\; " "xxxxxpubkeyxxxxx..." "...xxxxxpubkeyxxxxx"

# dig _adsp._domainkey.example.com txt
...
;; ANSWER SECTION:
_adsp._domainkey.example.com. 3600 IN TXT "dkim=unknown"

→ ANSWER SECTIONに想定通りの値が返ってくること。


3-10. メールを送信してみる


自分のGmailアカウント宛にメールを投げてみる

# echo "テストメールですよ" | mail -s "DKIMのテスト" hoge@gmail.com


maillogを確認してDKIM-Signatureフィールドが追加されていることを確認する

# tail /var/log/maillog

Mar 9 14:34:44 ns-test opendkim[23066]: 78A3B101059: DKIM-Signature field added (s=20170309, d=example.com)


3-11. 受信結果の確認

Gmailで受信したメールを確認してみる


Authentication-Resultsヘッダが"dkim=pass"となっていることを確認する

Authentication-Results: mx.google.com;

dkim=pass header.i=@example.com;
...

以上


3. 参考ページ