証明書ベースの VPN ログインが Mac に求めるのは、パスワードよりずっと狭い範囲だ:この実行コンテキストで、この特定の秘密鍵を使って、そのゲートウェイに対して身元を証明すること。失敗したとき、表示されるメッセージはふつう最後に起きたことだけを述べており、それが原因であることはまれだ。システムが判断する順番どおりに三つの決定をたどれば、診断は誠実なまま保たれ、ローカルの権限の問題が証明書チェーンの検証失敗として扱われることもなくなる。

Mac と同じ順番でログインをたどる

まずクライアントが身元を選ぶ:使える秘密鍵と対になった証明書、サポートされているストアまたは認証情報プロバイダー経由で利用できる。次に VPN コンポーネントがその鍵で暗号処理を行うよう要求し、ローカルの認可モデルが応答する。両方が成功してはじめて、リモートのハンドシェイクが行われ、そこで Mac がゲートウェイを評価し、ゲートウェイがクライアントの証明を評価する。

DecisionTypical symptomWhere to look
Identity selectionNo valid identity, wrong certificate offeredProfile and which identity the client picked
Local key useSigning or interaction error before any handshakeExecution context and key access rules
Remote authenticationChain, name or client-admission rejectionGateway identity and what it accepts

表を上から下へ読み、最初に失敗する行で止まる。失敗より下の行はすべて未証明であり、「証明書が信頼されていない」という結論がこれほど一般的で、これほど当てにならないのはそのためだ。

ローカルの権限が実際に覆う範囲

macOS のキーチェーンのモデルでは、保護された項目は操作ごとのアクセスルールと信頼済みアプリケーションの一覧を持つ。秘密鍵による署名もその操作の一つであり、ルールが適用されるのはそれを実行する実行ファイルであって、文書としての証明書ではない。Apple のアクセス制御のリファレンスは、このモデルと iCloud キーチェーンおよびアクセスグループの仕組みとの間にも線を引いており、片方に向けて書かれた助言がもう片方に移ることはない。

そこから二つの帰結が導かれる。一覧に公開証明書が見えることは、VPN のバックグラウンドコンポーネントがその鍵にそもそも到達できる証拠にはならない。そしてフロントエンドのアプリケーションに与えられた権限は、別のヘルパーやネットワーク拡張については何も語らない、なぜなら別のコードであり、別の身元だからだ。

古いクライアントから実行ファイルのパスを写すのではなく、実際の実装と、それがサポートする認証情報共有の仕組みを特定する。まず、システムがそもそもどの身元を提示するのかを確認する:

security find-identity -v -p ssl-client

errSecInteractionNotAllowed を読む

このステータスは Security Server とのやり取りが許可されなかったことを報告するもので、証明書チェーンについては何も述べていない。それを生んだ操作と合わせて読む:プロンプトを出せないコンテキストから発行された署名要求は、鍵と証明書のどちらも完全に有効であっても、この形で失敗する。始めるべきは、それを記録した操作であり、証明書ストアではない。信頼のアンカーについて何を変えても、エラーはまったく同じ場所にとどまる。

だからこのコードは、実行コンテキストと認可を調べる理由として扱う。ゲートウェイの CA が信頼されていない証拠として扱えば、問題の誤った半分へ送られることになり、そこで加えた変更はエラーにまったく影響しない。

狭く直し、広く直さない

まず接続の所有者による登録またはインポートの手順から始める。クライアントのバージョン、プロファイルの範囲、選ばれた身元、最初の関連するローカルエラーを記録する:この四つの事実がサポートへの引き継ぎに必要であり、後日の比較もこれに依存する。管理対象のプロファイルやハードウェアに支えられた身元では、管理者やプロバイダーが引き継ぎを修理する必要があるかもしれず、ローカルでいくらクリックしても代わりにはならない。

製品がユーザーの承認を期待する場面では、どのコンポーネントが求めているのかを確認し、サポートされている流れでそのアクセスだけを承認する。コンポーネントが動作するコンテキストでプロンプトを出せない場合、プロビジョニングはベンダーが文書化した経路に従うべきであり、別のターミナルウィンドウから引き出したダイアログではない。

古い助言では二つの変更がひとまとめにされるが、どちらも広すぎる。すべてのアプリケーションに秘密鍵へのアクセスを与えると、ローカルの鍵の使用は要件をはるかに超えて広がり、証明書を Always Trust に設定すると、マシン上のすべてについて証明書の評価が変わる。どちらも「この承認された VPN 実装が、この意図された身元を使って」を表現していない。

ゲートウェイを読む前にローカルで確かめる

修理のあとは、ローカルの操作が成功することを確かめ、反対側からの応答を解釈する前に。署名が今うまくいけば、そのあとで名前・チェーン・クライアント受け入れの拒否が出たとしても、それは再発ではなく新しい結果であり、別の担当者が持つ別の決定に属する。

役に立つ引き継ぎは、三つの決定のどれが失敗したのかを名指しし、そこで止まる。秘密鍵を含めることは決してなく、きれいな状態になれば助かるという期待で無関係なキーチェーンの項目をリセットすることも決してない。その二つの習慣は、何もかも一度に試したくなる誘惑が最も強い事件の最中ではなく、事件の前に決めておく。「キーチェーンを作り直した」と書かれたチケットは、元の不具合について次の読み手にほとんど何も伝えない。

関連記事