PAC 文件是一个文本文件,用于指定应将哪些流量重定向到代理服务器。当浏览器发起 Web 请求时,它会咨询 PAC 文件的 FindProxyForURL() 函数,该函数评估请求并返回路由指令,例如直接连接、代理服务器或故障转移序列。
默认的 Cloudflare PAC 文件遵循标准格式:
function FindProxyForURL(url, host) {
// No proxy for private (RFC 1918) IP addresses (intranet sites)
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")
) {
return "DIRECT";
}
// No proxy for localhost
if (isInNet(dnsResolve(host), "127.0.0.0", "255.0.0.0")) {
return "DIRECT";
}
// Proxy all
return "HTTPS 3ele0ss56t.proxy.cloudflare-gateway.com:443";
}您可以自定义 PAC 文件 ↗并将其托管在您的浏览器可以访问的位置。
- 确保用于终结点的指令是
HTTPS而不是PROXY。例如:- 正确:
return "HTTPS your-subdomain.proxy.cloudflare-gateway.com:443"; - 错误:
return "PROXY your-subdomain.proxy.cloudflare-gateway.com:443";
- 正确:
- 您必须使用 PAC 文件,而不是直接在浏览器的代理配置中配置终结点。现代浏览器在没有 PAC 文件的情况下不支持 HTTPS 代理。
- 使用诸如 VS Code 之类的纯文本编辑器以避免多余的字符。
- 如果您将 PAC 文件用于公共互联网浏览(而不仅是内部服务),请参阅 常见绕过规则,以了解您可能需要从代理中排除的域名,从而防止网站功能问题。
当使用授权终结点时,您必须在 PAC 文件中绕过您的身份提供程序 (IdP) 域。这可以防止出现身份验证循环,即浏览器在能够到达 IdP 进行身份验证之前尝试与代理进行身份验证。
以下示例 PAC 文件是一个包含常见 IdP 绕过规则的综合模板。请将占位符值替换为您的配置:
function FindProxyForURL(url, host) {
// *** Identity Provider Bypass ***
// CRITICAL: Bypass your IdP to prevent authentication loops
// Uncomment and configure the section for your IdP:
// Okta
// if (host === "your-domain.okta.com" || shExpMatch(host, "*.oktacdn.com")) {
// return "DIRECT";
// }
// Microsoft Entra ID (Azure AD)
// if (
// host === "login.microsoftonline.com" ||
// host === "aadcdn.msauth.net" ||
// host === "aadcdn.msftauth.net"
// ) {
// return "DIRECT";
// }
// Google Workspace
// if (
// host === "accounts.google.com" ||
// shExpMatch(host, "*.gstatic.com")
// ) {
// return "DIRECT";
// }
// GitHub
// if (shExpMatch(host, "*.github.com")) {
// return "DIRECT";
// }
// *** Private Networks ***
// Bypass private RFC 1918 IP addresses
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")
) {
return "DIRECT";
}
// Bypass localhost
if (isInNet(dnsResolve(host), "127.0.0.0", "255.0.0.0")) {
return "DIRECT";
}
// Bypass plain hostnames (no dots)
if (isPlainHostName(host)) {
return "DIRECT";
}
// Bypass .local domains
if (shExpMatch(host, "*.local")) {
return "DIRECT";
}
// *** Cloudflare Access Logout ***
// Optional: Redirect logout requests to your Access logout page
// if (shExpMatch(url, "*logout*")) {
// return "HTTPS your-team-name.cloudflareaccess.com/cdn-cgi/access/logout";
// }
// *** Proxy all other traffic ***
return "HTTPS your-subdomain.proxy.cloudflare-gateway.com:443";
}浏览器会针对每个请求评估 PAC 文件。优化 PAC 文件的性能对于避免用户在网页浏览中出现延迟和问题至关重要。
在使用 dnsResolve() 执行 DNS 解析时,请将结果存储在变量中,以便在多个检查中重用它。这可以避免冗余的 DNS 查找:
function FindProxyForURL(url, host) {
// Resolve once and reuse
var hostIP = dnsResolve(host);
if (isInNet(hostIP, "10.0.0.0", "255.0.0.0")) {
return "DIRECT";
}
// Reuse hostIP for additional checks
if (isInNet(hostIP, "172.16.0.0", "255.240.0.0")) {
return "DIRECT";
}
return "HTTPS proxy.example.com:443";
}NetBIOS 名称(不带句点的主机名)通常是内部名称,应绕过代理。首先检查这些名称:
if (isPlainHostName(host)) return "DIRECT";JavaScript 是区分大小写的。将主机名转换为小写以实现一致的匹配:
function FindProxyForURL(url, host) {
// Normalize to lowercase
host = host.toLowerCase();
url = url.toLowerCase();
if (shExpMatch(host, "*.example.com")) {
return "DIRECT";
}
return "HTTPS proxy.cloudflare-gateway.com:443";
}在将 PAC 文件用于公共互联网浏览(而不仅仅是内部服务)时,您可能需要针对某些域绕过代理,以防止网站功能问题。以下是您的代理可能干扰流量的常见场景。
字体 API 和静态资产提供程序通常应绕过代理以防止渲染问题:
// Bypass font providers
if (
shExpMatch(host, "*.googleapis.com") ||
shExpMatch(host, "*.gstatic.com") ||
shExpMatch(host, "fonts.adobe.com")
) {
return "DIRECT";
}视频流和大型媒体下载在直接连接下的性能可能更好:
// Bypass streaming services
if (
shExpMatch(host, "*.netflix.com") ||
shExpMatch(host, "*.youtube.com") ||
shExpMatch(host, "*.googlevideo.com")
) {
return "DIRECT";
}启用 HTTPS 检查时,使用证书锁定(certificate pinning)的应用程序和服务会拒绝 Cloudflare 注入的证书,并且在通过代理进行路由时会加载失败。在您的 PAC 文件中绕过这些域:
// Bypass certificate-pinned apps
if (
shExpMatch(host, "*.example-bank.com") ||
shExpMatch(host, "*.example-pinned-app.com")
) {
return "DIRECT";
}Do Not Inspect (DNI) 策略将无法防止这些连接上的证书锁定错误 —— 必须在 PAC 文件中绕过具有证书锁定的应用。
在将您的 PAC 文件部署到组织中的所有用户之前,请使用您的用户通常访问的网站和应用程序对其进行测试。这有助于确保:
- 内部资源可以访问,并且未被错误地通过代理进行路由
- 外部网站已通过 Gateway 进行正确过滤
- 典型使用模式下的性能是可以接受的
PAC 文件使用 JavaScript 语法。单个语法错误(例如缺少右括号 ) 或右括号 ])将导致整个 PAC 文件失效。在部署之前,请使用支持 JavaScript 的文本编辑器查找并修复语法错误。
如果您遇到代理路由问题,大多数浏览器都提供了调试工具来验证 PAC 文件行为:
基于 Chromium 的浏览器(Chrome、Edge、Brave)
- 在浏览器中,转到
chrome://net-export/(或edge://net-export/)。 - 选择 Start Logging to Disk(开始记录到磁盘)。
- 转到您要使用受影响的浏览器进行测试的网站。
- 选择 Stop Logging(停止记录)。
- 使用 netlog-viewer ↗ 打开下载的文件。
- 搜索您的域以查看代理解析决策。
Firefox
- 在 Firefox 中,转到 Tools(工具) > Browser Tools(浏览器工具) > Browser Console(浏览器控制台)。
- 转到您要使用受影响的浏览器进行测试的网站。
- 查找与代理解析相关的消息。
您还可以通过复制您的 FindProxyForURL 函数并使用测试 URL 调用该函数,直接在控制台中测试 PAC 文件逻辑。例如:
TODO
Safari
- 在 Safari 中,转到 Safari > Settings(设置),然后选择 Advanced(高级)。
- 开启 Show Develop menu in menu bar(在菜单栏中显示“开发”菜单)。
- 选择 Develop(开发) > Show Web Inspector(显示 Web 检查器)。
- 转到 Network(网络) 选项卡。
- 查看请求详细信息以验证代理使用情况。
PAC 文件中过多的 DNS 查找可能会导致延迟。请检查您的 PAC 文件,并尽量减少使用 dnsResolve()、isInNet() 和 isResolvable() 函数。
当您更新 PAC 文件时,浏览器可能会继续使用缓存的版本,从而导致意外的行为。在更新 PAC 文件后,请清除浏览器缓存并重启浏览器,以确保浏览器使用最新版本。