ぼくのかんがえたさいきょうのPostfix(DKIM&DMARC編)


さらに引き続きネタ。最新の送信ドメイン認証技術であるDKIMとDMARCをPostfixで使う設定を書いていきます。
そもそもそれぞれがどういったものかから書いていった方がいいかなと思いますので、簡単に解説します。詳しい解説はDKIM.jpの解説Yahooの中の人による解説がそれぞれわかりやすいですかね。
簡単に言うとヘッダーに署名を付加してその署名を検証するための公開鍵をDNSに定義しておき、そのメールが正しいサーバ(秘密鍵を持ったサーバ)から送信されたものかどうかを見分ける仕組みがDKIMです。
そしてDKIMやSPFと言った送信ドメイン認証技術の運用状況を検証するための枠組みがDMARCと言ったところでしょうか。ゆくゆくは制御に関するポリシーも公開して受信側に適用してもらいたいというのがDMARCの目指す未来なんだと思いますが、現状ではまだそこまで追いついていません。調べたところではPostfix+OpenDMARCの環境で、送信者側のDMARCポリシーに基づいて挙動を変える方法がわからなかったので、実質的には必要な情報をヘッダに付加してMUA側の振り分けルールで対応するのが関の山というのが現状ではないかと思います。

必要なパッケージのインストール

# aptitude install opendkim opendkim-tools opendmarc
おなじみのaptitudeでインストールしてしまうのがDebianではお手軽ですね。

秘密鍵と公開鍵の生成

# opendkim-genkey -D /etc/opendkim/ -d phase-d.com -s 20151225

# chown opendkim:opendkim /etc/opendkim/20151225.*

鍵ペアの生成もコマンド一発でやってくれるのでお手軽です。引数としては
-D ドメイン名
-d 出力先のディレクトリ名
-s セレクタ名
となりますので、この辺は環境に応じて適宜。セレクタ名は日付にしておくのが慣習っぽいですが、ポリシーに合わせてご自由にというところですね。
これで/etc/opendkimの下に「20151225.private」という秘密鍵と「20151225.txt」という公開鍵が生成されます。この内、秘密鍵の方は後ほどopendkim.confで指定します。一方、公開鍵の方は中身を参照してDNSサーバにTXTレコードとして登録します。BIND書式で出力されるので、お使いのDNSサーバ・サービスに合わせて適宜ですね。
「セレクタ名._domainkeys.ドメイン名」というFQDNのTXTレコードの中身が、「v=DKIM1; k=rsa; p=以下略」となるようにしましょう。具体的にはこんな感じ。

;; QUESTION SECTION:
;20151225._domainkey.phase-d.com. IN TXT

;; ANSWER SECTION:
20151225._domainkey.phase-d.com. 3599 IN TXT “v=DKIM1\; k=rsa\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9WEbYB2XwCs+IPEWsMc8FrlecH6rxnR+Em24zyN4wmmlW2CweZfCmJv1h0/MiFyJ/uWlPx0O/IedzXnZSgvSCIOKRZdfjndGv3kZ2s0ueB4d1Rp+6tIFiyNzIXVYNTuJo8aTZH4Hopdfpkj9nYfjdFQX8mkre7773EfThUr2BqwIDAQAB”

/etc/opendkim.confの設定

Syslog yes
UMask 002

Domain phase-d.com
KeyFile /etc/opendkim/20151225.private
Selector 20151225

Mode sv

OversignHeaders From

SignatureAlgorithm rsa-sha256
AutoRestart Yes
AutoRestartRate 10/1h

InternalHosts /etc/opendkim/TrustedHosts
ExternalIgnoreList /etc/opendkim/TrustedHosts
KeyTable /etc/opendkim/KeyTable
SigningTable /etc/opendkim/SigningTable

コメント行以外で設定しているのはこれだけですね。各パラメータの細かい意味はman opendkim.confとかで確認いただきたいところ。
Modeをsvにしておくと送信時の署名(Signer)と受信時の検証(Verifier)をそれぞれ行います。
ADSPDiscardという設定でyesが指定できると、受信時の判定でADSPレコードのポリシーに従った処理をしてくれるっぽいんだけど、これを有効にすると何故かエラーで起動できないので不本意ながらコメントアウトしたままにしてます。

/etc/opendkim以下その他の設定

==> KeyTable <==
20151225._domainkey.phase-d.com phase-d.com:20151225:/etc/opendkim/20151225.private

==> SigningTable <==
phase-d.com 20151225._domainkey.phase-d.com

それぞれこのようにDKIMの署名をするセレクタ名や秘密鍵を定義します。
DKIMの設定はここまで。続いて、DMARCの設定。

DMARC定義をTXTレコードして公開

$ dig txt _dmarc.phase-d.com

;; QUESTION SECTION:
;_dmarc.phase-d.com. IN TXT

;; ANSWER SECTION:
_dmarc.phase-d.com. 3600 IN TXT “v=DMARC1\; p=reject\; rua=mailto:postmaster@phase-d.com”

DMARCの設定としては自ドメインのTXTレコードにこんな具合の定義を公開しておくと、主要なメールプロバイダ(Gmailとか)から「自ドメインをFromとしたメールがどのくらい送られているか」という統計レポートが日々送られてくるようになります。これをどう活用するかは運用する人次第ですが、少なくとも「自ドメインを騙ったスパムがどのくらい存在するのか」を探る手がかりにはなります。
また通常は「p=none」で始めるのが正解です。この場合、受信サーバ側はDMARCの判定結果がなんであろうと、特に取り扱いを変えることはありません。しばらく運用をして、かつ受信したレポートを分析していると「自ドメインをFromとするメールは全てSPFにPassしてDKIM署名もついたものしか送られない、それ以外はスパムである」と判断することも可能になってくると思いますので、その場合は「p=quarantine」や「p=reject」にすると世の中のメール受信サーバを運用する人にとっては有益な情報を公開するということに繋がりますし、ひいては自ドメインのレピュテーション向上に寄与する可能性はあると思います。

/etc/opendmarc.confの設定

AuthservID HOSTNAME
FailureReportsBcc postmaster@phase-d.com
HistoryFile /var/run/opendmarc/opendmarc.dat
IgnoreAuthenticatedClients true
IgnoreMailFrom phase-d.com
PidFile /var/run/opendmarc/opendmarc.pid
RejectFailures false
Syslog true
SyslogFacility mail
TrustedAuthservIDs HOSTNAME
UMask 002
UserID opendmarc:opendmarc

続いてOpenDMARCの設定。こっちもあまりデフォルトからは変えてないです。受信したメールの統計情報がHistoryFileとして保存されるので、これはスクリプトを使って1日1回程度送信元にレポートをフィードバックしてあげます。この辺は任意というかボランティア精神的なところはありますが。
本当は各ドメインのDMARCポリシーにしたがって処理をできれば良いんでしょうけど、manを読んだ感じだとRejectFailuresという「DMARC判定にFailしたらReject」というのしか無いっぽいのでひとまず結果をヘッダに付記してあとは振り分けルールなどで対応というのが現状の最適解なのかなと思っています。

レポート用MySQLの設定

mysql> CREATE DATABASE opendmarc;
mysql> GRANT ALL PRIVILEGES ON opendmarc.* TO opendmarc IDENTIFIED BY ‘opendmarc’;

# mysql -h localhost -u opendmarc -p opendmarc < /usr/share/doc/opendmarc/schema.mysql

DMARCのレポート送信はMySQLを使ってお手軽に行える枠組みがあります。統計を送るサーバにMySQLが動いてないといけないというネックはありますが、一応こんな感じで実施できます。この場合はlocalhostでMySQLが動いてる想定ですが、別に別ホストで動いてても問題ありません。
ひとまずこのような具合でそれ用のデータベースを作って、用意されているスキーマを流し込みます。ちなみに少なくともパスワードは環境に合わせて任意に変えましょう。

レポート送信スクリプト設定

#!/bin/bash
# Imports data from OpenDMARC’s opendmarc.dat file into a local MySQL DB
# and sends DMARC failure reports to domain owners.
# Based on a script from Hamzah Khan (http://blog.hamzahkhan.com/)

# Database and History File Info

DBHOST=’localhost’
DBUSER=’opendmarc’
DBPASS=’opendmarc’
DBNAME=’opendmarc’
HISTDIR=’/var/run/opendmarc’
HISTFILE=’opendmarc’
LOG=’/var/log/opendmarc-reports.log’

# Make sure history file exists
touch ${HISTDIR}/${HISTFILE}.dat

# Move history file temp dir for processing
mv ${HISTDIR}/${HISTFILE}.dat /tmp/${HISTFILE}.$$

# Import temp history file data and send reports
/usr/sbin/opendmarc-import -dbhost=${DBHOST} -dbuser=${DBUSER} -dbpasswd=${DBPASS} -dbname=${DBNAME} -verbose < /tmp/${HISTFILE}.$$ >> ${LOG} 2>&1
/usr/sbin/opendmarc-reports -dbhost=${DBHOST} -dbuser=${DBUSER} -dbpasswd=${DBPASS} -dbname=${DBNAME} -verbose -interval=86400 -report-email ‘postmaster@phase-d.com’ -report-org ‘phase-d.com’ >> ${LOG} 2>&1
/usr/sbin/opendmarc-expire -dbhost=${DBHOST} -dbuser=${DBUSER} -dbpasswd=${DBPASS} -dbname=${DBNAME} -verbose >> ${LOG} 2>&1

# Delete temp history file
rm -f /tmp/*.$$

GitHubにあったスクリプトを少し改造して使っています。これをシェルスクリプトとして保存してcrontabに登録するか、あるいはいっそ/etc/cron.dailyに保存してしまえば、毎日このサーバで受信したメールのDMARC状況について、送信者側にフィードバックをすることが可能です。

こんな具合でDKIMとDMARCの設定をしてみました。
どちらもまだこれからという感じの技術ではありますが、中長期的には必須技術になってくるかなと思ってはいますので、可能な人は早めから対応を考えておいてもいいんじゃないかなと思います。

シェアする

フォローする