指定した URL に関係なく curl が localhost に接続しようとするなら、VPN は出発点として適切ではありません。ローカルの HTTP または SOCKS プロキシが意図された最初の接続である可能性があり、求めるサービスがまったく別の場所にある場合でも同じです。そのプロキシがもう動いていなければ、curl が宛先に届く前に localhost への試行は失敗します。プロキシからの応答も、宛先が応答した証拠にはなりません。

次の手順を順に進め、最初の接続試行が変わる最初の段階で止めてください。

まず curl 自身のプロキシ規則を確認する

curl はプロトコル固有のプロキシ変数を読みます。たとえば https_proxy や HTTPS_PROXY、そしてプロトコル固有の値が当てはまらない場合は ALL_PROXY です。curl を実際に起動しているシェル、サービス、タスクの環境を調べ、現在の端末の環境を見ないでください。CI ジョブ、systemd ユニット、対話シェルはそれぞれ別の集合を継承していることがあります。目に見えるシェルから推測することが、この調査で半日を無駄にする原因です。

覚えておく価値のある例外が一つあります。curl は http_proxy を小文字でのみ受け付け、大文字の HTTP_PROXY は無視されます。だから同じ環境でも他のツールでは挙動が異なります。

値は人目に触れない形で読み取ってください。プロキシの URL はしばしば認証情報を含みます。

次に curl の既定の設定ファイルにプロキシや接続の上書きがないか確認し、実際にどの実行ファイルを動かしているのかを確かめます。シェルの別名、関数、ラッパースクリプトは、コマンドラインには決して現れないオプションを追加することがあります。

TLS を有効にしたまま三つの呼び出しを比較する

三回の実行すべてで、承認された診断用の宛先と同一のバイナリを使ってください。

curl -v https://service.corp.example/status
curl -q -v https://service.corp.example/status
curl -q --proxy '' -v https://service.corp.example/status

-q は既定の curlrc を抑止し、機能させるには行の最初のパラメータである必要があります。プロキシの環境変数は取り除きません。そこを期待する人が戸惑う点です。三つ目の形式は空の --proxy 値を加え、その呼び出しに限って環境が要求したプロキシを上書きします。最終的なステータスコードではなく、各出力の最初の接続試行を比較してください。

詳細出力はヘッダー、トークン、プロキシの認証情報を露出しうるので、ローカルに保持し、共有する前に抜粋を読んでください。

各結果が何を排除するか

既定の設定を省くことで接続が変わるなら、原因は設定ファイルです。継承されたプロキシを明示的に無効にすると変わるなら、原因は環境変数です。どちらでも変わらず localhost が現れるなら、コマンドラインの接続上書き、ホスト名の解決、選択された実行ファイルを調べてください。それぞれ修正方法は異なり、いずれもルーティングの変更ではありません。

独自ライブラリの読み込みや注入されたネットワーク挙動は後の層であり、環境変数だけではその証拠になりません。

プロキシの判断は VPN と切り離しておく

curl が直接の宛先を選んだ後も、オペレーティングシステムはその接続を経路制御します。アプリケーションのプロキシを無効にしても、VPN の経路やフィルタリングポリシーは無効になりません。直接アクセスの比較は、その診断が許可されている場所でのみ行ってください。ポリシーを静かに迂回する試験は有効な結果ではなく、インシデントです。

ローカルのプロキシが必要なら、設定を削除するのではなく、そのサービスとアドレスを復旧してください。

選択した非公開の宛先だけに直接アクセスが必要なら、狭く承認された除外を追加し、それ以外はすべてプロキシのままにします。選んだ経路の最初のエラーを保存してください。localhost の拒否、プロキシの CONNECT 拒否、証明書の失敗、認可エラーは四つの異なる段階を示します。

関連記事