企業 VPN プロキシの内側で起きる 407:npm、Maven、VS Code
407 はレジストリの停止ではなく、プロキシが資格情報を求めているという合図です。npm、Maven、VS Code、コンテナを設定し、社内ホストは除外します。
ブラウザで社内ページが開いても、それはブラウザに対してプロキシが機能している証明にすぎず、npm や Maven に対しても機能する証明にはなりません。クライアントはそれぞれ独自の設定を読み込むうえ、VPN だけのネットワークでは、そもそもクライアントがプロキシに到達できるのかという第二の問いが加わります。まずステータスコードを確認し、次に失敗したツールの設定の連鎖をたどってください。あるクライアントは動作し、隣のクライアントは失敗するのは、そのためです。
407 が実際に証明していること
407 Proxy Authentication Required を返すのはレジストリやリポジトリではなく、プロキシです。クライアントはプロキシに到達しており、プロキシがそのリクエストを拒否するのは、通常は資格情報の欠落や形式の誤り、あるいはその宛先では受け付けられないためです。
タイムアウトは別の話を物語ります。プロキシのアドレスが誤っているか、トンネル確立前にプロキシへの経路がないか、社内ホストに対するバイパス設定が欠けている可能性があります。資格情報を変更する前に、まずエラーの文言を読んでください。
プロキシのホスト、ポート、認証方式、そしてユーザー名にドメインの接頭辞が必要かどうかを確認します。次に、失敗しているツールがその値をファイルから読むのか、環境変数から読むのか、その両方から読むのかを調べます。ドメイン修飾付きのユーザー名は 407 のよくある原因です。誤ったエンコーディングで保存されたパスワードも同じです。
npm は独自の設定の連鎖を読む
npm はユーザーまたはプロジェクトの .npmrc で proxy と https-proxy のキーを受け付けます。値は URL なのでスキームを含め、パスワード内の予約文字は、アットマークで値が分割されないよう URL エンコードしてください。
proxy=http://proxy.example.com:8080
https-proxy=http://proxy.example.com:8080
strict-ssl=true
npm config list を使うと、有効な各値がどのファイルから供給されたかを確認できます。npm_config_proxy のようなシェルの export はファイルの設定を上書きでき、個人のパスワードを含むプロジェクト直下の .npmrc は決してコミットしてはいけません。値だけでなく、供給元のパスも表示してください。
strict-ssl は有効のままにしてください。TLS を検査するプロキシでは、企業 CA をトラストストアに登録する必要がある場合があり、エラーを回避するために検証を無効にすると、本来の信頼の問題が隠れてしまいます。
Maven はプロキシとミラーを分けて扱う
Maven はプロキシとミラーをプロジェクトの pom ではなく、ユーザーの設定ファイルから読み込みます。ネットワーク固有のプロキシと社内リポジトリのミラーは ~/.m2/settings.xml に置き、公開リポジトリの宣言は本来の場所であるプロジェクト側に残してください。
proxy ブロックには id、active フラグ、プロトコル、ホストとポート、そして社内リポジトリ用の nonProxyHosts の項目が必要です。これらのフィールドはプロジェクトの pom ではなくユーザーの設定ファイルに置き、ネットワークの変更がチーム全体のビルドを書き換えないようにします。ミラーの項目は別物で、Maven の参照先を社内リポジトリに向けるものです。
社内リポジトリを nonProxyHosts に追加すると、Maven はそこへ直接接続します。この項目がないとプロキシが不要な中継点となり、障害はリポジトリの停止のように見えます。ミラーの項目は社内リポジトリを指すものであり、プロキシ設定の代わりにはなりません。
複数のネットワークを行き来する開発者は、ネットワークごとに設定ファイルを一つ用意し、シェルの起動時に適切なものを選ぶ運用ができます。移動のたびに一つのファイルを手で書き換えると、動いていたノート PC がサポート依頼の種になります。
VS Code と開発コンテナでは名前空間が異なる
VS Code はユーザー設定またはワークスペース設定から http.proxy を、スキームとポートも含めて読み込みます。これが対象とするのはエディタ自身の拡張機能とマーケットプレイスのリクエストであり、ターミナルやエディタから起動したコンテナが自動的に設定されるわけではありません。値だけでなく、設定のスコープも確認してください。ワークスペース設定は、あるプロジェクトに限ってユーザー設定を上書きできます。
開発コンテナは独自のネットワーク名前空間を持ちます。ホストのプロキシ変数やホストの VPN ルートは継承されないため、コンテナ内でマーケットプレイスの呼び出しが失敗するのに、同じ呼び出しがホスト上では成功することがあります。
コンテナにそれらの変数を与えるか、コンテナ専用のリゾルバとルートを与えてください。コンテナ内で名前は解決できるのにプロキシが応答しない場合、足りないのは通常アドレスではなく経路です。
バイパスリストと環境変数の優先順位
VPN ゲートウェイ、社内レジストリ、プライベート DNS のサフィックスをバイパスリストに追加します。トンネルが確立する前にクライアントがプロキシ経由で VPN ゲートウェイへ到達しようとすると、接続はプロキシ障害のように失敗します。そのバイパスはトンネルを切断した状態で検証してください。
環境変数とファイルの内容は食い違うことがあります。シェルではなくツール自身の設定ダンプを実行し、報告される値を比較してください。重複した小文字の変数、親シェルに残った古い値、プロジェクトのファイルは、いずれも今編集した設定より優先される可能性があります。
CI ではプロキシをシークレット変数として渡し、同じイメージ内でパッケージを一つ導入するテストを行ってください。コンテナ内での 407 は、ホストのシェルにはあるのにコンテナにはその変数がないだけ、ということがよくあります。
ツールごとに、プロキシのホスト、ポート、バイパスのサフィックス、そしてそれらを供給するファイルや変数を記録してください。あるクライアントが 407 を返し別のクライアントが動作するとき、その記録があれば四つの異なる設定の比較が短い確認で済みます。