跳转到内容
搜索文档

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 文件后,请清除浏览器缓存并重启浏览器,以确保浏览器使用最新版本。

这篇文档对您有帮助吗?