2022年8月、ホームページを全面リニューアルしました! 情報を分かりやすくお伝えできるサイト作りを目指してまいります。

PostfixによるSPF/Sender IDの実装!

SPFとは、 Sender Policy Framework と言って差出人のメールアドレスの偽造を防止するための、一つの技術である。 pobox.com の創始者が提唱したシステムらしい。
差出人の身元の判断を正確に行えば、「Spamブロックが出来る。」と言うことでSPAM防止の認証システムとしてなんとなく期待されている。
構造は、こんな感じだ。下の図1を見て欲しい。ドメインのメールを送信することができる正当なサーバ()のIPアドレスをそのドメインのDNSサーバ()のSPFレコードと言うTXTレコードで管理して公開する。宛先ドメインのメールサーバ()は、配送されてきたメールのメールサーバのIPアドレスとDNSサーバ()へ問い合わせて取得した差出人のSPFレコード情報のIPアドレスを照合して偽ったメールならば、メールサーバは自動的にメールを捨てる。これにより、SPAM屋が善良な庶民のドメイン名を含むメールアドレスを利用する悪行を防ぐことができる。だが、このシステムは多くの企業やISPがこのSPF採用を表明する事が必要である。

図1

また、SPAM屋が自前ドメインでRFCに則った正当なサーバを立てている場合や下の図2のようにドメインのメールサーバがクラックされ乗っ取られ踏み台となった場合は何れにせよ防ぐことは出来ない。だから、メールの受け取りを拒否するドメインを設定したりメールサーバのブラックリストを用意したりして、第2の対策の併用が必要である。

図2

このSPFは、IETFで標準化が検討されて、Microsoftが提唱していた同じ技術の「Caller ID for E-Mail」とSPFを統一化した「Sender ID」という名前で仕様を固め、標準として当初、普及させようとしていたらしいが、Microsoftの特許が引っかかることが解り、2007年3月現在、SPFの仕様も含めすったもんだしてるようだ。何れにせよ仕様が統合されているようなので、ここでは「SPF/Sender ID」(以降略してSPFと呼ぶ)と呼ぶことにする。

そんなこんなで、特許問題に引っかかって全てのSPFロジックが完成していないので、ここで説明するのは、SPFの送信側とPostfixに実装されているSPFの受信側Perlモジュールのセットアップと簡単なテストをした経緯や結果を説明する。
正直言うと、俺はこのSPFの受信側を使うつもりはない。受信側は、Sender IDとしてはPRAチェックという物のアルゴリズムにライセンス料が発生するらしい。
早い話、俺が送信するメールをSPAMだとされるのがはなはだ迷惑な話で、相手に「良い人が送ったメールである。」と判断されたいが為にこんな物使う訳で、自分に送られてきたメールをわざわざSPFチェックするつもりはない。それに、単にSender IDレコードを公開するだけならライセンスは無料で有ることも理由の一つだ。
つまり、正当なメールと判断されるためには、SPFの送信側のセットアップを行っておくことだ。SPFの送信側のセットアップは、自分のDNSサーバへSPFレコードを設置してBINDに読み込ませるだけなので簡単だ。


1.SPF送信側のセットアップ
SPFの送信側は、いたって簡単だ。BINDの正引きゾーンファイルにTXTレコードを一発書き入れてBINDを再起動するだけだ。
以下が正引きゾーンファイルの記入例だ。

1)手動でSPFレコードを作る

$ORIGIN xxxxxxxxx.net.
$TTL 86400
@     IN     SOA    ns.xxxxxxxxx.net. root.xxxxxxxxx.net. (
            2007030801 ; serial
            10800 ; refresh
            3600 ; retry
            604800 ; expire
            86400 ; default_ttl
            )

      IN     NS     ns
      IN     NS     ns.xxxxxxxxx.jp.

      IN     MX  10 mail

xxxxxxxxx.net.    IN   TXT ”v=spf1 mx ~all”
mail.xxxxxxxxx.net. IN   TXT ”v=spf1 a -all”

      IN     A      xxx.xxx.76.154
  ns  IN     A      xxx.xxx.76.154
  mail IN     A      xxx.xxx.76.154

  www IN     CNAME  ns
  pop IN     CNAME  mail
  smtp IN     CNAME  mail

固定IP一個で全てのサービスを行っているサーバならば、上記と同じ記載でOKのはずだ。

クラシックSPFとSender IDとは、若干表記方法が違うらしい。しかし、統合するという意味でいずれかがコンパチを保ってるようだ。
■ v=spf1 mx
v=spf1は、SPFのバージョンで本来のSPFとSender IDとの互換性を保つ意味もあるので、v=spf1にしておいた方無難だ。
mx は、このゾーンのmxレコード以外メールサーバは使わないことを意味している。
■ ~all
ドメインからの正当なメールでも送信ドメイン認証が成功しない場合があるかもしれない。と言うことを宣言して受信拒否をすることを防ぐのでこの記述は必ず必要である。
■ v=spf1 a
v=spf1は前と同じ意味。aは、このホストのaレコード以外使わないことを意味している。
■ -all
このホスト以外からのメールは転送されてこないことを意味する。

注:SPFレコードの設定が終わったら、必ずbindを再起動する。

2)SPFウィザードを使ってSPFレコードを作る
SPFレコードは1)以外に、Webサイトのウィザードを使って出力することも出来る。
以下のサイトにアクセスする。

マイクロソフトの
http://www.microsoft.com/mscorp/safety/content/technologies/senderid/wizard/
もあるけど、今回は、
http://old.openspf.org/wizard.html
で説明する。あくまでも俺のドメインの場合の例なので悪しからず。

■ 自分のドメイン名を記載する。
図3のように、まず自分のドメイン名を入力して「Begin」をクリック。

図3

■ 自ドメインのMXサーバがメールサーバなので、mxのところを”yes”にチェック、ptrは、”no”にする。

図4

■ 後は、”~all”にチェックを入れて「Continue」をクリック。

図5
図6

■ 以下のような結果が出力されるので、1)と同じように正引きゾーンファイルに追加する。

If you run BIND

xxxxxxxxx.net. IN TXT “v=spf1 mx ~all”
mail.xxxxxxxxx.net. IN TXT “v=spf1 a -all”

If you run tinydns (djbdns)

‘xxxxxxxxx.net:v=spf1 mx ~all:3600
‘mail.xxxxxxxxx.net:v=spf1 a -all:3600

3)digコマンドで調べてみる
# dig xxxxxxxxx.net a txt
;; Warning, extra type option

; <<>> DiG 9.2.4 <<>> xxxxxxxxx.net a txt
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2391
;; flags: qr aa ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;xxxxxxxxx.net. IN TXT

;; ANSWER SECTION:
xxxxxxxxx.net. 86400 IN TXT “v=spf1 mx ~all”

;; AUTHORITY SECTION:
xxxxxxxxx.net. 86400 IN NS ns.xxxxxxxxx.jp.
xxxxxxxxx.net. 86400 IN NS ns.xxxxxxxxx.net.

;; ADDITIONAL SECTION:
ns.xxxxxxxxx.net. 86400 IN A 210.196.76.154
ns.xxxxxxxxx.jp. 68687 IN A 61.206.115.83

;; Query time: 39 msec
;; SERVER: 210.196.76.154#53(210.196.76.154)
;; WHEN: Thu Mar 8 14:55:54 2007
;; MSG SIZE rcvd: 140

確認、OK!
送信側のセットアップはこれでおしまい。続いて、受信側。


2.SPF受信側(Postfixに実装)のセットアップ
一応、受信側も説明するが、参考程度に見て欲しい(汗。
本来なら、SPFを実装したドメイン間のメールの送受信で試すのが本当だが、現状実験していない。
それと、一つ断っておかねばならないことだが、メールサーバからPOP受信したメールにはMTAでSPF認証の可否がヘッダーに記載される。
Received-SPF: spf-none(SPFを使っていない)
Received-SPF: spf-pass
(SPF認証成功)
Received-SPF: spf-fail(SPF認証失敗)
公開されているPerlスクリプトには、このような感じに本来記載されるが、AntiVirusやベイジリアンフィルタ等のプラグインモジュールの影響なのかは解らないが、このヘッダー情報が未だに発見できていない。しかし、実装方法は間違いは無いと思う。

1)必要なPerlモジュールをインスコ
SPFモジュールをインスコするには、PerlモジュールのMail::SPF::Queryのインスコが必須となる。

■ CPANでのインスコなら、以下の要領で行う。
# perl -MCPAN -e shell
> install Mail::SPF::Query

ちなみに、RHL系のyumを使うなら、
# yum install perl-Mail-Spf-Query

Debianなら、
# apt-get install libmail-spf-query-perl

2)smtpd-policy.plをインスコ
■ スクリプトをサイトからダウンロード。
# wget http://cri.univ-tlse1.fr/documentations/spam/outils/spf.pl

■ コピー&リネーム。
# cp spf.pl /usr/lib/postfix/smtpd-policy.pl
コピー先のパスはPostfixに実装により異なるので注意(/usr/libexec/postfix/smtpd-policy.plの場合もあり)。

# chmod 755 /usr/lib/postfix/smtpd-policy.pl

■ スクリプトを実行してみる。
# perl /usr/lib/postfix/smtpd-policy.pl
結果、エラーがなければOK!

■ Postfix側の設定変更
master.cfに以下の記述を追加。
# vi /etc/postfix/master.cf
前省略
policy  unix – n n – – spawn
user=nobody argv=/usr/lib/postfix/smtpd-policy.pl

main.cfにのsmtpd_recipient_restrictionsに以下を追加。
# vi /etc/postfix/main.cf
前省略
smtpd_recipient_restrictions = permit_mynetworks,
省略
reject_unknown_sender_domain,
reject_unauth_destination,
check_policy_service unix:private/policy
注:上記の記述順は変えないこと。

■ Postfixリロード
# postfix reload


3.SPFのテスト
SPFのテストをするのに手っ取り早いのは、 check-auth@verifier.port25.com へ空メールを送ると自ドメインのSPFをチェックして報告書を返信してくれる。
したがって、以下にテスト結果を説明する。

1)SPFを実装したドメインからのメールテスト結果

Return-Path: <auth-results@verifier.port25.com>
X-Original-To: test@xxxxxxxxx.net
Delivered-To: test@xxxxxxxxx.net
Received: from localhost (localhost [127.0.0.1]) by ns.xxxxxxxxx.net (Postfix) with ESMTP id 0E8E85BF1E for <test@xxxxxxxxx.net>; Wed, 7 Mar 2007 18:26:12 +0900 (JST)
Received: from ns.xxxxxxxxx.net ([127.0.0.1]) by localhost (ns [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 01848-10 for <test@xxxxxxxxx.net>; Wed, 7 Mar 2007 18:26:11 +0900 (JST)
Received: from verifier.port25.com (207-36-201-235.ptr.primarydns.com [207.36.201.235]) by ns.xxxxxxxxx.net (Postfix) with ESMTP id 36D725BE2A for <test@xxxxxxxxx.net>; Wed, 7 Mar 2007 18:26:09 +0900 (JST)
Received: by verifier.port25.com (PowerMTA(TM) v3.2r5t2) id htq21k0cm50u for <test@xxxxxxxxx.net>; Wed, 7 Mar 2007 04:21:23 -0500 (envelope-from <auth-results@verifier.port25.com>)
Date: Wed, 7 Mar 2007 04:21:23 -0500
From: auth-results@verifier.port25.com
To: test@xxxxxxxxx.net
Subject: Authentication Report
Message-Id: <1173259283-467473@verifier.port25.com>
X-Virus-Scanned: by amavisd-new-20030616-p10 (Debian) at xxxxxxxxx.net
X-Spam-Flag: Yes
X-Spam-Probability: 1.000000

途中省略

———————————————————-
mail-from check details:
———————————————————-
Result: pass
Address: test@xxxxxxxxx.net
Header: verifier.port25.com smtp.mail=test@xxxxxxxxx.net; mfrom=pass;

SPF TXT record/s:
v=spf1 mx ~all

———————————————————-
PRA check details:
———————————————————-
Result: pass
Address: test@xxxxxxxxx.net
Header: verifier.port25.com header.from=test@xxxxxxxxx.net; pra=pass;

PRA TXT record/s:
v=spf1 mx ~all

以下を見れば解るように、”pass”を言うのが認証テスト合格である。
Result:が認証結果で、SPF TXT record/s:がDNSへ問い合わせたときのSPFレコードの公開情報だ。したがって、結果として送信先のメールサーバで認証が合格したことを意味している。


“pass”
the sending domain publishes the given authentication policy
and the message passed the authentication tests.
送付ドメインは、与えられた認証方針を出版する、メッセージは認証テストに合格しました。

“fail”
the sending domain publishes the given authentication policy
and the message failed the authentication tests.
送付ドメインは、与えられた認証方針を出版する、メッセージは認証テストに失敗しました。


“softfail”
the sending domain publishes an authentication policy which doesn’t
require authentication of all messages from that domain, and the
message failed the authentication tests. Please note that a
SPF/Sender-Id status of “neutral” also results in “softfail”.
送付ドメインはそのドメインからのすべてのメッセージの認証を必要としない認証方針で、さらに失敗させて認証テストされるメッセージを意味する。

“neutral”
sending domain does not publish any sender authentication policy.
送信ドメインは少しの送信側認証方針も出版しない(不確定)。


“temperror”
a temporary (recoverable) error occurred attempting to authenticate
the sender; either the process couldn’t be completed locally because
of some transient condition, or there was a temporary failure
retrieving the sending domain’s policy; a later attempt to
re-authenticate this message might produce a more final result.
送付者を認証するのを試みながら、一時的な(回復可能な)誤りが発生しました。過程で何らかの一時的なことのために局所的に完了しなかったのか、または送付ドメインの方針を検索する一時障害があった。このメッセージにより、その後、再認証する試みが、より最終的な結果を生むかもしない。


“permerror”
a permanent (unrecoverable) error occurred attempting to
authenticate the sender; either the process couldn’t be completed
locally, or there was a permanent failure retrieving the sending.
domain’s policy
送付者を認証するのを試みながら、永久的な(復旧できない)誤りが発生しました。過程が局所的に完了しなかったか、または送付ドメインの方針を探す為に永久的な失敗がありました。

2)SPFを実装していないドメインからのメールテスト結果

Return-Path: <auth-results@verifier.port25.com>
X-Original-To: test@xxxxxxxxx.com
Delivered-To: test@xxxxxxxxx.com
Received: from localmail (localmail.localdomain [127.0.0.1]) by mail.xxxxxxxxx.com (Postfix) with ESMTP id E7F84194EC6 for <test@xxxxxxxxx.com>; Thu, 8 Mar 2007 08:36:20 +0900 (JST)
Received: from mail.xxxxxxxxx.com ([127.0.0.1]) by localmail (mail [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 18133-07 for <test@xxxxxxxxx.com>; Thu, 8 Mar 2007 08:36:20 +0900 (JST)
Received: from verifier.port25.com (207-36-201-235.ptr.primarydns.com [207.36.201.235]) by mail.xxxxxxxxx.com (Postfix) with ESMTP id 29ADD194D4A for <test@xxxxxxxxx.com>; Thu, 8 Mar 2007 08:36:18 +0900 (JST)
Received: by verifier.port25.com (PowerMTA(TM) v3.2r5t2) id htt5ls0cm502 for <test@xxxxxxxxx.com>; Wed, 7 Mar 2007 18:31:38 -0500 (envelope-from <auth-results@verifier.port25.com>)
Date: Wed, 7 Mar 2007 18:31:38 -0500
From: auth-results@verifier.port25.com
To: test@xxxxxxxxx.com
Subject: Authentication Report
Message-Id: <1173310298-431659@verifier.port25.com>
X-Virus-Scanned: amavisd-new at xxxxxxxxx.com
X-Spam-Flag: No
X-Spam-Probability: 0.000000
X-UIDL: `=””!SLc!!)2?”!N0″#!

———————————————————-
mail-from check details:
———————————————————-
Result: neutral
Address: test@xxxxxxxxx.com
Header: verifier.port25.com smtp.mail=test@xxxxxxxxx.com; mfrom=neutral;

SPF TXT record/s:


———————————————————-
PRA check details:
———————————————————-
Result: neutral
Address: test@xxxxxxxxx.com
Header: verifier.port25.com header.from=test@xxxxxxxxx.com; pra=neutral;

PRA TXT record/s:

これは、SPFレコードの公開情報を実装していないドメインのテスト結果である。
Result:結果がneutralでPRA TXT record/s:も空白だ。neutralとは、 「認証情報を公開していない。」という意味で確かな結果が出ている。

以上の結果から、SPF認証情報の公開で「正当なメールサーバからのメール。」というお墨付きはゲットできそうだ。しかし、逆にSPF受信として機能をしてるのかがイマイチハッキリしない。ただ、負け惜しみで言うのではないが、
Received-SPF: spf-none
Received-SPF: spf-pass

Received-SPF: spf-fail
を付けるものではない。と言う説もあるので本当はヘッダー情報は付けられないのかも知れないと言うのが俺の意見。


4.SPFのメールログ

SPFに対応および未対応のメールサーバからの受信ログ

1)受信したメールの送信元のメールサーバがSPF/Senderに対応している場合のメールログ(SPF認証に成功)
Feb 15 14:13:06 hiro postfix/policy-spf[7637]: : SPF pass: smtp_comment=Please see http://www.openspf.org/why.html?sender=post-01021432-xxxx%3Dxxxxxxx.net%40post.freeml.com&ip=211.125.95.46&receiver=hiro.xxxxxxx.net: 211.125.95.0/25 contains 211.125.95.46, header_comment=hiro.xxxxxxx.net: domain of post-01021432-xxxx=xxxxxxx.net@post.freeml.com designates 211.125.95.46 as permitted sender
Feb 15 14:13:06 hiro postfix/policy-spf[7637]: handler sender_permitted_from: PREPEND Received-SPF: spf-pass
Feb 15 14:13:06 hiro postfix/policy-spf[7637]: handler sender_permitted_from: PREPEND Received-SPF: spf-pass is decisive.
Feb 15 14:13:06 hiro postfix/policy-spf[7637]: decided action=PREPEND Received-SPF: spf-pass


2)受信したメールの送信元のメールサーバがSPF/Senderに対応していない場合のメールログ(SPFを使っていない)
Feb 15 14:49:05 hiro postfix/policy-spf[7882]: : SPF none: smtp_comment=SPF: domain of sender xxxxxxxxxxxx@ml-1.plala.or.jp does not designate mailers, header_comment=hiro.xxxxxxx.net: domain of xxxxxxxxxxxx@ml-1.plala.or.jp does not designate permitted sender hosts
Feb 15 14:49:05 hiro postfix/policy-spf[7882]: handler sender_permitted_from: PREPEND Received-SPF: spf-none
Feb 15 14:49:05 hiro postfix/policy-spf[7882]: handler sender_permitted_from: PREPEND Received-SPF: spf-none is decisive.
Feb 15 14:49:05 hiro postfix/policy-spf[7882]: decided action=PREPEND Received-SPF: spf-none

3)受信したメールの送信元が偽造されてる送信元の場合のメールログ(SPF認証に失敗)
Feb 17 11:21:58 hiro postfix/policy-spf[19039]: : SPF fail: smtp_comment=Please see http://www.openspf.org/why.html?sender=jsjkz%40changeip.org&ip=58.255.148.227&receiver=hiro.xxxxxxx.com, header_comment=hiro.xxxxxxx.com: domain of jsjkz@changeip.org does not designate 58.255.148.227 as permitted sender
Feb 17 11:21:58 hiro postfix/policy-spf[19039]: handler sender_permitted_from: PREPEND Received-SPF: spf-fail
Feb 17 11:21:58 hiro postfix/policy-spf[19039]: handler sender_permitted_from: PREPEND Received-SPF: spf-fail is decisive.
Feb 17 11:21:58 hiro postfix/policy-spf[19039]: decided action=PREPEND Received-SPF: spf-fail

以上

コメント