先の記事で Postfix にグレイリスティングを組み込んだことで、spam を受け取る数が大幅に減った。
更なる spam 対策の一環として Sender Policy Framework (SPF) を利用した送信元サーバーの検証を行うようにする。
SPF とは、
- ある組織が、自分のドメインから送信されるメールは、これこれのメールサーバーからしか送信しないということを宣言する
- メールサーバーがそのドメインからのメールを受け取るときに、送信元のサーバーが宣言されているメールサーバーに含まれているか確認する
という方法で、不正なメールサーバーが勝手なドメインを名乗ってメールを送りつけてきたことを判定する仕組みだ
これによって、なりすましメールという spam の一種を防ぐことが可能になる。
この方式の欠点は、送信元が予め宣言しておかなくてはならないことだ。
また、大手のプロバイダやフリーメールでは SPF の宣言がされているところが多くなっているが、その中の一部ユーザーが送ってくる spam を判定することはできないということだ。(先のグレイリスティングでもこの手の spam を判定することは不可能。)
SPF については、プラスαレンタルサーバーの「SPFとは」の Web ページが (言っては悪いが) 以外と平易な表現で比較的わかりやすい。
より詳しく知りたいなら、ZDNET Japan の「メール送信者認証の仕組みを探る(2/2)」の Web ページが良いかもしれない。
なお、SPF は RFC 4408 (英文) -英日対訳(当時の Web ページは消滅。レイアウトは崩れるが Web アーカイブに痕跡あり)
- で定義されている。
SPF は先に書いたように宣言と確認の二つに分かれている。
送信するときには予め宣言し、受信のときは他者の宣言を参照して判定する。
このそれぞれは独立しているため、宣言だけして確認はしない、宣言していないが確認はする、宣言して確認もするの何れの組み合わせもできる。
そこでまずは確認できることを優先し、その後に宣言することにする。
ubuntu の標準リポジトリには、SPF の確認を行うためのパッケージが以下に挙げるように複数登録されている。
- postfix-policyd-spf-perl
- postfix-policyd-spf-python (または python-policyd-spf)
- spfmilter
- spf-milter-python
spfmilter は現時点では Sendmail 専用にパッケージングされている。/etc/init.d/spfmilter ファイル中で Sendmail パッケージに含まれる /usr/sbin/sendmail コマンドを前提にした実装がされている
spf-milter-python は、Postfix と連携させるための UNIX ソケットが root ユーザーに対してのみ書き込みが許可されている (読み込みは全てのユーザー / グループで可。)
この UNIX ソケットに対して、指定したグループに書き込みを許可したりするような、アクセス権の変更はできないようだ。
UNIX ソケットではなく INET ソケットを使うようにすればいいということは分かっている
しかし、なんとなくではあるが INET ソケットの使用を避けたいという思いもある。
こういった理由で結局は、postfix-policyd-spf-python を使うことにした。
Postfix への設定方法は /usr/share/doc/postfix-policyd-spf-python/README.Debian に書いて通りで、postfix の二つの設定ファイル、/etc/postfix/master.cf と /etc/postifx/main.cf のそれぞれに以下の数行を追加するだけだ。
1 2 |
policyd-spf unix - n n - 0 spawn user=nobody argv=/usr/bin/python /usr/bin/policyd-spf /etc/postfix-policyd-spf-python/policyd-spf.conf |
1 2 3 4 5 6 7 |
smtpd_recipient_restrictions = ... reject_unauth_destination ... check_policy_service unix:private/policyd-spf ... policyd-spf_time_limit = 3600 |
注意が必要なのは、/etc/postfix/main.cf ファイルの smtpd_recipient_restrictions エントリの各パラメーターを記載する順番だ。
postfix-policyd-spf-python のための check_policy_service unix:private/policyd-spf は、必ず reject_unauth_destination より後に指定しなければはならない。
これを reject_unauth_destination より前に書くと、reject_unauth_destination が有効に機能しない状況が生じてしまう。
つまり、SPF で検証できるサーバーにとっては、オープンリレー同様になるということだ。
これは決して望ましいこととは言えないので、smtpd_recipient_restrictions エントリの各パラメーターの記載順は十分に気を付けて欲しい。
後は、postfix-policyd-spf-python 自体の設定を調整して、postfix を再起動するだけだ。
postfix-policyd-spf-python の設定ファイルは /etc/postix-policyd-spf-python/policyd-spf.conf ファイルだ。
このファイルについては、インストール時のままで、特に変更する必要はないだろう。
1 2 3 4 5 6 7 8 9 10 11 12 |
# For a fully commented sample config file see policyd-spf.conf.commented debugLevel = 1 defaultSeedOnly = 1 HELO_reject = SPF_Not_Pass Mail_From_reject = Fail PermError_reject = False TempError_Defer = False skip_addresses = 127.0.0.0/8,::ffff:127.0.0.0//104,::1//128 |
ただし、SPF については以前の記事にも書いたように、サーバー更改のときなどにそれに合わせた SPF レコードの更新をし忘れている事例がいくつか見られる。
気がついたときにホワイトリストに追加して救済すると共に、サイトの管理者宛に SPF レコードの不備をメールで通達している。
メールで通達してから数日ないしはせいぜい数週間のうちには、こういった不備は改修されるが、「SPF を使うなら part3」で示したサイトに関してだけは、半年以上が経過しても一向に改修される気配がない。
これについては、オンライン ショップの広告メールだということもあり、受信できなくても全く困らないので放置してある。
このような SFP レコードの不備があるサイトからのメールを取りこぼしたくないときは、先に挙げた /etc/postfix/master.cf ファイルに Mail_From_reject = False (「SPF を使うなら part3」のような状況でも救済するなら更に HELO_reject = False) の行を追加すれば良いだろう。
以下は、postfix-policyd-spf-python の設定ファイルで指定できる全ての項目と、それに関するコメントをできる限り勝手訳したものだ。
オリジナルのファイルは
/usr/share/doc/postfix-policyd-spf-python/policyd-spf.conf.completed だ。
良く意味が分からず訳しきれなかった箇所は原文のままにしてある。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# デバッグ情報の量。 0 はデバッグ情報を記録せず、4 は全てのデバッグ情報を含む。 debugLevel = 1 # 0 に設定すれば、メッセージは SPF で拒否されません。 これによって、メールを拒否することなく、 # メールログをチェックして SPF による潜在的影響を確認できます。 defaultSeedOnly = 1 # HELO チェックによる拒否の方針。 オプションは、 # HELO_reject = SPF_Not_Pass (規定) - 結果が Pass/None/Tempfail でないときに拒否する # HELO_reject = Softfail - 結果が Softfail と Fail のときに拒否する # HELO_reject = Fail - HELO の結果が Fail のときに拒否する # HELO_reject = Null - Null 送信者による HELO の失敗だけを拒否する (旧形式の SPF) # HELO_reject = False - HELO では拒否したり遅延させたりせず、ヘッダーに追加するだけにする # HELO_reject = No_Check - HELO でのチェックをしない HELO_reject = SPF_Not_Pass # HELO を通過したときの制限の方針 # HELO_pass_restriction = helo_passed_spf - HELO チェックの結果が通過 (Pass) の時に # 与える制限。与える制限は Postfix SMTP サーバーの access テーブルの access (5) で定義 # されているアクション。 #HELO_pass_restriction # Mail From による拒否の方針。 オプションは、 # Mail_From_reject = SPF_Not_Pass - 結果が Pass/None/Tempfail でないときに拒否する # Mail_From_reject = Softfail - 結果が Softfail と Fail のときに拒否する # Mail_From_reject = Fail - Mail From Fail が Fail のときに拒否する (規定) # Mail_From_reject = False - Mail From では拒否したり遅延させたりせず、ヘッダーに追加する # だけにする # Mail_From_reject = No_Check - Mail From や Return Path でのチェックをしない Mail_From_reject = Fail # メールの送信をしないドメインからのメールの拒否。オプションは、 # No_Mail = False - 通常の SPF レコードの処理 (規定) # No_Mail = True - "v=spf1 -all" レコードだけを拒否 # Mail From を通過したときの制限の方針 # Mail_From_pass_restriction = mfrom_passed_spf - Mail From チェックの結果が通過 # (Pass) の時に与える制限。与える制限は Postfix SMTP サーバーの access テーブルの # access (5) で定義されているアクション。 #Mail_From_pass_restriction # これらのドメインで Netural/Softfail の結果の時にメールを拒否する。 # たとえ SPF レコードで Fail のときのみならず、SPF が Pass/None でさえなければ、特定のドメインか # らのメールを拒否する、レシーバーの方針のオプション。 このオプションは PermError_reject や # TempError_Defer の効果を変更しません。 #Reject_Not_Pass_Domains = aol.com,hotmail.com # SPF PermError による拒否の方針。オプションは、 # PermError_reject = True # PermError_reject = False PermError_reject = False # SPF TempError による遅延の方針。オプションは、 # TempError_Defer = True # TempError_Defer = False TempError_Defer = False # Prospective SPF checking - Check to see if mail sent from the defined IP # address would pass. # Prospective = 192.168.0.4 # ローカルホストのアドレスのためにチェックしない - もし良ければ、内部ネットワークのために SPF をスキップ # するアドレスを追加してください。規定は、標準的な IPv4 と IPv6 の localhost アドレスです。 skip_addresses = 127.0.0.0/8,::ffff:127.0.0.0//104,::1//128 # Whitelist: SPF のチェックをしない IP アドレスの CIDR 表記によるリスト # 例 (規定のホワイトリストは無し) # Whitelist = 192.168.0.0/31,192.168.1.12 # Domain_Whitelist: List of domains whose sending IPs (defined by passing # their SPF check should be whitelisted from SPF. # 例 (規定のドメイン ホワイトリストは無し): # Domain_Whitelist = pobox.com,trustedforwarder.org # Domain_Whitelist_PTR: List of domains to whitelist against SPF checks base # on PTR match. # 例 (規定の PTR ホワイトリストは無い # Domain_Whitelist_PTR = yahoo.com |