SPF の検証に SPF Engine を使う。ついでに DMARC と ARC も。

Linux/UNIX
この記事は約13分で読めます。
スポンサーリンク

はじめに

 2022/08/23 よりドコモがドコモメールのドメイン認証技術に DKIM と DMARC を採用するというお話しがあった。
 報道発表資料の PDF はこちら

 そう言えば自宅サーバー (CentOS 7) の MTA は DKIM までやっているけど DMARC は放置だったなと。
 加えて SPF 検証に使っている Perl スクリプトが 2003 年リリースの非常に古い物だったから新しい物に入れ替えようと作業を始めることになった。

 今回は SPF Engine と ARC に関して触れる。

DKIM はググって設定済だが手順が多いし、DMARC はかんたんだけど他サイトにお任せという丸投げで。

SPF, DKIM, DMARC, ARC

 SPF (Send Policy Framework) は送信されてきたメールが DNS の SPF レコードに記載されている IP アドレスから送信されている事を確認し、正しい経路で配送されているかを判断する事ができる技術。
 hoge@example.jp というアドレスからのメールが全く無関係の mx.example.cn から送信されていたら取り敢えずあやしいですよね。ってお話し。
 もちろんドメインが異なるメールサーバーから送信されていても SPF レコードに登録されていれば「これは正しいメールです」なんて事にもなるので便利。

 さらに DKIM (DomainKeys Identified Mail) はメールサーバーが送信するメールに「たしかにうちが送信した」という電子署名を行うことでなりすましを防ぎつつも、メール内容の改竄が行われていないかのチェックまで行える。

 DMARC (Domain-based Message Authentication, Reporting, and Conformance) は SPF と DKIM の両方を利用して各々の検証で失敗した際のふるまいを DNS のリソースレコードを用いて公開するしろもの。
 エンドユーザーに対するものというよりは運用上、あれば便利という技術になる。

 ARC (Authenticated Received Chain) はメーリングリストなどで複数経由したメールサーバーそれぞれで電子署名を行うことで、大元のメールがなりすましや内容の改竄をされずにエンドポイントまで正しく配送されているかの判断を出来るようにする技術。
 SPF レコードや DKIM のチェックが及ばない部分で検証が出来る。

 迷惑メールではない、なりすまされていない、改竄されていない。ということを受信者側で容易に判断できる材料としてはこれだけあれば現状は良いのかなと思われる。
 逆に迷惑メール業者がこれら技術を利用しても、SPF レコードに示されたホストやネットワークレンジ、DKIM で署名したホストなんかをブラックリストに入れれば受信することもなくなるのでメリットがないはず。

SPF の設定をする

 今までは 2003 年リリースの postfix-policyd-spf という Perl スクリプトを使用してきたので、これを新たに SPF Engine に置き換える。
 postfix-policyd-spf 自体は後継に postfix-policyd-spf-perl という物があり、更に Python スクリプトの postfix-policyd-spf-python がある。
 それの更に後継が SPF Engine という立ち位置になる。日本語の情報がなくて苦労したから備忘録として書きたかったのがこれ

SPF Engine のダウンロード

SPF Engine in Launchpad

 上記サイトよりソースをダウンロードしてくる。(2022/08/28 現在の最新バージョンは 2.9.3)
 作業は基本的に同梱されている README を読みながら行う。
 必要環境としては Python 3.3 以上、pyspf 2.0.9 以上が必要。その他依存関係のあるライブラリが諸々。

SPF Engine のインストールと設定

 SPF Engine 自体のインストールは簡単。

wget https://launchpad.net/spf-engine/2.9/2.9.3/+download/spf-engine-2.9.3.tar.gz
tar xzf spf-engine-2.9.3.tar.gz
cd spf-engine-2.9.3
sudo python3 setup.py install --single-version-externally-managed --record=/dev/null

 CentOS 7 のパッケージがある物は優先してインストールした。

sudo yum install python36-dns python36-pymilter python-ipaddress python-dns python3-authres

 pip で必要なライブラリなどをインストールする。

sudo pip install dkimpy_milter

 今回は使わないけど dkimpy_milter を入れようとすると依存関係で自動的にインストールされるライブラリが SPF Engine でも必要とされる物と大体同じなので楽出来る。
 dkimpy_milter の依存ライブラリとしては authres, dkimpy, dnspython, pydkim, pymilter, PyNaCl, pyspf が入る。
 加えて不足している ipaddress もインストールした。

 その他何かインストール漏れがあるかも知れないので、エラーが出たらログを見て対処する。

 動作に必要のユーザー作成も行う。
 README では Debian での手順だが、うちは CentOS 7 なので書いてあることから必要そうな所だけ抜粋してコマンドを打ち込んだ。
 また、手順には記載されていないが、既存の postfix ユーザーを今回作成する pyspf-milter ユーザーのグループに入れておく必要がある。

sudo useradd --no-create-home --shell /sbin/nologin --home /run/pyspf-milter pyspf-milter
sudo usermod -G postfix,pyspf-milter postfix
sudo chown -R pyspf-milter:pyspf-milter /run/pyspf-milter

 pyspf-milter.conf の作成。
 困ったのがこの設定ファイル。サンプルもないしデフォルトでは存在しない。
 systemd の Unit ファイルには “man:pyspf-milter.conf(5)” と書かれているけど、そもそもそんなマニュアルファイルは無い。

 そこで Ubuntu 用パッケージ pyspf-milter_2.9.2-1_all.deb を拾ってきて中身を展開することで pyspf-milter.conf の書き方が分かってきた。
 そんな苦労しながら書いたのがこれ。
 Postfix が pyspf-milter.sock を用いて通信を行う為、先述のグループ追加をしておかないとパーミッションエラーを起こすので注意。

Authserv_Id = mx.example.com # MTA のホスト名にする
Socket = local:/run/pyspf-milter/pyspf-milter.sock
PidFile = /run/pyspf-milter/pyspf-milter.pid
UserID = pyspf-milter
InternalHosts = 127.0.0.1
Hide_Receiver = Yes
MacroList       daemon_name|VERIFYING

## vim:ft=conf :

 尚、パラメータに関しては “man 5 policyd-spf.conf” の内容にだいたい同じだったという……

 つぎに systemd の Unit ファイルの設定。

sudo systemctl daemon-reload
sudo systemctl enable --now pyspf-milter
sudo systemctl status pyspf-milter

 pyspf-milter の状態を確認し、エラーが出ているようなら syslog でも覗いて対応する。

OpenARC のインストールと設定

 インストールは yum で楽々。

sudo yum install openarc

 設定ファイル /etc/openarc.conf を次のように設定した。

PidFile /var/run/openarc/openarc.pid
Syslog  yes
UserID  openarc:openarc
Socket  inet:8894@localhost

Canonicalization        relaxed/relaxed
AuthservID              mx.example.com # MTA のホスト名
Domain                  example.com   # MTA のドメイン名
Selector                20220826      # DKIM 用に作った鍵のセレクター
Mode                    sv
KeyFile                 /etc/openarc/20220826.private
SignatureAlgorithm rsa-sha256

 署名に使う秘密鍵は DKIM 設定時に作成した物をそのままコピーしてきて使用した。

 そしてこれも自動起動など有効化して起動確認をしておく

sudo systemctl enable --now openarc.service
sudo systemctl status openarc.service

Postfix の設定

 /etc/postfix/{main,master}.cf のバックアップを取っておく。

 以下の通り、main.cfsmtpd_miltersunix:/run/pyspf-milter/pyspf-milter.sock を追加する。
 ちなみに inet:127.0.0.1:8891 は OpenDKIM、inet:127.0.0.1:8893 が OpenDMARC、inet:127.0.0.1:8894 を OpenARC で使用している。
 ソケット通信がアレなら 8892 あたりで pyspf-milter を動かせば穴が埋まって良いのかも。
 また、上記 OpenARC の設定も行っているのであれば inet:127.0.0.1:8894 も追加しておこう。

# for OpenDKIM and OpenDMARC
milter_default_action = accept
non_smtpd_milters     = $smtpd_milters
smtpd_milters         = inet:127.0.0.1:8891, inet:127.0.0.1:8893, inet:127.0.0.1:8894, unix:/run/pyspf-milter/pyspf-milter.sock

 つぎに master.cf の設定も変更。
 一番上にある smtp の部分に -o milter_macro_daemon_name=VERIFYING を追加する。

smtp      inet  n       -       n       -       -       smtpd
...
...
  -o milter_macro_daemon_name=VERIFYING
...
...

 設定を適用する。

sudo postfix reload
sudo systemctl status postfix

動作確認をする。

 お手軽なテストは Gmail 宛にメールを送ること。
 SPF, DKIM, DMARC, ARC の検証が行われているので、メールヘッダを見ると分かりやすい。

 今回設定した MTA から Gmail に送ったメールのヘッダの順序を保ったまま抜粋した物が以下のもの。

 流れとしては

  1. 自 MTA で DKIM により署名
  2. OpenDMARC は素通り
  3. OpenARC により署名
  4. Google 側の MTA にて DKIM, ARC, SPF, DMARC の検証が入り、全部 pass

 といった感じになっている。

 自宅サーバーの MTA で行った DKIM と ARC の署名は正しく行われており、検証も相手側により正しいとされている。

ARC-Authentication-Results: i=2; mx.google.com;
       dkim=pass header.i=@bp7.org header.s=20220826 header.b=GnVScNO5;
       arc=pass (i=1);
       spf=pass (google.com: domain of xxxx @bp7.org designates 202.238.198.240 as permitted sender) smtp.mailfrom= xxxx @bp7.org;
       dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=bp7.org
Received-SPF: pass (google.com: domain of  xxxx @bp7.org designates 202.238.198.240 as permitted sender) client-ip=202.238.198.240;
Authentication-Results: mx.google.com;
       dkim=pass header.i=@bp7.org header.s=20220826 header.b=GnVScNO5;
       arc=pass (i=1);
       spf=pass (google.com: domain of  xxxx @bp7.org designates 202.238.198.240 as permitted sender) smtp.mailfrom= xxxx @bp7.org;
       dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=bp7.org
ARC-Seal:i=1; a=rsa-sha256; d=bp7.org; s=20220826; t=1661679111; cv=none;
    b=KvjyG0Mt6hzwRjgbZi7AZfRGFj0T5g58c3SycPUYsNjZxMi2w5X7TS4gWsrhPKUPYMq506Z1tf33aN2LGTJK7hzOfUYerDTIuwT68npLoR+EeTWMfBtl00Yoidaq0xMkJqCJbU26xHlUKZoFvCjr5q+IzvcBFCYF2cMdqtfZzTg=
ARC-Message-Signature:i=1; a=rsa-sha256; d=bp7.org; s=20220826;
    t=1661679111; c=relaxed/relaxed;
    bh=Mt0JNd3Iya1CctERpikypmyWflI0sScUFe8PKlCTCXI=;
    h=DMARC-Filter:DKIM-Filter:DKIM-Signature:Message-ID:Date:
     MIME-Version:User-Agent:From:Subject:To:Content-Language:
     Content-Type:Content-Transfer-Encoding; b=NIR5pPNIQcHKZ9HmzZktezp6M5IO8DSZG1XhEyBOuW6dYZ94Q1xF7sWyczIzjAmMj/pLISD7cK4pEJ67ESFsgihJdvrJfXLM9gcuIrn/GkHzBR1+AHEwwIllUbIIz/wAajPSuUdRwlHI6nAw8q8u5vJkDh1qnEQJGats8n/Z59Q=
ARC-Authentication-Results:i=1; mx.bp7.org; dmarc=none (p=none dis=none) header.from=bp7.org; arc=none smtp.client-ip=192.168.1.10
DMARC-Filter: OpenDMARC Filter v1.4.1 mx.bp7.org ECB2518E826
DKIM-Filter: OpenDKIM Filter v2.11.0 mx.bp7.org ECB2518E826
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bp7.org; s=20220826;
    t=1661679111; bh=Mt0JNd3Iya1CctERpikypmyWflI0sScUFe8PKlCTCXI=;
    h=Date:From:Subject:To:From;
    b=GnVScNO55lH3L6G7SqD7ZjifMDDkRascTPAEoRL9t7qWNEbZ7ylvI7H8O1Il3bpnG
(snip..

おわりに

 MTA の設定に大きく手を入れたのは 7 年ぶり。
 これでなんとか今風の動作になったのかなーと思われる。
 メール周りは面白い。

スポンサーリンク
著者プロフィール
ぶっち

本格的に PC へ触れ始めてたのは 1990 年位から。
興味は PC 全般。OS は Windows と Linux などを嗜む。
プログラマやネットワークエンジニアを経てフリーに活動している 2 児の父なアラフォーのおじさんです。

ぶっちをフォローする
ぶっちろぐ

コメント

タイトルとURLをコピーしました