PACファイル(プロキシ自動設定ファイル)の記述方法完全版

ITエンジニア
記事内に広告が含まれています。

PACファイル(プロキシ自動設定ファイル)の記述方法完全版

はじめに

  • PACファイルとは、Proxy Auto-Configurationの略で、ブラウザのプロキシ設定を自動的に管理するためのファイルです。
  • PACファイルには、JavaScriptの関数が記述されており、ブラウザがアクセスするURLやホスト名に応じて、使用するプロキシを決定します。
  • 本記事では、PACファイルの記述方法について、基本概念から応用例まで詳しく解説します。

ファイル名

PACファイルは拡張子「.pac」でなければなりません。

サーバーの設定

  • PACファイルをダウンロードできるように、MIMEタイプに「.pac」拡張子を下記のように設定する必要があります。
    application/x-ns-proxy-autoconfig

    IISの場合は、IISマネージャでMIMEの種類を開き、追加で、ファイル名の拡張子に.pac、MIMEの種類にapplication/x-ns-proxy-autoconfigを設定します。

PACファイルの基本構造

  • PACファイルは、次のようなJavaScriptの関数を必ず含める必要があります。
    function FindProxyForURL(url, host) { // プロキシ設定を返すコード }
  • この関数は、引数としてURLとホスト名を受け取り、プロキシ設定を表す文字列を返します。
  • プロキシ設定の文字列は、次のような書式に従います。
    • DIRECT:プロキシを使用せずに直接接続する
    • PROXY host:port:指定されたプロキシを使用する
    • SOCKS host:port:指定されたSOCKSサーバーを使用する
    • HTTP host:port:指定されたHTTPプロキシを使用する(Firefoxのみ)
    • HTTPS host:port:指定されたHTTPSプロキシを使用する(Firefoxのみ)
    • SOCKS4 host:port, SOCKS5 host:port:指定されたSOCKSサーバーを(指定されたSOCKSバージョンで)使用する(Firefoxのみ)
  • プロキシ設定の文字列は、セミコロンで区切って複数指定することができます。その場合、最も左にある有効な設定が優先されます。
  • PACファイルで使用できる関数と変数
    • PACファイルでは、JavaScriptの標準的な関数や変数に加えて、次のような特殊な関数や変数が使用できます。
      • ホスト名に基づく条件
        • isPlainHostName(host):ホスト名にドットが含まれない場合にtrueを返す
        • dnsDomainIs(host, domain):ホスト名が指定されたドメインと一致する場合にtrueを返す
        • localHostOrDomainIs(host, hostdom):ホスト名が指定されたホスト名またはドメインと一致する場合にtrueを返す
        • isResolvable(host):ホスト名がDNSで解決できる場合にtrueを返す
        • isInNet(host, pattern, mask):ホスト名が指定されたパターンとマスクに一致するIPアドレスを持つ場合にtrueを返す
      • 関連するユーティリティ関数
        • dnsResolve(host):ホスト名からIPアドレスを取得する
        • convert_addr(ipaddr):IPアドレスから整数値に変換する
        • myIpAddress():自分自身のIPアドレスを取得する
        • dnsDomainLevels(host):ホスト名に含まれるドットの数を取得する
      • URL/ホスト名に基づく条件
        • shExpMatch(str, shexp):文字列が指定されたシェル式に一致する場合にtrueを返す
      • 時刻に基づく条件
        • weekdayRange(wd1, wd2, gmt):現在の曜日が指定された範囲内にある場合にtrueを返す
        • dateRange(day1, month1, year1, day2, month2, year2, gmt):現在の日付が指定された範囲内にある場合にtrueを返す
        • timeRange(hour1, min1, sec1, hour2, min2, sec2, gmt):現在の時刻が指定された範囲内にある場合にtrueを返す
      • ログ用ユーティリティ
        • alert(message):メッセージをログに出力する
      • 定義済みの連想配列(非推奨)
        • ProxyConfig.bindings:プロキシ設定の値をキーとして持つオブジェクト

PACファイルの記述例

ここでは、PACファイルの記述方法をいくつかの例で紹介します。

  • 例1:特定のドメインにはプロキシを使用せず、それ以外はプロキシを使用する。
    function FindProxyForURL(url, host) {
      if (dnsDomainIs(host, ".example.com")) {
        return "DIRECT";
      } else {
        return "PROXY 192.168.100.20:8080";
      }
    }

    説明:もしURLが”.example.com”ドメインの場合はプロキシを使用しないで直接接続する。それ以外は、プロキシ192.168.100.20:8080を使用する。

  • 例2:特定のIPアドレス範囲にはプロキシを使用せず、それ以外はプロキシを使用する。
    function FindProxyForURL(url, host) {
      if (
        isInNet(host, "10.0.0.0", "255.0.0.0") ||
        isInNet(host, "172.16.0.0", "255.240.0.0") ||
        isInNet(host, "192.168.0.0", "255.255.0.0")
      ) {
        return "DIRECT";
      } else {
        return "PROXY 192.168.100.20:8080";
      }
    }

    説明:もしIPアドレスが、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16の範囲に含まれる場合はプロキシを使用しないで直接接続する。それ以外はプロキシ192.168.100.20:8080を使用する。

  • 例3:特定のURLパターンにはSOCKSサーバーを使用し、それ以外はプロキシを使用する。
    function FindProxyForURL(url, host) {
      if (shExpMatch(url, "://.example.com/*")) {
        return "SOCKS socks.example.com:1080";
      } else {
        return "PROXY 192.168.100.20:8080";
      }
    }

    説明:もしURLが”.example.com”ドメインの場合はSOCKSサーバーsocks.example.com:1080を使用し、それ以外はプロキシ192.168.100.20:8080を使用する。

  • 例4:特定の曜日や時刻にはプロキシを使用せず、それ以外はプロキシを使用する。
    function FindProxyForURL(url, host) {
      if (weekdayRange("SAT", "SUN") || timeRange(18, 0, 0, 9, 0, 0)) {
        return "DIRECT";
      } else {
        return "PROXY 192.168.100.20:8080";
      }
    }

    説明:土曜日と日曜日の場合または、18:00~09:00まではプロキシを使用しないで直接接続する。それ以外はプロキシ192.168.100.20:8080を使用する。

  • 例5:社内で運用しているWebサーバなどにある、ホスト名がNetBIOS名の場合(”.”を含まない)はプロキシを使用せず、それ以外はプロキシを使用する。
    function FindProxyForURL(url, host) {
      if (isPlainHostName(host)){
        return "DIRECT";
      } else {
        return "PROXY 192.168.100.20:8080";
      }
    }

    説明:アクセスするURLが”http://example/”、”https://intrasite/”などホスト名が”.”を含まない場合はプロキシを使用しないで直接接続する。それ以外はプロキシ192.168.100.20:8080を使用する。

  • 例6:ホスト名がNetBIOS名の場合(”.”を含まない)または社内のローカルドメインの場合はプロキシを使用せず、それ以外はプロキシを使用する。
    function FindProxyForURL(url, host) {
      if (
            isPlainHostName(host) ||
            shExpMatch(host, "*.intra1.local") ||
            shExpMatch(host, "*.intra2.local") ||
            shExpMatch(host, "*.intra3.local")
        ){
        return "DIRECT";
      } else {
        return "PROXY 192.168.100.20:8080";
      }
    }

    説明:アクセスするURLが”http://example/”、”https://intrasite/”などホスト名が”.”を含まない場合、またはホスト名が”*.intra1.local”、”*.intra1.local”、”*.intra1.local”のパターンに一致する場合はプロキシを使用しないで直接接続する。
    それ以外はプロキシ192.168.100.20:8080を使用する。

  • urlパラメータ
    アクセスするURLです。
    例:http://www.example.com/
  • hostパラメータ
    URLから抽出したホスト名です。
    例:www.example.com
  • urlパラメータに渡される値のHTTPプロトコルとHTTPSプロトコルでの違い

    FindProxyForURL(url, host)関数では、urlパラメータにはアクセスするURLが渡されます。ただし、HTTPとHTTPSでこのurlパラメータの内容に違いがあります。

    • HTTPの場合urlパラメータには完全なURL(パスとクエリを含む)が渡されます。
    • HTTPSの場合urlパラメータには、パスとクエリの部分が削除されたURLが渡されます。
      例:

      アクセスするURL urlに渡される値 hostに渡される値
      HTTPの場合 http://www.example.com/site/sample/index.html http://www.example.com/site/sample/index.html www.example.com
      HTTPSの場合 https://www.example.com/site/sample/index.html https://www.example.com/ www.example.com

これは、HTTPS通信の内容が暗号化されており、PACファイル(特にJavaScriptコード)がHTTPSリクエストの詳細(パスやクエリパラメータなど)を見ることができないためです。

ただし、この挙動はブラウザによります。例えば、現在のEdgeやChromeではこの設定を無効にすることはできませんが、Firefoxでは、この設定はnetwork.proxy.autoconfig_url.include_pathで制御できます。

したがって、PACファイルを使用する際は、これらの違いを理解し、必要に応じて適切に対応することが重要です。

まとめ

  • PACファイルでは、JavaScriptの関数と変数を使って、プロキシ設定のロジックを記述します。
  • PACファイルは、ブラウザのプロキシ設定を自動的に管理するためのファイルです。
  • PACファイルの記述方法は、様々な条件や目的に応じてカスタマイズできます。

コメント

  1. You completed a few good points there. I did a search on the topic and found a good number of people will go along with with your blog.

タイトルとURLをコピーしました