画像やリンクが無効になっている可能性もあるのでご了承下さい。
はじめに
2022/08/23 よりドコモがドコモメールのドメイン認証技術に DKIM と DMARC を採用するというお話しがあった。
報道発表資料の PDF はこちら
そう言えば自宅サーバー (CentOS 7) の MTA は DKIM までやっているけど DMARC は放置だったなと。
加えて SPF 検証に使っている Perl スクリプトが 2003 年リリースの非常に古い物だったから新しい物に入れ替えようと作業を始めることになった。
今回は SPF Engine と ARC に関して触れる。
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 のダウンロード
上記サイトよりソースをダウンロードしてくる。(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 の設定
以下の通り、main.cf
の smtpd_milters
に unix:/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 に送ったメールのヘッダの順序を保ったまま抜粋した物が以下のもの。
流れとしては
- 自 MTA で DKIM により署名
- OpenDMARC は素通り
- OpenARC により署名
- 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 年ぶり。
これでなんとか今風の動作になったのかなーと思われる。
メール周りは面白い。
コメント