跳转到内容
搜索文档

PAC 文件最佳实践

最后更新 查看 MarkdownAgent 设置

PAC 文件是一个文本文件,用于指定应将哪些流量重定向到代理服务器。当浏览器发起 Web 请求时,它会咨询 PAC 文件的 FindProxyForURL() 函数,该函数评估请求并返回路由指令,例如直接连接、代理服务器或故障转移序列。

PAC 文件格式

默认的 Cloudflare PAC 文件遵循标准格式:

default-pac.jsjs
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 文件模板

当使用授权终结点时,您必须在 PAC 文件中绕过您的身份提供程序 (IdP) 域。这可以防止出现身份验证循环,即浏览器在能够到达 IdP 进行身份验证之前尝试与代理进行身份验证。

以下示例 PAC 文件是一个包含常见 IdP 绕过规则的综合模板。请将占位符值替换为您的配置:

pac-idp-template.jsjs
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 文件的性能对于避免用户在网页浏览中出现延迟和问题至关重要。

将 DNS 结果缓存到变量中

在使用 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";
}

首先检查单标签主机名(plain hostnames)

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 文件

使用预期网站进行测试

在将您的 PAC 文件部署到组织中的所有用户之前,请使用您的用户通常访问的网站和应用程序对其进行测试。这有助于确保:

  • 内部资源可以访问,并且未被错误地通过代理进行路由
  • 外部网站已通过 Gateway 进行正确过滤
  • 典型使用模式下的性能是可以接受的

验证语法

PAC 文件使用 JavaScript 语法。单个语法错误(例如缺少右括号 ) 或右括号 ])将导致整个 PAC 文件失效。在部署之前,请使用支持 JavaScript 的文本编辑器查找并修复语法错误。

对配置进行故障排除

调试 PAC 文件路由决策

如果您遇到代理路由问题,大多数浏览器都提供了调试工具来验证 PAC 文件行为:

基于 Chromium 的浏览器(Chrome、Edge、Brave)

  1. 在浏览器中,转到 chrome://net-export/(或 edge://net-export/)。
  2. 选择 Start Logging to Disk(开始记录到磁盘)。
  3. 转到您要使用受影响的浏览器进行测试的网站。
  4. 选择 Stop Logging(停止记录)。
  5. 使用 netlog-viewer ↗ 打开下载的文件。
  6. 搜索您的域以查看代理解析决策。

Firefox

  1. 在 Firefox 中,转到 Tools(工具) > Browser Tools(浏览器工具) > Browser Console(浏览器控制台)。
  2. 转到您要使用受影响的浏览器进行测试的网站。
  3. 查找与代理解析相关的消息。

您还可以通过复制您的 FindProxyForURL 函数并使用测试 URL 调用该函数,直接在控制台中测试 PAC 文件逻辑。例如:

TODO

Safari

  1. 在 Safari 中,转到 Safari > Settings(设置),然后选择 Advanced(高级)。
  2. 开启 Show Develop menu in menu bar(在菜单栏中显示“开发”菜单)。
  3. 选择 Develop(开发) > Show Web Inspector(显示 Web 检查器)。
  4. 转到 Network(网络) 选项卡。
  5. 查看请求详细信息以验证代理使用情况。

在使用 PAC 文件的设备上浏览网页速度较慢

PAC 文件中过多的 DNS 查找可能会导致延迟。请检查您的 PAC 文件,并尽量减少使用 dnsResolve()、isInNet() 和 isResolvable() 函数。

浏览器错误地缓存 PAC 文件

当您更新 PAC 文件时,浏览器可能会继续使用缓存的版本,从而导致意外的行为。在更新 PAC 文件后,请清除浏览器缓存并重启浏览器,以确保浏览器使用最新版本。

这篇文档对您有帮助吗?