PAC (proxy auto-config) 自動代理

代理是個好東西,幫你節省時間,減少麻煩。今天講一個自動代理文件格式-PAC,它是微軟發明的,1999年就提交到了IETF標準化組織,但後來就沒有下文了,好在常見的瀏覽器(Firefox,IE,Safari)都實現了對PAC支持。利用PAC我們可以對某些特定站點或移動到特定的網絡時選擇特定的代理服務器來瀏覽網頁,這解決了很多時候的不便利。

PAC的語法很簡單,下面就是一個例子:

function FindProxyForURL(url, host) {
if (
 shExpMatch(url,"*.mitbbs.com*") ||
 shExpMatch(url,"*.pandora.com*") ||
 shExpMatch(url,"*.popyard.org*") ||
 shExpMatch(url,"*.wordpress.com*") ||
 shExpMatch(url,"*.bullogger.com*")
 )
 {
 return "SOCKS localhost:1080";
 }

 return "DIRECT";
}

把上面的代碼保存成一個文本文件,然後配置瀏覽器使用這個文件,IE的詳細設置教程請看:http://www.microsoft.com/technet/prodtechnol/ie/reskit/6/part6/c26ie6rk.mspx?mfr=true

 

Proxy Auto Config


什麼是 Proxy Auto Config

首先,我們一定要知道什麼是 Proxy?他的功用是什麼?如果還不知道,可以參照這份文件
PAC(Proxy Auto Config) 又是什麼呢?它實際上是一個 Script;經由編寫這個 Script,我們可以讓系統判斷在怎麼樣的情形下,要利用哪一臺 Proxy 來進行聯機。這樣做主要的好處有:

1.      分散 Proxy 的流量,避免 Proxy Server 負載過高

2.      針對個別條件設定、加快瀏覽速度

3.      設定要求順序,在某臺 Proxy 無法聯機時,可自動嘗試別種聯機方式


Proxy Auto Config File 的格式

基本上 Proxy Auto Config File(以下簡稱 PAC)是一個純文字文件,他的語法採用 JavaScript;所以建議要學習編寫 PAC 的人,最好先學習基本的 JavaScript。一個 PAC 檔必需是單獨的 JavaScript,其中不能包含任何 HTML 標籤。

PAC 檔中,一定要定義 Function FindProxyForURL 如下:

function FindProxyForURL( url, host )

{

      ...

}

如果使用了 PAC 檔,則瀏覽器在接受我們要求的網址後,會去執行

ret = FindProxyForURL( url, host );

這樣的指令。其中,url 是所要求網址的完整路徑,host 是對方的計算機名稱(就是在 :// / 之中的部份);而 return ret 則是 Proxy 的組態,它的格式有下列三種:

·  DIRECT 直接聯機而不透過 Proxy

·  PROXY host:port 使用指定的 Proxy 伺服機

·  SOCKS host:port 使用指定的 Socks 伺服機

比如說當瀏覽器得到的是 Proxy proxy.ncu.edu.tw:3128; Proxy proxy.csie.ncu.edu.tw:3128; DIRECT 的話,那瀏覽器會先嚐試透過 proxy.ncu.edu.tw 來開啓網頁,如果無法使用,則嘗試 proxy.csie.ncu.edu.tw,還是不行的話,就直接聯機。


PAC 中特別的 Function

PAC 中,除了可以使用一般 JavaScript Function 外,它還定義了一些特別的 Function 可以使用:

·  isPlainHostName()

·  dnsDomainIs()

·  localHostOrDomainIs()

·  isResolvable()

·  isInNet()

·  dnsResolve()

·  myIpAddress()

·  dnsDomainLevels()

·  shExpMatch()

·  weekdayRange()

·  dateRange()

·  timeRange()


isPlainHostName( host )

host 由網址取得的主機名稱。

Function 會判斷 host 是否爲不包含網域 (Domain)。如果是,則 return true;如果包含,則 return false

範例:

1.      isPlainHostName("www") return true

2.      isPlainHostName("www.netscape.com") return false


 

dnsDomainIs( host, domain )

host 由網址取得的主機名稱。
domain
指定的網域。

Function 會判斷 host 是否屬於網域 domain。如果是,則 return true;否,則 return false

範例:

1.      dnsDomainIs("www.netscape.com", ".netscape.com") return true

2.      dnsDomainIs("www", ".netscape.com") return false

3.      dnsDomainIs("www.mcom.com", ".netscape.com") return false


 

localHostOrDomainIs( host, hostdom )

host 由網址取得的主機名稱。
hostdom
完整的網域名稱。

Function 會判斷 host 是否爲 hostdom,或 host 是否爲 hostdom 的主機名稱。如果是,則 return true;否,則 return false

範例:

1.      localHostOrDomainIs("www.netscape.com", "www.netscape.com") return true (完全相同)

2.      localHostOrDomainIs("www", "www.netscape.com") return true (主機名稱相同)

3.      localHostOrDomainIs("www.mcom.com", "www.netscape.com") return false (網域不同)

4.      localHostOrDomainIs("home.netscape.com", "www.netscape.com") return false (主機名稱不同)


 

isResolvable( host )

host 由網址取得的主機名稱。

Function 會嘗試透過 DNS 去解析 host,如果解析成功,則 return true;否則 return false

範例:

1.      isResolvable("www.netscape.com") return true (除非 DNS 無法正常運作)

2.      isResolvable("bogus.domain.foobar") return false (除非真的冒出這個 domain 出來


 

isInNet( host, pattern, mask )

host 主機名稱,可以是 Domain Name IP。如果是 Domain Name,則會透過 DNS 查出 IP
pattern IP

mask
對應於 pattern 的屏蔽。

Function host 是否在指定的 IP 範圍內,如果是,則 return true;否則 return false

範例:

1.      isInNet(host, "198.95.249.79", "255.255.255.255") host 198.95.249.79 時,會 return true

2.      isInNet(host, "140.115.0.0", "255.255.0.0") host 140.115.*.* 時,會 return true


 

dnsResolve( host )

host 要透過 DNS 解晰的主機名稱。

Function 會透過 DNS 去解析 hostreturn 值即爲解析之結果。

範例:

1.      dnsResolve("www.math.ncu.edu.tw") return "140.115.25.9"


 

myIpAddress()

Function return 瀏覽器所在計算機之 IP 地址。


 

dnsDomainLevels( host )

host 由網址取得的主機名稱。

Function return host Domain 層數(點的數目)。

範例:

1.      dnsDomainLevels("www") return 0

2.      dnsDomainLevels("www.netscape.com") return 2


 

shExpMatch( str, shexp )

str 要進行比對的字符串。
shexp
比對的條件。

Function 會比對 str 是否符合 shexp 的表示式(此表示式爲 shell expression 而非 regular expressions)。如果是,則 return true;否則 return false

範例:

1.      shExpMatch("http://home.netscape.com/people/ari/index.html", "*/ari/*") return true

2.      shExpMatch("http://home.netscape.com/people/montulli/index.html", "*/ari/*") return false


 

weekdayRange()dateRange()timeRange()

這三個 Function 的功用都是檢查線在時間是否在指定範圍內,用這些 Function 就可以設定分時段使用 Proxy Server但由於較爲繁瑣,如有興趣或需要,請參考原始文件


範例

1.中央大學數學系之設定

2.                         function FindProxyForURL( url, host ){

3.                                        if ( dnsDomainIs( host, "locahost" ) || dnsDomainIs( host, ".edu.tw" ) || isInNet( host, "140.0.0.0", "255.0.0.0" ) || isPlainHostName( host ) )

4.                                        {

5.                                                        return "DIRECT; PROXY proxy.csie.ncu.edu.tw:3128;" + " PROXY cache.math.ncu.edu.tw:3128";

6.                                                        //localhost domain .edu.twIP 140.*.*.* 或只有 Host Name

7.                                                        //則直接聯機;如果直接聯機不行,則嘗試使用 proxy.csie cache.math

8.                                        }else if ( dnsDomainIs( host, ".tw" ) )

9.                                        {

10.                                                   return "PROXY proxy.csie.ncu.edu.tw:3128;" + " PROXY cache.math.ncu.edu.tw:3128;" + " DIRECT";

11.                                                   //如果網域是 .tw,則依序嘗試 proxy.csiecache.math、直接聯機

12.                                   }else

13.                                                   return "PROXY cache.math.ncu.edu.tw:3128;" + " PROXY proxy.csie.ncu.edu.tw:3128;" + " DIRECT";

14.                                                   //其它:依序嘗試 cache.mathproxy.csie、直接聯機

15.                    }

16. 中央大學計算器中心提供之設定

17.                    function FindProxyForURL(url,host)

18.                    {

19.                                   var RFC="1234567890-_qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM.";

20.                                   for(var i=0;i < host.length;i++)

21.                                   {

22.                                                   var c=host.charAt(i);

23.                                                   if(RFC.indexOf(c)==-1 && !(dnsDomainIs(host, ".cc") || dnsDomainIs(host,".tw"))) {

24.                    //      alert(url+"--"+host);

25.                                                                  return "PROXY dnsrelay.twnic.net.tw:3127";

26.                                                   }

27.                                   }

28.                                   if(host == 'auto.search.msn.com')

29.                                                   return "PROXY keyword.twnic.net.tw:80";

30.                     

31.                                   if(dnsDomainIs(host, ".tw"))

32.                                   {

33.                                                   return "DIRECT";

34.                                   }

35.                                   return "PROXY proxy.ncu.edu.tw:3128; PROXY cache.ncu.edu.tw:3128; DIRECT";

36.                    }


參考數據

·  Navigator Proxy Auto-Config File Format

·  Using the Client Autoconfiguration File

 

 

172.16.82.0 網段的客戶端通過A代理走。
172.16.83.0 網段的客戶端也通過A代理走。
172.16.84.0 網段的客戶端通過B代理走。
不屬於以上三個網段的地址,以上的代理設置不生效。
我們假定A代理的IP地址爲172.16.1.1 B代理的IP地址爲172.16.1.2。
function FindProxyForURL(url host)
{
if (shExpMatch(url "http://* ")) && (((isInNet(myIpAddress()"172.16.82.0""255.255.255.0")) || (isInNet(myIpAddress()"172.16.83.0""255.255.255.0"))))
return "PROXY 172.16.1.1:80";
else
if (shExpMatch(url "http://* ")) && (isInNet(myIpAddress()"172.16.84.0""255.255.255.0"))
return "PROXY 172.16.1.2:80";
else
{
if (shExpMatch(url "https://* ")) && (((isInNet(myIpAddress()"172.16.82.0""255.255.255.0")) || (isInNet(myIpAddress()"172.16.83.0""255.255.255.0"))))
return "PROXY 172.16.1.1:443";
else
if (shExpMatch(url "https://* ")) && (isInNet(myIpAddress()"172.16.84.0""255.255.255.0"))
return "PROXY 172.16.1.2:443";
else
return "DIRECT";
}
}

以上的script僅供您參考。
其中isInNet(myIpAddress()"172.16.84.0""255.255.255.0")指的是主機IP地址是172.16.84.0網段,shExpMatch(url "http://* ")指的是以http://結尾的網站。

squid 做HTTPS代理

使用iptbales+squid很容易實現http透明代理
如果要https的透明代理也只需要下面兩個步驟就行了
1.生成測試用的證書:

openssl req -new -keyout /etc/squid/key.pem -nodes -x509 -days 365 -out /etc/squid/cert.pem

(如果要生成一個證書請求用於申請正式證書請用下面兩個命令:

生成私鑰 openssl genrsa -out key.pem 1024
生成待簽名證書 openssl req -new -out req.csr -key key.pem

然後將req.csr文件中的內容提交給證書頒發機構。)

 

2. 在squid.conf相應地方添加

https_port 443 cert=/etc/squid/cert.pem /etc/squid/key.pem

如果出現下面的錯誤

The following error was encountered:

Invalid Request

Some aspect of the HTTP Request is invalid. Possible problems:

Missing or unknown request method

Missing URL

Missing HTTP Identifier (HTTP/1.0)

Request is too large

Content-Length missing for POST or PUT requests

Illegal character in hostname; underscores are not allowed

 

只需要在https_port 後面在加transparent

https_port 443 cert=/etc/squid/cert.pem /etc/squid/key.pem transparent
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章