【OpenARC検証事例】MS (i=1) → 転送 (Postfix+OpenARC、i=2) → Gmail で arc=pass
電子メールの送信元ドメインが詐称されていないかを検証する送信ドメイン認証 (Sender Domain Authentication)。
2024年のGmailのメール送信者向けのルール強化に関連し、先日、たまたま当サイトにARC (Authenticated Received Chain) に関するお問い合わせをいただく機会がありました。
お問い合わせとその後続のやり取りの内容を要約すると、”MS (i=1) → 転送 (Postfix+OpenARC、i=2) → Gmail で arc=pass” にするための対処です (詳しくは記事内で説明します)。
本記事は、お問い合わせいただいた方 (以降、Aさん) に、この件を記事化させていただく旨をお伝えした上で、その内容をまとめたものです。
環境が一致していなくても、何かしら参考にされる方がいらっしゃるかもしれないという前提で、技術情報の辿り方の一例として、OpenARCの開発状況や、RFCの関連部分を調べたときの経過をなるべく細かく含めています。
SPF、DKIM、DMARC、ARC、BIMIといった送信ドメイン認証のまとめ記事はこちらです。
前提
送信ドメイン認証に関するまとめ記事、ARCに関する記事、そして2024年のメール送信者向けのルール強化に関する記事は以下です。
なお、本記事の作成時点で、ARC の RFC8617 は Experimental なので、最終的にどのような仕様になるか、またどのような実装が普及するか、という点は分かりません。
本記事で扱うメール配送パターン、構成
本記事では、以下のメール配送パターンについて説明します。
1. [MS] からメール送信 → 2. [自システム] で転送 → 3. [Gmail] で受信
- Microsoft 関連メールサービス (以下、[MS]) から自システムにメールが送信される (ARC署名: i=1)
- そのメールが Postfix + OpenARC の [自システム] で Gmail に転送される (ARC検証&署名: i=2)
- そのメールが [Gmail] にて ARC 検証される
使用している OpenARC は、Aさんのお話によると、当初は GitHub のソース、OpenARC-master.zip (0.1.0 2017/12/06 Initial pre-release.) を利用していましたが、対処の過程で、EPEL で配布されている SRPM (後述) の中からソースを取り出してコンパイルしたものになりました。
OpenARC
OpenARC は arc-spec.orgでも紹介されている ARC 実装の一つで、Cライブラリあるいは Milter として使用することができます。今回の構成のように、Postfix と組み合わせることができます。設定方法は OpenDKIM と似ています。
注意点として、GitHub上のソースが古いままであり、未完了の Issue や PR も多いという点が挙げられます (リソース状況等の事情もあるようで)。
RPM 版も公開されており、EPEL で RHEL9 系向け (openarc-1.0.0-0.15.Beta3.el9.src.rpm) や RHEL8 系向け (openarc-1.0.0-0.15.Beta3.el8.src.rpm) のものが配布されています。これらは上記GitHubのソース (たぶんrel-openarc-1-0-0-Beta3) をベースに、EPEL (Fedora) 側での RPM 作成に際し、いくつかの修正が加えられているようです (記事の最後で補足します)。
ということで、何の心配もなくそのまま本番運用できるソフトウェアとは言いづらいです。
This package is intended for use by operators willing to take part in the experiment and provide their feedback to the development team.
出典:GitHub – trusteddomainproject/OpenARC: Open source ARC implementation
本記事作成時点では、ソース版よりRPM版の方が、より多くの修正が適用されている状況かと思います。
対処が必要となった事象 (トラブル)
以下、2件の事象とその対処について説明します。
- [MS] から届いたメールの ARC 検証失敗
[MS] から届いたメールに対し、[自システム] の OpenARC で ARC 検証すると arc=fail (signature failed) となる - [自システム] で ARC 署名したメールの ARC 検証失敗
1つ目の事象を解決後、[自システム] の OpenARC で ARC 署名したメールが [Gmail] で arc=fail となる
それぞれ説明します。
なお、正確に確認はしていませんが、おそらく上記の事象1,2のいずれも、最新のRPM版を使用した場合には発生しないものであったと思われます。
事象1: [MS] から届いたメールの ARC 検証失敗
[MS] から届いたメールに対し、[自システム] の OpenARC で ARC 検証すると arc=fail (signature failed) となる、という事象です。
- 原因
-
- OpenARC の ARC-Seal (AS) ヘッダの署名検証において、RFC 上は必須でない t タグを必須のものとして扱う動作になっていた
具体的には、ARC-Seal ヘッダの t タグは、ARCのRFCから参照先のDKIMのRFC を辿ると “RECOMMENDED” と記載されており必須ではないのですが (ちなみに h タグは “REQUIRED” で必須)、GitHub 上の OpenARC ではこの t タグを必須のものとして検証する動作になっています。結果、ASヘッダの署名検証が失敗し、arc=fail となります。
Microsoft からのメールに付与されている ARC 署名においては、AS ヘッダに t タグが無いようで、今回の事象が発生しました。
- 対処
-
今回の環境は、GitHubから取得したOpenARCのソースをコンパイルしたものなので、libopenarc/arc.c の該当箇所を修正して再コンパイル、再インストール (make install) したところ、t タグが無い [MS] からのメールの ARC 署名検証に成功 (arc=pass) したそうです。
arc.c の修正内容は、以下の赤字部分の削除です。
/* these have no defaults */ case ARC_KVSETTYPE_SEAL: /* make sure required stuff is here */ if (arc_param_get(set, (u_char *) "cv") == NULL || arc_param_get(set, (u_char *) "i") == NULL || arc_param_get(set, (u_char *) "b") == NULL || arc_param_get(set, (u_char *) "s") == NULL || arc_param_get(set, (u_char *) "d") == NULL || arc_param_get(set, (u_char *) "a") == NULL || arc_param_get(set, (u_char *) "t") == NULL) { arc_error(msg, "missing parameter(s) in %s data", settype); set->set_bad = TRUE; return ARC_STAT_SYNTAX; }
- 補足
-
上記の対処を終えた旨のご連絡をAさんからいただいた後に気付いたのですが、GitHub上で、2019年に同じ問題に対する修正 (PR) までは出ていたようです。
また、RPM版の方には 1.0.0-0.13.Beta3 でこの PR が取り込まれているようです (記事の最後で補足します)。
ちなみに、Microsoft からのメールは送信時点で ARC 署名が付与されているという点が (私の認識としては) 特徴的ですが、AS ヘッダに t タグが無いという点も、頭の片隅の端っこくらいに置いておいても良いかも知れません。
事象2: [自システム] で ARC 署名したメールの ARC 検証失敗
1つ目の事象を解決後、[自システム] の OpenARC で ARC 署名したメールが [Gmail] で arc=fail となる、という事象です。
- 原因
-
- 原因の特定には至らず
具体的な原因は特定できていませんが、対処は以下のとおりです。詳細は後述の “補足” もご覧ください。
- 対処
-
後述の “補足” の RPM 版に関する情報を参考に、以下の対処を行ったところ、 [Gmail] で ARC 署名検証に成功 (arc=pass) したそうです。
https://packages.fedoraproject.org/pkgs/openarc/openarc/ より openarc-1.0.0-0.15.Beta3.el8.src.rpm を入手し src.rpm より下記を取出し、 openarc-1.0.0.Beta3.tar.gz openarc-headerdebug.patch autoreconf -fvi; ./configure; make; make install
のように対処されたそうです。
ただし、src.rpmにおいても、事象1 の “t タグ必須” のコードが残っていたようで、これは削除されたとのことです (記事の最後で補足します)。
arc_param_get(set, (u_char *) "a") == NULL || arc_param_get(set, (u_char *) "t") == NULL)
- 補足
-
この事象2については、Aさんのお話によると、”openarc.conf の
SignHeaders
でSign対象とするHeaderを指定しているにも関わらず、ARC header i=1 で到着したメールのARC-Message-Signature:のh=のHeaderを対象に、sign/seal して i=2 として転送送出してしまう”、また、”元々ARC headerの無いメールは openarc.conf / SignHeaders指定のHeaderが対象” になるとのことでした。気になって、以前私が RHEL8系 + RPM版Postfix + RPM版 OpenARC の環境で試した際のメモを確認してみたところ、Aさんからお知らせ頂いたような “署名対象を引き継ぐ” 動作でなく、SignHeadersに従って署名していたようです。
ただし、SignHeadersで指定したヘッダであっても、署名対象のメッセージに存在しないものは “h=” タグに記載されない動作かと思います (おそらく必要に応じ OversignHeaders で補完する感じで、DKIMの仕様 (RFC 6376の5.4あたり) を考慮した動作だと理解しています)。上記と、前述の対処結果から、GitHubのソースとRPM版との間で、この事象の発生有無に関する何らかの差異があるのかもしれませんが、その詳細については未確認です。
事象1,2のまとめ
以上が、今回の事象1,2の対処内容です。
正確に確認はしていませんが、おそらく上記の事象1,2のいずれも、最新のRPM版を使用した場合には発生しないものであったと思われます。
アップストリーム側 (GitHub上のソース) の方がより多くの修正が反映されているケースもあると思いますが、今回は、RPM版の方がより多くの修正が反映されていたものと理解しています。
RPM版OpenARCに加えられている修正についての補足
本記事の作成時点で、RPM 版のOpenARCの最新版は 1.0.0-0.15.Beta3 です。
このバージョンの OpenARC を例に、RPM版固有で加えられている修正について補足しておきます。
例えば、事象1に対処するPR 121は、1.0.0-0.13.Beta3 で反映されていることがchangelogから確認できます。
* Tue May 24 2022 Matt Domsch mdomsch@fedoraproject.org – 1.0.0-0.13.Beta3
– Add upstream PR 121 to fix Office 365 signature validation
– Use systemd service type=simple to avoid PID file race
出典:Tree – rpms/openarc – src.fedoraproject.org
RPMのソース (src.rpm) の中では、ベースとなる rel-openarc-1-0-0-Beta3 はGitHub上のソースのままのはずで、RPM固有の修正コードは別ファイルの 0001-Remove-t-from-the-list-of-required-AS-tags.patch にあり、RPMをビルドする際に反映されるようになっていると理解しています。
(参考) RPMのソース内のopenarc.specから、changelogを抜粋した内容
%changelog
* Sun Oct 2 2022 Matt Domsch<mdomsch@fedoraproject.org> - 1.0.0-0.15.Beta3
- Remove PidFile from config as systemd doesn't need it
- Remove ReadWritePaths from systemd as it's not needed
* Mon Sep 5 2022 Matt Domsch<mdomsch@fedoraproject.org> - 1.0.0-0.14.Beta3
- Add Restart=on-failure to systemd service file
- add postun to restart on upgrade
* Fri Jul 22 2022 Fedora Release Engineering <releng@fedoraproject.org>
- 1.0.0-0.13.Beta3.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Tue May 24 2022 Matt Domsch <mdomsch@fedoraproject.org> - 1.0.0-0.13.Beta3
- Add upstream PR 121 to fix Office 365 signature validation
- Use systemd service type=simple to avoid PID file race
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org>
- 1.0.0-0.11.Beta3.5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Tue Sep 14 2021 Sahana Prasad <sahana@redhat.com> - 1.0.0-0.11.Beta3.4
- Rebuilt with OpenSSL 3.0.0
* Thu Jul 22 2021 Fedora Release Engineering <releng@fedoraproject.org>
- 1.0.0-0.11.Beta3.3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org>
- 1.0.0-0.11.Beta3.2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org>
- 1.0.0-0.11.Beta3.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Mon May 18 2020 Matt Domsch <mdomsch@fedoraproject.org> - 1.0.0-0.11.Beta3
- set selinux labels on /run/openarc
- restore selinux labels at service start
* Fri May 15 2020 Matt Domsch <mdomsch@fedoraproject.org> - 1.0.0-0.10.Beta3
- add headerdebug patch
* Fri May 1 2020 Matt Domsch <mdomsch@fedoraproject.org> - 1.0.0-0.9.Beta3
- fix typo in systemd service file
- use RuntimeDirectory and RuntimeDirectoryMode when systemd 211 or
higher is present
rather than tmpfiles.d.
- use ReadWritePaths to ensure our temp directory is writable with
ProtectSystem=strict
* Tue Apr 21 2020 Matt Domsch <mdomsch@fedoraproject.org> - 1.0.0-0.8.Beta3
- packaging suggestions from
https://github.com/trusteddomainproject/OpenARC/pull/103#issuecomment-574367733
- use systemd service ProtectHome and ProtectSystem
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org>
- 1.0.0-0.7.Beta3.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Mon Dec 2 2019 Tim Landscheidt <tim@tim-landscheidt.de> - 1.0.0-0.7.Beta3
- Remove obsolete requirement for %%postun scriptlet
* Mon Dec 2 2019 Matt Domsch <mdomsch@fedoraproject.org> - 1.0.0-0.6.Beta3
- Upstream beta3
- Add dependency on janusson-devel, needed for new SealHeaderChecks
config option
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org>
- 1.0.0-0.5.Beta2.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Mon Feb 11 2019 Matt Domsch <matt@domsch.com - 1.0.0-0.1.Beta2
- Upstream beta2, drop merged patch
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org>
- 1.0.0-0.1.Beta1.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Fri Sep 28 2018 Matt Domsch <matt@domsch.com> 1.0.0-0.1.Beta1
- Upstream beta1
* Sat Sep 22 2018 Matt Domsch <matt@domsch.com> 1.0.0-0.4.Beta0
- fix ownership of openarc.conf and PeerList files
* Sat Sep 22 2018 Matt Domsch <matt@domsch.com> 1.0.0-0.3.Beta0
- replace header generation patch with upstream fix
- apply specfile fixes from
https://github.com/trusteddomainproject/OpenARC/pull/103
* Mon Sep 10 2018 Matt Domsch <matt@domsch.com> 1.0.0-0.2.Beta0
- Own /etc/openarc/
- improve default config file, add default PeerList config
* Wed Jul 11 2018 Xavier Bachelot <xavier@bachelot.org> 1.0.0-0.1.Beta0
- Specfile clean up.
- Update to 1.0.0 beta 0.
* Sun Jul 23 2017 Matt Domsch <matt@domsch.com> 0.1.0-1
- update to Fedora Packaging Guidelines
まとめ
本記事では、たまたま当サイトにARC (Authenticated Received Chain) に関するお問い合わせをいただく機会があった際に、”MS (i=1) → 転送 (Postfix+OpenARC、i=2) → Gmail で arc=pass” にするための対処に関するやり取りをまとめてみました。