0%

PAC文件配置

PAC

代理自动配置(英语:Proxy auto-config,简称PAC)是一种网页浏览器技术,用于定义浏览器该如何自动选择适当的代理服务器来访问一个网址。

一个PAC文件包含一个JavaScript形式的函数“FindProxyForURL(url, host)”。这个函数返回一个包含一个或多个访问规则的字符串。用户代理根据这些规则适用一个特定的代理器或者直接访问。当一个代理服务器无法响应的时候,多个访问规则提供了其他的后备访问方法。浏览器在访问其他页面以前,首先访问这个PAC文件。PAC文件中的URL可能是手工配置的,也可能是是通过网页的网络代理自动发现协议(WPAD)自动配置的。

PAC内置函数

PAC脚本提供了几个内置函数:

dnsDomainIs: 类似于 ==,但是对大小写不敏感

1
2
3
4
if (dnsDomainIs(host, "google.com") || 
dnsDomainIs(host, "www.google.com")) {
return "DIRECT";
}

shExpMatch:正则匹配

1
2
3
4
if (shExpMatch(host, "vpn.domain.com") ||
shExpMatch(url, "http://abcdomain.com/folder/*")) {
return "DIRECT";
}

isInNet:判断是否在网段内容,比如 10.1.0.0 这个网段,10.1.1.0 就在网段中

1
2
3
4

if (isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0")) {
return "DIRECT";
}

dnsResolve:通过 DNS 查询主机 ip

1
2
3
4
5
6
7

if (isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") ||
isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") ||
isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") ||
isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0")) {
return "DIRECT";
}

myIpAddress:返回主机的 IP

1
2
3
if (isInNet(myIpAddress(), "10.10.1.0", "255.255.255.0")) {
return "PROXY 10.10.5.1:8080";
}

isResolvable:判断主机是否可访问

1
2
3
if (isResolvable(host)) {
return "PROXY proxy1.example.com:8080";
}

dnsDomainLevels:返回是几级域名,比如 dnsDomainLevels(barretlee.com) 返回的结果就是 1

1
2
3
4
5
if (dnsDomainLevels(host) > 0) {
return "PROXY proxy1.example.com:8080";
} else {
return "DIRECT";
}

PAC基本语法

FindProxyForURL最后返回的字符串就是目标地址采用的代理类型。

可支持的类型: SOCKS5 [host:port] SOCKS [host:port] PROXY [host:port] 和 DIRECT 直连几种类型

而且可以连接在一起写,以达到代理自动降级的目的:
比如return ‘SOCKS5 bac.com:80 ; SOCKS abc.com:80; DIRECT;’
如果bac.com无法访问会降级到访问abc.com,最后会采用直连的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function FindProxyForURL(url, host) {
// our local URLs from the domains below example.com don't need a proxy:
if (shExpMatch(url,"*.example.com/*")) {return "DIRECT";}
if (shExpMatch(url, "*.example.com:*/*")) {return "DIRECT";}

// URLs within this network are accessed through
// port 8080 on fastproxy.example.com:
if (isInNet(host, "10.0.0.0", "255.255.248.0")) {
return "PROXY fastproxy.example.com:8080";
}

// All other requests go through port 8080 of proxy.example.com.
// should that fail to respond, go directly to the WWW:
return "PROXY proxy.example.com:8080; DIRECT";
}