curl は PAC ファイルを読めない:代わりにプロキシを渡す
PAC は JavaScript のポリシーであり、curl が求めるのはエンドポイントです。ポリシーが URL に選ぶプロキシを聞き、それを渡し、NO_PROXY と TLS に注意してください。
設定ファイルの中では、PAC ファイルのアドレスとプロキシのエンドポイントは同じように見えますが、実際は別物です。一方は URL ごとに評価する必要があるポリシープログラムで、もう一方は接続を受け付けるホストとポートです。curl が理解するのは後者だけです。PAC のアドレスを --proxy に渡すのはカテゴリーの誤りで、多くの場合ウェブサーバーへの長い CONNECT タイムアウトの末に、分かりにくい形で失敗します。
それぞれの正体
| 手元にあるもの | それが何か | curl がそれで何をするか |
|---|---|---|
http://wpad.corp.example/proxy.pac | 特定の URL に対してプロキシまたは直接接続を返す JavaScript | ファイルとして取得し、そこで止まる |
http://proxy.corp.example:8080 | プロキシ経由のリクエストを受け付けるリスナー | それを使う。HTTPS の宛先には CONNECT も含む |
この点について curl の FAQ は次のように明言しています。curl は JavaScript も PAC も解釈しません。PAC を理解するラッパーを curl の周りに置けば可能ですが、curl 自体はできず、どんなフラグでもブラウザーにはなりません。
ブラウザーは動くのに curl は動かない理由
ブラウザーはシステムのプロキシ設定と統合され、PAC ファイルを取得して、開こうとしている URL に対してそのルールを実行します。その評価こそが PAC ファイルの提供するサービスであり、ブラウザーの内部で行われます。ターミナルの中で行われるのではありません。
curl で PAC ファイルをダウンロードしても、手に入るのはそのテキストだけです。curl がポリシーを実行するわけではなく、プロキシを探すために手で読むのは同じ評価の手作業版で、誤った分岐を選ぶ可能性も同じです。読む場合は、ファイル内の最初のプロキシ名ではなく、自分のホストに合う return 文を読んでください。ほとんどの PAC ファイルには複数のプロキシが含まれ、自分に当てはまる分岐は一つだけです。
承認済みの HTTP プロキシと承認済みの HTTPS サービスを使う場合、例示的なリクエストは次のとおりです。
curl --proxy http://proxy.corp.example:8080 https://service.example.net/status
最初のアドレスがプロキシのリスナー、二つ目が目的のサービスです。これは例示用のエンドポイントであり、誰かが実施したテストではないため、組織のスキーム、ポート、認証の流れに置き換えてください。
この宛先に合うプロキシを選ぶ
管理者には、組織がどのプロキシを持っているかではなく、ポリシーが必要な URL に対してどのプロキシを選ぶかを尋ねてください。PAC のルールは内部サービス、公開サイト、フェイルオーバーの状況で異なる結果を返すことがあり、今日の URL に一致するルールも、編集後には別の URL に一致する可能性があります。
ワークフローが複数の既知のリクエストを必要とするなら、管理者がサポートする静的設定か、承認済みの PAC 対応連携を使ってください。コピーした一つのアドレスをハードコードするのは、ポリシーが変わり、そのアドレスを選んだ理由を誰も覚えていない日までしか持ちません。
次に、curl が何を引き継ぐかを見ます。プロキシの環境変数と NO_PROXY は、渡したプロキシを上書きしたり除外したりでき、宛先に一致する除外はリクエストを黙って直接送ります。すべての除外を消したり、すべてを一つのアドレスに押し込んだりせず、意図したポリシーを保ってください。リクエストを一度 -v を付けて実行し、実際にどのアドレスへ接続したかを確認します。
二つの TLS の身元を混同しない
HTTPS プロキシでは TLS 接続が二つ関与します。一つは自分からプロキシへ、もう一つはプロキシから宛先へ。それぞれに検証すべき身元があり、どちらかの検証を切ることは PAC の修正ではなく、最初の問題に二つ目を足すことになります。
検証は有効なままにして、返ってきた失敗を読んでください。プロキシの認証要求、到達できないプロキシ、ウェブサイトからの拒否は三つの異なる結果で、認証情報に関わるのは最初の一つだけです。VPN は、これらいずれかが成功する前に、プロキシ自体の名前解決を含め、プライベートなプロキシへの許可された経路を提供している必要があります。
エンドポイント、スキーム、ポート、認証方式、除外、そしてプロキシまでの VPN 経路を書き留めてください。その記録が次のリクエストを再現可能にし、自分のプロキシを知ることと推測することの差になります。