SPF(Sender Policy Framework)は、送信元メールアドレスのドメインが偽装されていないことを確認するための仕組みです。送信側のメールサーバのIPアドレスをSPFレコードとしてDNSサーバーに登録し、受信側のメールサーバでは、SPFレコードを参照して送信元のメールアドレスが偽装されていないことを検証します。そこで今回は、受信側のメールサーバとなる Postfix を pypolicyd-spf を使って、SPF検証に対応するための設定方法をまとめてみました。
SPF検証の仕組み
今回SPF検証の設定を行うのは、図の左上「受信側のメールサーバ」になります。受信側のメールサーバがSPF検証に対応すると、正規のメールサーバからメールが送られてきたタイミングで、送信元のメールアドレスのドメイン(図の例では「example.com」)を管理しているDNSサーバに、正規のメールサーバのIPアドレスを問い合わせることで検証を行います。
図の例では、正規のメールサーバのIPアドレス(192.0.2.1)は、ドメインを管理するDNSサーバに登録されているため「認証OK」になりますが、迷惑メール送信者のメールサーバのIPアドレス(192.0.2.99)は、登録されていないため「認証NG」となります。
参考資料:SPF(Sender Policy Framework) | 迷惑メール対策委員会
Postfix の設定
受信側のメールサーバの Postfix は、以下の手順で構築されている前提の手順になります。今回サーバOSは、AlmaLinux を利用していますが、Rocky Linux や CentOS Stream など RHEL系のディストリビューションであれば同じ手順で設定できると思います。
関連記事:SSLメールサーバ構築メモ Postfix + Dovecot【2023年版】
rootユーザの利用について
この記事では rootユーザで設定を行うことを前提にしていますので、以下コマンドで rootユーザになってから実施してください。
sudo -s
※通常の運用時は sudo <コマンド> を利用することをオススメします。
pypolicyd-spf のインストール
pypolicyd-spf のインストール元となる EPELリポジトリを登録します。
dnf config-manager --set-enabled crb dnf install epel-release dnf update
pypolicyd-spf をインストールします。
dnf install pypolicyd-spf
pypolicyd-spf の設定
説明付きの設定ファイルがありますので、設定ファイルをそちらと入れ換えます。
mv -i /etc/python-policyd-spf/policyd-spf.conf /etc/python-policyd-spf/policyd-spf.conf.org cp -ip /usr/share/doc/pypolicyd-spf/policyd-spf.conf.commented /etc/python-policyd-spf/policyd-spf.conf
今回は、受信したメールのヘッダにSPFの検証結果を追加するのみとして、メールを破棄しないように設定します。
vi /etc/python-policyd-spf/policyd-spf.conf
HELO_reject = Fail ↓ HELO_reject = False Mail_From_reject = Fail ↓ Mail_From_reject = False
設定方法の詳細は、設定ファイルのコメントをご確認ください。今回は、SPF検証の動作を確認するため最低限の設定にしていますが、ネットワークアドレスやドメイン単位で、SPF検証を除外することもできます。
Postfix と pypolicyd-spf の接続
メールの受信時に、pypolicyd-spf で SPF検証を行うように Postfix と pypolicyd-spf を接続します。
Postfix の基本設定は以下の記事をご参照ください。
関連記事:SSLメールサーバ構築メモ Postfix + Dovecot【2023年版】
master.cf に pypolicyd-spf をサービス名「policyd-spf」として登録します。
vi /etc/postfix/master.cf
---(下記を最終行に追加)---------------------------
# # ==================================================================== # # SPF検証設定 # policyd-spf unix - n n - 0 spawn user=nobody argv=/usr/libexec/postfix/policyd-spf
続いて main.cf の smtpd_recipient_restrictions ディレクティブの最後に青字の部分を追加します。
注意:必ず一番最後に追加してください!先頭に追加するとオープンリレーになります。
vi /etc/postfix/main.cf
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_destination
↓
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_destination
check_policy_service unix:private/policyd-spf
さらに main.cf の最終行に pypolicyd-spf のタイムアウトの設定を追加します。(単位は秒です)
vi /etc/postfix/main.cf
---(下記を最終行に追加)---------------------------
# # SPF検証設定 # policyd-spf_time_limit = 3600
設定に間違いがないことをチェックします。(なにも表示されなければOKです)
postfix check
Postfix を再起動します。
systemctl restart postfix
第三者中継(オープンリレー)チェック
Postfix の重要な部分の設定を変更していますので、以下のツールなどでオープンリレーになっていないことを必ず確認しましょう。
AppRiver SpamLab - Open Relay Test
SPF検証の動作確認
Gmailなど外部のメールサーバからメールを送信して、受信したメールのヘッダに、以下のようなSPF検証結果が追加されていればOKです。
Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=209.85.128.45; helo=mail-wm1-f45.google.com; envelope-from=xxx@gmail.com; receiver=<UNKNOWN>
以上で Postfix SPF検証設定は完了です。お疲れさまでした!!
コメント
[…] 参考1 参考2 […]
こんにちは。SPF導入において大変参考にさせて頂きました。
導入後のトラブルで、メールのヘッダが一部消えてしまう
(In-Reply-To, References)という現象が発生してしまったのですが
原因または解消方法に心当たりがありますでしょうか…?
導入したのは、pypolicyd-spf-1.3.2 で Postfix 2.6.6-6、RHEL6.3を使っています。
>MICKさん
コメントありがとうございます。
申し訳ありませんが、私の環境では、症状を確認できませんでした。
環境:pypolicyd-spf-1.3 Postfix 2.10.1 CentOS 7.2.1511 RHEL6系の記事なのに7を使っていてすみません(^^;)
確認方法:
1)自分のメールサーバからGmailへメールを送信
↓
2)Gmail側で 1)で送られてきたメールに対して返信
↓
3)2)で送られてきたメールヘッダを確認
もし確認方法など違っていましたら、またコメントください。
いつも参考にし、とても良いブログだと尊敬しております
master.cfにてpolicy-spfと定義してるので
main.cfをpolicy-spf_time_limitとしないとエラーが起きてしまいます
宜しくお願い致します
>ねこさん
ご指摘ありがとうございます!
記事の内容がかなり古くなっていますので、近いうちに修正したいと思います。