Firefox 52以降でのルート証明書の自動インポート機能でできること、できないこと - 2017-06-01 - ククログ

ククログ

株式会社クリアコード > ククログ > Firefox 52以降でのルート証明書の自動インポート機能でできること、できないこと

Firefox 52以降でのルート証明書の自動インポート機能でできること、できないこと

Firefox ESR52以降のバージョンでは、隠し設定のsecurity.enterprise_roots.enabledtrueに設定することで、Windowsの証明書ストアに登録されたルート証明書をFirefox側で認識して使えるようになりました。

ただ、この機能の背景や使い方についてユーザー側の期待と実際の挙動との間に若干の齟齬が見られるため、ここで改めて状況を整理してみます。

この機能を有効にすると、以下の事を実現できます。

  • 組織内ネットワークに設置したSSLプロキシやSSLロガーの使用に必要な専用のルート証明書をFirefoxで認識させる。
  • 組織内ネットワークで運用しているサーバーの証明書専用のルート証明書をFirefoxで認識させる。

それに対し、以下のことは依然としてできません

  • Windowsの証明書ストアに元から含まれている証明書、例えば政府認証基盤のルート証明書をFirefoxで認識させる。 (「Firefoxでは日本の官公庁関係のWebサイトの一部が証明書エラーで見られない」という問題を解消する。)
  • 管理者でないユーザーがWindowsの証明書ストアに追加した証明書をFirefoxでも認識させる。

何故こうなっているのかは、機能の背景を知ることで理解できます。

この機能の導入経緯

上記の設定が導入されたBugを見ると、これは「エンタープライズでFirefoxを使いやすくする」という文脈に基づく機能だということが読み取れます。

「エンタープライズ」とは、従業員規模が千人や万人といった単位に達するような大規模な組織での使用ということです。このような規模の組織では組織内専用のルート証明書が必要になる事がままあり、それをFirefoxで使うためには証明書のインポート機能を提供するアドオンを使うか、集中管理の仕組みの実装の裏をかいて強引にインポートさせるかしかありませんでした。ところが、現在Firefoxは古い基盤技術からの脱却を進めているため、これらの裏技的なやり方は早晩使えなくなる見込みが立っています。そこで、裏技ではなくきちんとした正当な機能としてルート証明書をインポートする方法を設ける必要があった、というのがこれらのBugの背景にある事情です。

実際の動作

「Windowsの証明書ストア」は、実際にはそれ専用のデータベースがあるわけではありません。Windowsのレジストリ内には以下のようなレジストリキーの配下に証明書の情報が分散して格納されており、それらをマージして一覧表示した物を「証明書ストア」として見せているということになります。

  • HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates
  • HKEY_LOCAL_MACHINE\Software\Microsoft\SystemCertificates
  • HKEY_LOCAL_MACHINE\Software\Microsoft\EnterpriseCertificates
  • HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SystemCertificates

エンタープライズ運用における「ルート証明書の追加」とは、Active Directoryなどを使って、これらの中で特に以下の位置に証明書を登録する事を指しています。

  • HKEY_LOCAL_MACHINE\Software\Microsoft\SystemCertificates\Root\Certificates
  • HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SystemCertificates\Root\Certificates
  • HKEY_LOCAL_MACHINE\Software\Microsoft\EnterpriseCertificates\Root\Certificates

このことから、Firefoxは前述の隠し設定が有効な場合、起動時に上記のレジストリキー配下を走査して、追加された証明書があればそれらをインポートするという設計となっています。

ただし、この機能によってインポートされた証明書は、Firefox自身の証明書ストアに永続的に保存されるわけではありません。複数のレジストリキーをマージした結果がWindowsの証明書ストアとして扱われるのと同様に、Firefoxでも「Firefox自身の元々の証明書ストアの内容」+「この機能によって認識されたWindowsの証明書ストア内の証明書」が、実際の認証処理における証明書ストアとして使われるという形となります。(そのため、不要になった証明書はWindowsの証明書ストアから削除するだけで、Firefoxからも認識されなくなります。Firefoxの証明書マネージャで証明書を削除する、という事をする必要はありません。)

動作確認の方法

この機能でインポートされた証明書はFirefoxの証明書マネージャには表示されないため、期待通りに証明書がインポートされているかどうかは、別の方法で確認する必要があります。

Firefox 78以降のバージョンの場合(2021年8月17日追記)

Firefoxのエラーコンソールでスクリプトを実行できる状態で、以下のスクリプトを実行することにより、エンタープライズの証明書としてインポートされた証明書の一覧を見る事ができます。

{
  const enterpriseRoots = Components.classes['@mozilla.org/psm;1'].getService(Components.interfaces.nsINSSComponent).getEnterpriseRoots();
  const certDB = Components.classes['@mozilla.org/security/x509certdb;1'].getService(Components.interfaces.nsIX509CertDB);
  console.log(enterpriseRoots.map(certDer => certDB.constructX509(certDer).commonName).join('\n'));
}

古いバージョンのFirefoxの場合

上記の方法が使えないバージョンでは、デバッグ用の詳細なログを見て判断する必要があります。

MCD用設定ファイルを使う場合には、例えば以下のようにします。

// 証明書のインポート機能を有効化する設定
lockPref('security.enterprise_roots.enabled', true);

// NSS(Firefoxのセキュリティモジュール)のログを出力するための設定
lockPref("logging.pipnss", 5);
lockPref("logging.config.LOG_FILE", "C:\\Users\\Public\\certlog.txt");
lockPref("logging.config.add_timestamp", true);
lockPref("logging.config.clear_on_startup", false);
lockPref("logging.config.sync", true);

この設定を反映した上で、実験用のダミーの証明書をHKEY_LOCAL_MACHINE\Software\Microsoft\EnterpriseCertificates\Root\Certificates配下に加えるレジストリファイルを使って「example.com」という名前の証明書をインポートした状態でFirefoxを起動すると、C:\Users\Public\certlog.txtに出力されたログに以下のような箇所が含まれるようになります。

...
2017-05-09 10:21:23.017000 UTC - [Main Thread]: D/pipnss certificate is trust anchor for TLS server auth
2017-05-09 10:21:23.017000 UTC - [Main Thread]: D/pipnss Imported 'example.com'
2017-05-09 10:21:23.017000 UTC - [Main Thread]: D/pipnss imported 1 roots
...

このD/pipnss Imported '(証明書の一般名)'というログが出ていれば、その証明書はFirefoxから見えています。逆に、そのようなログが現れていない場合、証明書は無視されているということになります。

(2021年8月17日追記)Firefoxのバージョンによっては、D/pipnss Imported '(証明書の一般名)'というログが出ず、インポートされた証明書の総数のみが出力される場合があります。その場合、確認の必要がある証明書がWindowsの証明書データベース内にある時と無い時での総数の変化から、インポートに成功しているかどうかを判断する必要があります。

ユーザーが自分で操作してWindowsの証明書ストアにインポートした証明書をFirefoxが認識しない理由

Windowsでルート証明書のファイルをダウンロードしてダブルクリックすると、その証明書を証明書ストアにインポートすることができます。しかし、この方法でインポートされた証明書は上記のFirefoxの機能では認識されません。何故でしょうか。

これは、証明書が保存されるレジストリ上の位置に理由があります。この方法で手動でインポートした証明書は、HKEY_CURRENT_USER配下の以下の位置に保存されます。

  • HKEY_CURRENT_USER\Software\Microsoft\SystemCertificates

それに対し、Firefoxの証明書インポート機能はHKEY_LOCAL_MACHINE配下の以下のキーのみを走査します。エンタープライズ向けの機能としてはそれで正解で、個々のユーザーがWindowsの証明書ストアに追加した物まで認識するのはお門違いだからです。

  • HKEY_LOCAL_MACHINE\Software\Microsoft\SystemCertificates\Root\Certificates
  • HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\SystemCertificates\Root\Certificates
  • HKEY_LOCAL_MACHINE\Software\Microsoft\EnterpriseCertificates\Root\Certificates

政府認証基盤の証明書など、「Firefoxの証明書ストアには無いがWindowsの証明書ストアには含まれている」証明書がインポートされない理由と、その対処

2017年6月1日現在、政府認証基盤(GPKI)のルート証明書はFirefoxの証明書ストアには含まれていません。要望は上がっているのですが、政府側の対応がMozillaの定めるルート証明書の登録基準を満たしていないために作業が滞っているという状態です。

Windowsの証明書ストアには政府認証基盤の証明書も含まれているため、「Windowsの証明書ストアのルート証明書をFirefoxでインポートできるようになったのなら、政府認証基盤の証明書もインポートされて、証明書のエラーに悩まされることもなくなるのでは?」と期待される方もいらっしゃることでしょう。

ですが残念ながら、この機能では政府認証基盤のルート証明書はインポートされません。これは、Firefoxの証明書インポート機能の処理対象があくまで「管理者によってWindowsの証明書ストアに追加された証明書」に限られているからです。

Bugzilla上のコメント等で度々言及されていますが、Mozillaはユーザーの安全を守るために、どのルート証明書を登録するかを独自に判断しており、他社の判断を鵜呑みにはしないというポリシーで証明書ストアを管理しています。FirefoxがWindowsの全ての証明書を無条件で信頼してしまっていては、このポリシーが無意味になり、ユーザーの安全やプライバシーを保護するための判断を全てMicrosoftに委ねることになってしまいます。ですので、Mozillaとしてはあくまでユーザー(エンタープライズの文脈では、組織のシステム管理者)により追加された証明書のみをインポート対象にするというのが、この機能の趣旨となっています。

なお、以上のような趣旨のため、政府認証基盤(GPKI)のルート証明書を改めて「システム管理者が追加した証明書」としてWindowsの証明書ストアに登録すれば、これはFirefoxのインポート対象となります。

まとめ

以上、Firefox 52以降で使えるWindowsの証明書ストアからのルート証明書のインポート機能について、詳細と検証手順をご案内しました。

弊社で取り扱うFirefoxの導入・サポート案件においても、ルート証明書のインポートについては度々ご相談を頂いています。ニーズの高い機能でありながら今まで対応が進んでこなかったのには、アドオンや裏技的な方法で強引に解決してしまえるからという言い訳が立っていたからという側面は否定できないでしょう。従来からあるアドオンが切り捨てられるという方針の転換には批判の声も多く挙がっていますが、本体で対応される事が望ましい機能が本来あるべき形で実装されるきっかけとなったという事で、ここは素直に喜んでおきたいところです。

ちなみに、Firefox 52の段階ではこの機能はWindows限定の物となっています。macOSやLinuxでは設定を有効化しても効果を得られませんのでご注意下さい。