PAC 魔法 让你的代理变得聪明
字数 1590 2025-08-18 11:39:11
PAC 魔法:智能代理配置教学文档
1. PAC 文件概述
PAC (Proxy Auto-Configuration) 文件是一种 JavaScript 脚本文件,用于智能决定网络请求是否通过代理服务器以及使用哪个代理服务器。
核心特点:
- 本质是一个 JavaScript 文件
- 包含
FindProxyForURL函数的实现 - 可以根据请求的 URL 和主机名动态决定代理策略
2. 基本语法结构
function FindProxyForURL(url, host) {
// 代理决策逻辑
return "DIRECT"; // 直接连接
// 或
return "PROXY 127.0.0.1:8080"; // 使用指定代理
// 或
return "SOCKS5 127.0.0.1:1080"; // 使用SOCKS代理
}
3. 核心函数参数
FindProxyForURL(url, host) 函数接收两个参数:
url: 完整的请求URL (如 "http://example.com/path/page.html")host: 主机名部分 (如 "example.com")
4. 返回值说明
返回值可以是以下形式之一或组合:
| 返回值格式 | 说明 |
|---|---|
DIRECT |
不经过代理直接连接 |
PROXY host:port |
使用HTTP代理 |
SOCKS host:port |
使用SOCKS代理 |
| 多个代理 | 用分号分隔,如 PROXY 1.1.1.1:80; PROXY 2.2.2.2:80; DIRECT |
5. 典型应用场景
- 选择性代理:只代理特定域名的请求
- 负载均衡:在不同代理服务器间分配流量
- 故障转移:当主代理不可用时自动切换到备用代理
- 安全测试:只拦截测试目标的流量而不影响其他网络请求
6. 实用示例代码
示例1:只代理特定域名
function FindProxyForURL(url, host) {
if (shExpMatch(host, "*.target.com") ||
host == "api.example.org") {
return "PROXY 127.0.0.1:8080"; // Burp Suite代理
}
return "DIRECT";
}
示例2:排除本地地址和特定域名
function FindProxyForURL(url, host) {
// 本地地址直接连接
if (isPlainHostName(host) ||
host == "localhost" ||
isInNet(host, "10.0.0.0", "255.0.0.0") ||
isInNet(host, "192.168.0.0", "255.255.0.0")) {
return "DIRECT";
}
// 目标域名走代理
if (shExpMatch(host, "*.test.com")) {
return "PROXY 127.0.0.1:8080";
}
// 默认直接连接
return "DIRECT";
}
7. PAC 实用函数
PAC 提供了一些内置函数帮助决策:
| 函数 | 说明 |
|---|---|
isPlainHostName(host) |
检查是否为无域名主机名 (如 "localhost") |
dnsDomainIs(host, domain) |
检查主机是否属于特定域名 |
shExpMatch(str, pattern) |
shell风格的通配符匹配 |
isInNet(host, pattern, mask) |
检查IP是否在指定子网内 |
dnsResolve(host) |
解析主机名为IP地址 |
myIpAddress() |
返回本机IP地址 |
8. 部署方式
- 本地文件:保存为
.pac文件,如file:///path/to/proxy.pac - Web服务器:通过HTTP访问,如
http://example.com/proxy.pac
9. 浏览器配置
在浏览器代理设置中选择"自动代理配置(PAC)"并输入PAC文件URL。
10. 高级技巧
- 多代理负载均衡:
var proxies = ["PROXY proxy1:8080", "PROXY proxy2:8080"];
function FindProxyForURL(url, host) {
return proxies[Math.floor(Math.random() * proxies.length)];
}
- 时间条件代理:
function FindProxyForURL(url, host) {
var hour = new Date().getHours();
if (hour >= 9 && hour <= 18) {
return "PROXY work-proxy:8080";
}
return "DIRECT";
}
- 协议类型判断:
function FindProxyForURL(url, host) {
if (url.substring(0, 5) == "http:") {
return "PROXY http-proxy:8080";
} else if (url.substring(0, 6) == "https:") {
return "PROXY https-proxy:8443";
}
return "DIRECT";
}
11. 调试技巧
- 使用
alert()函数输出调试信息(部分浏览器支持) - 在PAC文件中添加注释说明决策逻辑
- 使用浏览器开发者工具查看代理决策过程
12. 安全注意事项
- 确保PAC文件来自可信来源
- 定期检查PAC文件内容是否被篡改
- 避免在PAC文件中包含敏感信息
13. 性能优化
- 尽量减少DNS查询(
dnsResolve)的使用 - 将常用规则放在函数开头
- 对大量域名使用哈希表查找而非线性判断
14. 实际应用案例(渗透测试)
function FindProxyForURL(url, host) {
// 只拦截测试目标的流量
var targets = [
"api.target.com",
"app.target.com",
"*.test.target.com"
];
for (var i = 0; i < targets.length; i++) {
if (shExpMatch(host, targets[i])) {
return "PROXY 127.0.0.1:8080"; // Burp Suite代理
}
}
// 其他流量直接连接
return "DIRECT";
}
15. 相关工具推荐
- Burp Suite:专业渗透测试工具,支持代理流量分析
- goproxy:Golang编写的代理库,可自定义代理逻辑
- Charles Proxy:另一款常用的HTTP代理/监控工具
通过合理配置PAC文件,可以显著提高代理使用的效率和精确度,特别适合需要精细控制代理流量的开发和安全测试场景。