プロキシ自動設定

プロキシ自動設定ファイルは、ウェブブラウザやその他のユーザーエージェントが、与えられたURLを取得するための適切なプロキシサーバを自動選択する方法を定義する。 PACファイルにはJavaScriptの関数“FindProxyForURL”が書かれている。この関数は一つあるいは複数のアクセスメソッド指定を含む文字列を返す。これらの指定によりユーザーエージェントは特定のプロキシサーバを使って接続するか、または直接に接続する。

アクセスメソッドを複数指定しておくことにより、一つのプロキシが反応しない場合のフォールバックを提供できる。ブラウザは他のURLにリクエストを送る前に、このPACファイルを取得する。PACファイルのURLは手動で設定しておくか、あるいはWeb Proxy Auto-Discovery Protocolにより自動的に決定される。

1. プロキシ設定手法の概要
--------------

現代的なウェブブラウザはいくつかのレベルの自動化を実装している。ユーザは必要に応じてそのレベルを選ぶことができる。一般的に次のレベルが実装される：

自動プロキシ選択：全てのURLに対して用いられるホスト名とポート番号を指定する。多くのブラウザは、このプロキシを通さないで繋ぐドメインのリストを指定することを許容している
プロキシ自動設定 ：各URLに対する適切なプロキシを決定するためのJavaScript関数を記述したPACファイルのURLを指定する。この手法は幾つかの異なるプロキシ設定を必要とする小型携帯端末のユーザ、あるいは法人組織の中で多くの異なるプロキシを使った複雑な設定を必要とするユーザに適している。
Web Proxy Auto-Discovery Protocol ：DHCPおよびDNSルックアップを通じて、ブラウザにPACファイルの場所を探させる。

2. プロキシ設定
---------

コンピュータがインターネット通信をするためには、 オペレーティングシステム に多くの設定をする必要がある。これらの設定はインターネットサービスプロバイダから与えられるのが普通である。ネットワークに接続するためには匿名あるいは実際の設定のいずれかを使うことができる。

3. PAC ファイル
-----------

プロキシ自動設定ファイルは、1996年にNetscape Navigator 2.0 のためにNetscapeによって最初に設計され、それは最低限一つのJavaScript関数FindProxyForURLを定義したテキストファイルであった。この関数の二つの引数の意味は：urlが目的のURLで、hostがそのURLから得られるホスト名である。慣例として、PACファイルの名前はproxy.pacとする。WPAD標準はwpad.datを使う。

PACファイルを使うには、まずPACファイルをHTTPサーバに公開しておき、クライアントのユーザーエージェントは、ブラウザのプロキシ接続設定にPACファイルのURLを入力しておくか、またはWPADプロトコルを通じてのいずれかにより、そのPACファイルを使うよう指示される。

多くのクライアントは、完全性のために、また互換性を高めるために、HTTPリプライで返されたMIMEタイプが何であれ、PACファイルのスクリプトを処理するが、HTTPサーバはPACファイルのMIMEタイプとしてapplication/x-ns-proxy-autoconfig または application/x-javascript-configのいずれかを宣言しておくべきである。

これらのMIMEタイプのどちらを使った方がよいという根拠はほとんどないが、application/x-ns-proxy-autoconfigがapplication/x-javascript-configよりも多くのクライアントでサポートされていると想定するのは妥当だろう。なぜなら前者は最初のNetscapeの仕様で定義されたものであり、後者はもっと最近になってから使われるようになったものだからだ。

PACファイルの非常に単純な例を示す: function FindProxyForURL { return "PROXY proxy.example.com:8080; DIRECT"; }

この関数は、proxy.example.comサーバのポート番号8080上のプロキシを通じて全てのページを取得するようブラウザに指示する。このプロキシが応答に失敗した場合、ブラウザはプロキシを使わず目的のウェブサイトに直接接続する。後者の直接接続はファイアウォールあるいはその他の中間的なネットワーク装置が、プロキシ以外を発信元とする要求を拒否する設定になっている場合には失敗する。

利用できるJavaScript関数をFindProxyForURL関数の中で幾つか使った、より複雑な例を示す：

function FindProxyForURL { // example.com以下のドメインにある我々のローカルなURLに対してはプロキシ不要: if ) { return "DIRECT"; } // 下記のネットワーク内のURLには // fastproxy.example.comのポート8080を通じてアクセスする: if ) { return "PROXY fastproxy.example.com:8080"; }

// その他のリクエストはproxy.example.comのポート8080を通じて出る。 // 応答がなければ、直接WWWに出る： return "PROXY proxy.example.com:8080; DIRECT"; }<WtXmlEndTag />

3.1. 制約
-------

3.1.1. PAC 文字エンコード
------------------

Mozilla FirefoxやInternet Explorerなどのブラウザはシステムのデフォルトの文字コードのPACファイルしかサポートしないdate=April 2013}}ので、UTF-8などのUnicodeでエンコードされたものはサポートできないdate=April 2013}}。

3.1.2. dnsResolve
-----------------

dnsResolve関数はDNSルックアップを実行するが、DNSサーバが応答しない場合、ブラウザを長時間ブロックすることがある。

Microsoft Internet Explorer 5.5以上でドメイン名によりプロキシ自動設定結果をキャッシュすることは、PAC標準の柔軟性を制限してしまう。実質的に、URLのパスに基づいてではなく、ドメイン名に基づいてプロキシを選ぶことになる。それを回避するにはレジストリを編集してプロキシ自動設定結果のキャッシュを無効にする必要がある。

Internet ExprolerのPAC設定を使用する.NET 2.0 Frameworkなどの他のWindowsコンポーネントとの互換性のために、isInNet関数内では、ホストのドメイン名ではなく、常にIPアドレスを用いることが推奨される。たとえば次のように書く： if , "255.255.248.0")) // .NET 2.0 は適切にプロキシを解決するだろう

if ) // .NET 2.0 はプロキシを適切に解決できないだろう<WtXmlEndTag />

PACファイルが利用できない場合は直接接続にフェイルオーバーするのが現在の慣例である。

ネットワーク設定を切り替えた少し後、dnsResolveがDNSキャッシュによる古い結果を返すことがある。

たとえば、Firefoxは通常20個のドメインのエントリーを60秒キャッシュしている。これは設定変数network.dnsCacheEntries およびnetwork.dnsCacheExpirationで設定できる。システムのDNSキャッシュを捨てることも役に立つ場合がある、これは例えばLinuxではsudo service dns-clean startで実行できる。

3.1.3. myIpAddress
------------------

myIpAddress関数は不正確であったり使えない結果を返すことがしばしば報告されてきた。システムのホストファイルで当該マシンのホスト名を参照する行をすべて削除する一方、127.0.0.1 localhostの行はそのままにしておくことが役に立つ場合がある。

Internet Explorer 9では、isInNetがtrue を返すので、これが回避策として使える。

myIpAddress関数は、その装置が一つのIPv4アドレスを持つと想定している。その装置が複数のIPv4アドレスあるいはIPv6アドレスを持つ場合、その結果は未定義となる。

3.1.4. セキュリティ
-------------

2013年、研究者らはプロキシ自動設定のセキュリティ上の危険性を警告し始めた 。その脅威とは、PACを使って被害者のブラウザの通信先を攻撃者が支配しているサーバにすり替えてしまうというものなどである。

3.1.5. その他
----------

その他の制約は、JavaScriptエンジンのローカルマシンに対する制約と関係したものである。

3.2. 発展機能
---------

より発展したPACファイルは、リクエストがネットワークへ送られる前に、プロキシの負荷を減らし、負荷分散、フェイルオーバーを行い、更にはブラックリスト/ホワイトリストの作成まで行うことができる。複数のプロキシを返すこともできる：

return "PROXY proxy1.example.com:80; PROXY proxy2.example.com:8080";

4. 発展学習
-------

5. 脚注
-----

6. 外部リンク
--------