policyd-spf

メール受信時にPostfixでSPF検査を行う為のスクリプト。
設定変更が出来ないPerl版と、細かい変更が可能なPython版の2種類がある。
Postfixで使う時はポリシーチェックとしてスクリプトを呼び出す。

構築環境

今回検証した環境はこちら

  • debian 9.5 x86_64
  • CentOS 7.5 x86_64
  • openSUSE 42.3 x86_64



設定ファイル・スクリプト本体がディストリビューション毎に違うが、
設定と説明を統一化する為、同ファイル名のシンボリックリンクを作成する。
シンボリックリンクを作りたく無い時は、実ファイルPATHを直設定する。

構築

1. インストール
インストールはディストリビューションによってパッケージ名に違いがある。
今回はパッケージ管理を利用してインストールするので各々の環境にあわせる。

  • Debian
    # apt-get install postfix-policyd-spf-python
    # ln -s /etc/postfix-policyd-spf-python/policyd-spf.conf /etc/policyd-spf.conf
    # ln -s /usr/local/bin/policyd-spf /usr/bin/policyd-spf
  • CentOS
    # yum install pypolicyd-spf
    # ln -s /etc/python-policyd-spf/policyd-spf.conf /etc/policyd-spf.conf
    # ln -s /usr/libexec/postfix/policyd-spf /usr/local/bin/policyd-spf
  • openSUSE
    # zypper install python-policyd-spf
    # ln -s /etc/python-policyd-spf/policyd-spf.conf /etc/policyd-spf.conf
    # ln -s /usr/libexec/postfix/policyd-spf /usr/local/bin/policyd-spf

 
SPFレコードをAR形式(Authentication-Resultsヘッダ)で追加する場合、python-authresモジュールが必要となる。
ただし、Python2環境ではモジュールが用意されていないので自力でrpmを作成してインストールする。

 インストール手順
 
2. 設定
policyd-spfは受信側の処理となる為、DNSのtxtレコード設定については割愛。
ドキュメントはDebianの公開している物を確認する。
[01] debugLevel       = 1
[02] Header_Type      = SPF
[03] #Authserv_Id     = mx.test.org
[04] HELO_reject      = False
[05] Mail_From_reject = False
[06] PermError_reject = False
[07] TempError_Defer  = False
[08] skip_addresses   = 127.0.0.0/8,::ffff:127.0.0.0/104,::1
[09] Whitelist        = 192.168.0.1
[10] Domain_Whitelist = mail.test.org

--------------------------------------------------

[01] 出力ログレベル。1(最低限)~5(デバッグログ)を設定出来る
[02] SPFのヘッダ形式。SPFは"Received-SPF"、ARは"Authentication-Results"
[03] ヘッダ形式にARを設定した時にヘッダ識別子として使用する
[04] HELOコマンドのSPF評価方針。ヘッダ付与のみ行い拒否しない時は"False"を設定
[05] MAIL FROMコマンドのSPF評価方針。ヘッダ付与のみ行い拒否しない時は"False"を設定
[06] SPF PermErrorの拒否方針。Falseを設定すると無効となる
[07] SPF TempErrorの遅延方針。Falseを設定すると無効となる
[08] SPF評価を無効化するIPアドレス。ローカルホストなど不変な物を設定
[09] SPF評価を無効化するIPアドレス。ドメイン内の他MXサーバなどユーザ毎に変わる値を設定
[10] SPF評価を無効化するドメイン。アスタリスクレコードは利用不可


3. master.cf
policyd-spfを呼び出す為、Postfixのmaster.cfを書き換える。
今回はポリシーとして呼び出す為、下記設定を最終行に追記する。
# SPF Check
policy-spf  unix    -    n    n    -    0    spawn
    user=nobody argv=/usr/local/bin/policyd-spf /etc/policyd-spf.conf

 
上の設定でSPFチェックが出来ない場合、argvの中でPythonがスクリプトを直接実行する様に書き換える。
この時、ディストリビューションによってはPythonのバージョン毎にPATHが変わるので注意する。
利用するPythonのバージョンは実スクリプトの1行目を読んで判断する。

# SPF Check
policy-spf  unix    -    n    n    -    0    spawn
    user=nobody argv=/usr/bin/python2 /usr/local/bin/policyd-spf /etc/policyd-spf.conf



4. main.cf
master.cfに追加したpolicy-spfを呼び出す為、check_policy_serviceを追加する。
この時、設定は下記の様に "reject_unauth_destination" の後に追加する。
前に設定すると、check_policy_serviceで処理したメールが全て許可となり、MTAがオープンリレー化する。

smtpd_recipient_restrictions =
     permit_mynetworks,
     reject_unauth_destination,
     check_policy_service unix:private/policy-spf

 
追加した "policy-spf" はmaster.cfに追加したポリシー名と同じにする。
また、デフォルト状態では1,000秒程でポリシープロセスがkillされてしまう為、
下記設定も追加してプロセスのkill間隔を調整する。

# PROC Kill
policy-spf_time_limit = 3600s


確認

実際に外部のメールサーバからメールを送信し、SPFヘッダが追加されるか確認する。
下記は実際に外部からメールを送信し、ヘッダ付与テストを行った結果となる。

Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=59.135.**.**; helo=ezweb.ne.jp; envelope-from=*****@ezweb.ne.jp; receiver=*****@***.***.***