2020/12/07
postfix-policyd-spf-python はサポートが終わり py-spf-engine になった模様。
2016/04/02
ついにうちのドメインからのメールがはじかれたというので、DNSにSPFのレコード追加するついででこちらのPostfixもSPFで検証ができるようにした時の備忘録。
一番情報が見つけやすかったので postfix-policyd-spf-python を使用。
うちの環境は FreeBSD 10.2 RELEASE で、portsから導入。
cd /usr/ports/mail/postfix-policyd-spf-python; make; make install を実行。依存関係でエラー等あれば臨機応変に対応。
pkg info コマンドを叩くと、パッケージ名は py27-postfix-policyd-spf-python-1.3.2_1 になっていた。
root@amame:~ # root@amame:~ # pkg info |grep postfix-policyd-spf-python py27-postfix-policyd-spf-python-1.3.2_1 Pure Python Postfix policy daemon for SPF checking root@amame:~ #
portsでインストールした際のメッセージに書いてあるよ!
Installing py27-postfix-policyd-spf-python-1.3.2_1... # # To configure Postfix # This package must be integrated with Postfix to be effective: 1. Add to your postfix master.cf: policyd-spf unix - n n - 0 spawn user=nobody argv=/usr/local/bin/policyd-spf 2. Configure the Postfix policy service in your main.cf so that the "smtpd_recipient_restrictions" includes a call to the policyd-spf policy filter. If you already have a "smtpd_recipient_restrictions" line, you can add the "check_policy_service" command anywhere *after* the line which reads "reject_unauth_destination" (otherwise you're system can become an open relay). smtpd_recipient_restrictions = ... reject_unauth_destination check_policy_service unix:private/policyd-spf ... policyd-spf_time_limit = 3600 3. Please consult the postfix documentation for more information on these and other settings you may wish to have in the "smtpd_recipient_restrictions" configuration. 4. Reload postfix.
/usr/local/etc/postfix/master.cf の最後に以下を追記。
# ==================================================================== # policyd-spf unix - n n - 0 spawn user=nobody argv=/usr/local/bin/policyd-spf
注意として、3行目の行終端は空白やタブを書かない事。4行目は必ず空白かタブで始まる事。
/usr/local/etc/postfix/main.cf の最後に以下を追記。
# SPF smtpd_recipient_restrictions = reject_unauth_destination check_policy_service unix:private/policyd-spf policyd-spf_time_limit = 3600
すでに smtpd_recipient_restrictions を定義済みなら、その記述内に reject_unauth_destination と check_policy_service unix:private/policyd-spf をこの順序でマージする。
service postfix reload を実行して終了。
root@amame:~ # service postfix reload postfix: Postfix is running with backwards-compatible default settings postfix: See http://www.postfix.org/COMPATIBILITY_README.html for details postfix: To disable backwards compatibility use "postconf compatibility_level=2" and "postfix reload" postfix/postfix-script: refreshing the Postfix mail system root@amame:~ #
警告的なメッセージは、Postfix2.11.x を Postfix3.0.xにアップグレードしたせい。後方互換性をオフにしたければこのメッセージにあるコマンドを実行すればいい。
送信者のドメイン詐称でひっかかってリジェクトされたかな。
Apr 2 05:02:04 amame postfix/smtpd[6093]: connect from unknown[221.214.208.226] Apr 2 05:02:05 amame policyd-spf[6098]: ERROR: 127.0.0.0/8 in skip_addresses not IP network. Message: '221.214.208.226' does not appear to be an IPv4 or IPv6 address. Did you pass in a bytes (str in Python 2) instead of a unicode object?. Aborting whitelist processing. Apr 2 05:02:05 amame policyd-spf[6098]: None; identity=helo; client-ip=221.214.208.226; helo=133.242.191.153; envelope-from=zvjmhximzx@i.softbank.jp; receiver=iam@hgotoh.jp Apr 2 05:02:05 amame policyd-spf[6098]: Fail; identity=mailfrom; client-ip=221.214.208.226; helo=133.242.191.153; envelope-from=zvjmhximzx@i.softbank.jp; receiver=iam@hgotoh.jp Apr 2 05:02:05 amame postfix/smtpd[6093]: NOQUEUE: reject: RCPT from unknown[221.214.208.226]: 550 5.7.1 <iam@hgotoh.jp>: Recipient address rejected: Message rejected due to: SPF fail - not authorized. Please see http://www.openspf.net/Why?s=mfrom;id=zvjmhximzx@i.softbank.jp;ip=221.214.208.226;r=iam@hgotoh.jp; from=<zvjmhximzx@i.softbank.jp> to=<iam@hgotoh.jp> proto=SMTP helo=<133.242.191.153> Apr 2 05:02:05 amame postfix/smtpd[6093]: disconnect from unknown[221.214.208.226] helo=1 mail=1 rcpt=0/1 quit=1 commands=3/4 Apr 2 05:05:25 amame postfix/anvil[6095]: statistics: max connection rate 1/60s for (smtp:221.214.208.226) at Apr 2 05:02:04 Apr 2 05:05:25 amame postfix/anvil[6095]: statistics: max connection count 1 for (smtp:221.214.208.226) at Apr 2 05:02:04 Apr 2 05:05:25 amame postfix/anvil[6095]: statistics: max cache size 1 at Apr 2 05:02:04 Apr 2 05:05:37 amame postfix/smtpd[6101]: warning: hostname ool-6038827a.static.optonline.net does not resolve to address 96.56.130.122: hostname nor servname provided, or not known Apr 2 05:05:37 amame postfix/smtpd[6101]: connect from unknown[96.56.130.122] Apr 2 05:05:40 amame policyd-spf[6106]: ERROR: 127.0.0.0/8 in skip_addresses not IP network. Message: '96.56.130.122' does not appear to be an IPv4 or IPv6 address. Did you pass in a bytes (str in Python 2) instead of a unicode object?. Aborting whitelist processing. Apr 2 05:05:41 amame policyd-spf[6106]: None; identity=helo; client-ip=96.56.130.122; helo=138-0-131-188.dinamic.sertao.net; envelope-from=01y2nvx1vs@i.softbank.jp; receiver=oreda@hgotoh.jp Apr 2 05:05:41 amame policyd-spf[6106]: Fail; identity=mailfrom; client-ip=96.56.130.122; helo=138-0-131-188.dinamic.sertao.net; envelope-from=01y2nvx1vs@i.softbank.jp; receiver=oreda@hgotoh.jp Apr 2 05:05:41 amame postfix/smtpd[6101]: NOQUEUE: reject: RCPT from unknown[96.56.130.122]: 550 5.7.1 <oreda@hgotoh.jp>: Recipient address rejected: Message rejected due to: SPF fail - not authorized. Please see http://www.openspf.net/Why?s=mfrom;id=01y2nvx1vs@i.softbank.jp;ip=96.56.130.122;r=oreda@hgotoh.jp; from=<01y2nvx1vs@i.softbank.jp> to=<oreda@hgotoh.jp> proto=SMTP helo=<138-0-131-188.dinamic.sertao.net> Apr 2 05:05:42 amame postfix/smtpd[6101]: disconnect from unknown[96.56.130.122] helo=1 mail=1 rcpt=0/1 quit=1 commands=3/4 A
221.214.208.226はチャイナですか。96.56.130.122はモバイル系のインターネット接続業者?のお客さんかな。
root@amame:~ # drill -x 221.214.208.226 ;; ->>HEADER<<- opcode: QUERY, rcode: NXDOMAIN, id: 1287 ;; flags: qr rd ra ; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0 ;; QUESTION SECTION: ;; 226.208.214.221.in-addr.arpa. IN PTR ;; ANSWER SECTION: ;; AUTHORITY SECTION: 214.221.in-addr.arpa. 1673 IN SOA ns.sdjnptt.net.cn. root.ns.sdjnptt.net.cn. 100213 28800 7200 604800 86400 ;; ADDITIONAL SECTION: ;; Query time: 0 msec ;; SERVER: 210.224.163.4 ;; WHEN: Sat Apr 2 15:26:42 2016 ;; MSG SIZE rcvd: 104 root@amame:~ # drill -x 96.56.130.122 ;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 24783 ;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;; 122.130.56.96.in-addr.arpa. IN PTR ;; ANSWER SECTION: 122.130.56.96.in-addr.arpa. 964 IN PTR ool-6038827a.static.optonline.net. ;; AUTHORITY SECTION: ;; ADDITIONAL SECTION: ;; Query time: 0 msec ;; SERVER: 210.224.163.3 ;; WHEN: Sat Apr 2 15:28:04 2016 ;; MSG SIZE rcvd: 91 root@amame:~ #
気になるエラーが出ている。
Apr 2 05:02:05 amame policyd-spf[6098]: ERROR: 127.0.0.0/8 in skip_addresses not IP network. Message: '221.214.208.226' does not appear to be an IPv4 or IPv6 address. Did you pass in a bytes (str in Python 2) instead of a unicode object?. Aborting whitelist processing.
情報は https://forums.freebsd.org/threads/54568/ や https://bugzilla.redhat.com/show_bug.cgi?id=1232595 で見つかって、要約すると、
policyd-spfは実行時に py-ipaddressパッケージのインポートを試し、これに失敗すると py-ipaddrパッケージをインポートするんだ。 これはpy-ipaddressパッケージがあればpython3.xの環境だと判断しているせい。困った事に。 そして更に困ったことにpy-ipaddressパッケージにはバグがある。policyd-spfを使うならpy-ipaddrパッケージ固定で使う方がいい。
py-ipaddress と py-ipaddr が同居していると先のエラーが出力される。
py-ipaddress がなくて py-ipaddr がある環境だと先のエラーが出ないことを確認した。
対処方法としては /usr/local/bin/policyd-spf を書き換えてしまうのが一番早い。
2行を入れ替えるだけだがエラーは起きずに動作している。
オリジナル | 修正後 |
---|---|
try: import ipaddress except ImportError: import ipaddr as ipaddress | try: import ipaddr as ipaddress except ImportError: import ipaddress |