2016年1月19日火曜日

SPF + DKIMを設定して、Postfixでメールを送信(CentOS)

Postfixを使ってメール送信できるように設定をする手順です。
素のPostfixでもメール送信はできますが、SPFやDKIMといったメールの信頼性を高める認証技術を利用してメールを送信できるようにします。

実は、Amazon SESにSPF + DKIMを設定してメール送信をしようとしていたのですが、Yahooメールにテストメールを送信したところ、迷惑メールに振り分けられていたりしてAmazon SESの使用を断念した経緯がありました。メールヘッダを見ると一部のAmazon SESメールサーバのIPアドレスがYahooのフィルタでブロックされている記述がありました。これでは、使いものにならないので、EC2上にMTAを構築してメール送信をすることにしました。[AWSイスターシリーズ] Amazon Simple Email Service の選択肢 1 です。

以下の例では、EC2にMTAとしてPostfixを利用してメール送信するにはどうしらよいか?調べたメモになります。
なお、メール受信については取り扱っていません。

環境は EC2 CentOS 6 (x86_64) - with Updates HVM です。
IPアドレスは 192.0.1.1、ドメインは example.com としています
ドメインの設定は AWS Route53 を使用しています。別のDNSサービスを使っているときは、サービスにフォーマットを合わせてください。
以下、設定手順です。

Postfix

IPV4のみを使うようにします。
# emacs /etc/postfix/main.cf
inet_protocols = ipv4

SPFレコード

AWS Route53 を利用してSPFレコードを設定します。
Create Record Setから2つのレコードを登録します。
Name: 入力なし
Type: TXT
Value: "v=spf1 +ip4:192.0.1.1 -all"
Name: 入力なし
Type: SPF
Value: "v=spf1 +ip4:192.0.1.1 -all"
digコマンドで設定を確認。
$ dig example.com txt
example.com. 48 IN TXT "v=spf1 +ip4:192.0.1.1 -all"

※ 既にSPFレコードを登録している場合。
1つのドメインに対して複数行のspf1レコードは公開できません。そのばあいは、以下のフォーマットで1行にまとめて登録します。
"v=spf1 ip4:192.0.1.1 ip4:192.0.2.2 include:_spf.google.com ~all"
※ 既に別のTXTレコードがある場合。
複数行併記すれば良いです。
"google-site-verification=xxxxxxxxxxxxxx"
"v=spf1 ip4:192.0.1.1 ip4:192.0.2.2 include:_spf.google.com ~all"

DKIM レコード

SELINUXを無効にする。
# getenforce
Enforcing
# setenforce 0
Permissive
# emacs /etc/selinux/config
SELINUX=enforcing
->
SELINUX=disabled

OpenDKIMをインストール。
# rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
# yum -y install opendkim
鍵ファイルの作成先ディレクトリを用意して、鍵を作成。 -s で指定するセレクタは自由に設定できますが、ここでは、dkimselector としました。
# mkdir /etc/opendkim/keys/example.com
# opendkim-genkey -D /etc/opendkim/keys/example.com -d example.com -s dkimselector
# chown opendkim:opendkim /etc/opendkim/keys/example.com/*
鍵の中を確認します。
# cat /etc/opendkim/keys/example.com/dkimselector.txt
dkimselector._domainkey IN TXT ( "v=DKIM1; k=rsa; "
   "p=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" )  ; ----- DKIM key dkimselector for example.com
Route 53に2つのレコードを登録します。 公開鍵レコードを登録。
Name: dkimselector._domainkey
Type: TXT
Value: "v=DKIM1; k=rsa; p=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
ADSPレコードを登録。
_adsp._domainkey.example.com.  IN TXT "dkim=unknown"
登録したレコードが正しく引けるかを確認します。
# dig dkimselector._domainkey.example.com txt
# dig _adsp._domainkey.example.com txt 
DNSの設定はこれで完了です。

OpenDKIMの設定をしていきます。設定ファイルを編集。
# cp /etc/opendkim.conf /etc/opendkim.conf.org
# emacs /etc/opendkim.conf
---
Mode    v
->
Mode    sv

KeyFile /etc/opendkim/keys/default.private
->
# KeyFile /etc/opendkim/keys/default.private

# KeyTable      /etc/opendkim/KeyTable
->
KeyTable        refile:/etc/opendkim/KeyTable

# SigningTable  refile:/etc/opendkim/SigningTable
->
SigningTable   refile:/etc/opendkim/SigningTable

# ExternalIgnoreList    refile:/etc/opendkim/TrustedHosts
->
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts

# InternalHosts refile:/etc/opendkim/TrustedHosts
->
InternalHosts  refile:/etc/opendkim/TrustedHosts
DKIM署名に使う秘密鍵を指定。
# emacs  /etc/opendkim/KeyTable
dkimselector._domainkey.example.com example.com:dkimselector:/etc/opendkim/keys/example.com/dkimselector.private
DKIM署名を行うドメイン名を指定。
# emacs  /etc/opendkim/SigningTable
*@example.com  dkimselector._domainkey.example.com
メール送信を行うPostfixサーバのIPアドレスを指定。デフォルトで127.0.0.1が記述してあるので、このままで良いです。
# emacs  /etc/opendkim/TrustedHosts
127.0.0.1
OpenDKIMを起動。
# service opendkim start
OpenDKIMの自動起動を設定しておきます。
# chkconfig opendkim on
PostfixからOpenDKIMを使えるように設定します。最終行に追加。
# emacs /etc/postfix/main.cf
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters
milter_default_action = accept
Postfixをリロードします。
# service postfix reload
DKIM認証の設定が完了しました。

動作確認

Gmailなどへメールを送信してテストしてみます。
メールコマンドをインストールして、メール送信。
送り主を info@example.com、あて先を my-email-address@gmail.com としました。自身のメールアドレスに書き換えてください。
# yum -y install mailx
# echo "Test Mail." | mail -s "test mail" -r info@example.com my-email-address@gmail.com

メール送信ログ
DKIMフィールドが追加されている。
# tail -f /var/log/maillog
Jan 19 08:37:25 ip-192-0-1-1 opendkim[6565]: F182261A0A: DKIM-Signature field added (s=dkimselector, d=example.com)

メールヘッダ
下記のような表示があればOKです。
ヘッダーの Authentication-Results にGoogleが許可した認証を spf=pass, dkim=passのように追記しています。
Received-SPF: pass (google.com: domain of info@example.com designates 192.0.1.1 as permitted sender) client-ip=192.0.1.1;
Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of info@example.com designates 192.0.1.1 as permitted sender) smtp.mailfrom=info@example.com;
       dkim=pass header.i=@example.com
DKIM-Filter: OpenDKIM Filter v2.10.3 ip-192-0-1-1CAD5961A13
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com;
 s=dkimselector; t=1453192772;
 bh=XXXXXX=;
 h=Date:From:To:Subject:From;
 b=XXXX/XXXX
  XXXX
  XXXX=

まとめ

SPFとDKIMを設定してメール送信できるようにしました。
これで、認証付きのメール送信は出来るようになりましたが、携帯キャリアなどに送信テストしていません。用途によって、ちゃんとメール送信・受信テストする必要があります。
他にも、メールサービスによっては、フィルタがきつくて受信できないところもあるかもしれません。また、大量メール配信はできないでしょう。
クリティカルな用途でなかったら、これで十分かもしれませんが。用途によっては、メールの到達率、可用性く、大量のワークロードを処理できる、などといった指標をクリアする商用のMTAを使うことをおすすめしたいです。

See Also.
間違いから学ぶSPFレコードの正しい書き方 : 迷惑メール対策委員会
http://salt.iajapan.org/wpmu/anti_spam/admin/operation/information/spf_i01/
複数の SPF レコード - Google Apps 管理者 ヘルプ
https://support.google.com/a/answer/4568483
Postfix DKIM 認証 設定メモ(CentOS6.5+OpenDKIM) | あぱーブログ
https://blog.apar.jp/linux/856/
SE奮闘記: PostfixにDKIMを設定して送信メールサーバーの信頼度を上げる
http://se-suganuma.blogspot.jp/2015/01/postfixdkim.html
Top photo from Bill Ward Mail Trucks