Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
27
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

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

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

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. 参考ページ

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
27
Help us understand the problem. What are the problem?