文章目录
-
- [什么是 PAC 文件?](#什么是 PAC 文件?)
- 需要准备的文件
-
- [1. 主程序:agent-pac.py](#1. 主程序:agent-pac.py)
- [2. 代理规则文件:proxy.pac](#2. 代理规则文件:proxy.pac)
- 如何启动服务
- 常用操作命令
- 客户端如何使用
-
- [Windows 电脑设置](#Windows 电脑设置)
- [Mac 电脑设置](#Mac 电脑设置)
- 手机设置(iPhone/Android)
- [Chrome 浏览器设置](#Chrome 浏览器设置)
- [Firefox 浏览器设置](#Firefox 浏览器设置)
- 整体业务流程
- 使用场景
-
- [场景 1:公司办公](#场景 1:公司办公)
- [场景 2:家里上网](#场景 2:家里上网)
- [场景 3:开发测试](#场景 3:开发测试)
- 常见问题
-
- Q1:服务启动失败,提示端口被占用
- [Q2:客户端获取不到 PAC 文件](#Q2:客户端获取不到 PAC 文件)
- [Q3:修改了 proxy.pac 为什么不生效](#Q3:修改了 proxy.pac 为什么不生效)
- Q4:如何添加新的网站规则
- Q5:如何停止后台服务
- 快速参考
什么是 PAC 文件?
PAC(Proxy Auto-Config)文件是一个简单的文本文件,告诉浏览器:访问哪些网站走代理,哪些网站直接连接。
举个例子
- 访问百度、淘宝 → 直接连接(速度快)
- 访问 Google、YouTube → 走代理服务器(能访问)
这样就不需要手动切换代理,全部自动完成!
需要准备的文件
1. 主程序:agent-pac.py
python
# Created by johnny on 20240412
import os
import http.server
import socketserver
PORT = 22222
PACFILE_NAME = "proxy.pac"
def prepare_pac():
dir_path = os.path.dirname(os.path.abspath(__file__))
pacfile_path = os.path.join(dir_path, PACFILE_NAME)
try:
with open(pacfile_path, 'rb') as f:
return f.read()
except FileNotFoundError:
print(f"File {pacfile_path} not found.")
return None
class PacRequestHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/' + PACFILE_NAME:
pac_content = prepare_pac()
if pac_content is None:
self.send_error(404)
return
self.send_response(200)
self.send_header('Content-type', 'application/x-ns-proxy-autoconfig')
self.end_headers()
self.wfile.write(pac_content)
else:
self.send_error(404)
class ThreadingTCPServer(socketserver.ThreadingTCPServer):
allow_reuse_address = True
def main():
Handler = PacRequestHandler
with ThreadingTCPServer(("10.11.12.222", PORT), Handler) as httpd:
print("Serving PAC file on port", PORT)
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("Shutting down server...")
httpd.shutdown()
if __name__ == '__main__':
main()
2. 代理规则文件:proxy.pac
在同一个文件夹下创建 proxy.pac 文件,内容如下:
javascript
function FindProxyForURL(url, host) {
// 1. 公司内部网站直接访问
if (dnsDomainIs(host, ".company.com") ||
shExpMatch(host, "*.local")) {
return "DIRECT";
}
// 2. 国内网站直接访问
if (shExpMatch(host, "*.baidu.com") ||
shExpMatch(host, "*.taobao.com") ||
shExpMatch(host, "*.cn")) {
return "DIRECT";
}
// 3. 国外网站走代理
if (shExpMatch(host, "*.google.com") ||
shExpMatch(host, "*.youtube.com")) {
return "PROXY 10.11.12.222:8080";
}
// 4. 其他的默认直连
return "DIRECT";
}
说明:
DIRECT= 直接连接,不走代理PROXY 10.11.12.222:8080= 走代理服务器(请改成你的代理地址)- 可以添加更多网站规则
如何启动服务
第一步:准备文件
把下面两个文件放在同一个文件夹里:
/opt/pac-server/
├── agent-pac.py # 主程序
└── proxy.pac # 代理规则
第二步:修改配置
用记事本打开 agent-pac.py,找到这一行:
python
with ThreadingTCPServer(("10.11.12.222", PORT), Handler) as httpd:
把 "10.11.12.222" 改成你电脑的实际 IP 地址。
第三步:启动服务
在终端里执行命令:
bash
nohup python3 agent-pac.py &
命令说明:
nohup:让程序在后台运行,关掉终端也不会停止&:表示后台运行
第四步:检查是否启动成功
bash
netstat -tnpl | grep 22222
如果看到类似这样的输出,说明启动成功了:
tcp 0 0 10.11.12.222:22222 0.0.0.0:* LISTEN 12345/python3
常用操作命令
启动服务
bash
# 后台启动(推荐)
nohup python3 agent-pac.py &
# 后台启动并记录日志到指定文件
nohup python3 agent-pac.py > pac.log 2>&1 &
查看运行状态
bash
# 查看服务是否在运行
netstat -tnpl | grep 22222
# 查看进程
ps aux | grep agent-pac
# 查看日志
tail -f nohup.out
停止服务
bash
# 查找进程号并停止
ps aux | grep agent-pac
kill <进程号>
# 或者一键停止
pkill -f agent-pac.py
测试服务
bash
# 在服务器上测试
curl http://10.11.12.222:22222/proxy.pac
# 在其他电脑上测试(确保网络连通)
curl http://10.11.12.222:22222/proxy.pac
客户端如何使用
Windows 电脑设置
- 打开 设置 → 网络和 Internet → 代理
- 打开 使用设置脚本
- 填入地址:
http://10.11.12.222:22222/proxy.pac - 点击 保存
Mac 电脑设置
- 打开 系统偏好设置 → 网络
- 选择当前网络,点击 高级 → 代理
- 勾选 自动代理配置
- 填入地址:
http://10.11.12.222:22222/proxy.pac - 点击 好 → 应用
手机设置(iPhone/Android)
- 进入 Wi-Fi 设置
- 点击当前 Wi-Fi 后面的 ⓘ 或 修改
- 找到 代理设置 ,选择 自动
- 填入地址:
http://10.11.12.222:22222/proxy.pac - 保存
Chrome 浏览器设置
Chrome 使用系统代理,设置好系统代理即可。
也可以用命令行启动:
bash
chrome.exe --proxy-pac-url="http://10.11.12.222:22222/proxy.pac"
Firefox 浏览器设置
- 打开设置 → 网络设置
- 选择 自动代理配置 URL
- 填入:
http://10.11.12.222:22222/proxy.pac - 确定
整体业务流程
1.获取配置
返回规则
2.访问百度
3.访问Google
你的电脑/手机
PAC服务器
直接连接
代理服务器
Google网站
详细流程图
目标网站 代理服务器 PAC服务器 用户浏览器 目标网站 代理服务器 PAC服务器 用户浏览器 用户访问 www.baidu.com 用户访问 www.google.com 请求:http://10.11.12.222:22222/proxy.pac 读取 proxy.pac 文件 返回代理规则 检查规则:直连 直接访问 检查规则:走代理 通过代理访问 转发请求 返回内容 返回内容
使用场景
场景 1:公司办公
问题:公司内部系统和外部网站都要访问,手动切换代理很麻烦。
解决:
javascript
// 公司内网直接访问
if (dnsDomainIs(host, ".company.com")) {
return "DIRECT";
}
// 外网走公司代理
return "PROXY company-proxy.com:8080";
场景 2:家里上网
问题:想自动区分国内网站和国外网站,国内直连,国外走代理。
解决:
javascript
// 国内网站直连
if (shExpMatch(host, "*.baidu.com") ||
shExpMatch(host, "*.cn")) {
return "DIRECT";
}
// 其他走代理(访问国外网站)
return "PROXY 你的代理服务器:端口";
场景 3:开发测试
问题:开发和生产环境用不同的代理。
解决:
javascript
if (shExpMatch(host, "*.test.com")) {
return "PROXY test-proxy:8080";
}
if (shExpMatch(host, "*.prod.com")) {
return "PROXY prod-proxy:8080";
}
常见问题
Q1:服务启动失败,提示端口被占用
解决:
bash
# 查看谁占用了 22222 端口
netstat -tlnp | grep 22222
# 杀掉占用进程
kill <进程号>
# 或者修改端口(修改 agent-pac.py 里的 PORT = 22222)
Q2:客户端获取不到 PAC 文件
排查:
- 服务器上测试:
curl http://localhost:22222/proxy.pac - 其他电脑 ping 服务器:
ping 10.11.12.222 - 检查防火墙是否放行 22222 端口
Q3:修改了 proxy.pac 为什么不生效
原因:浏览器会缓存 PAC 文件。
解决:
- 重启浏览器
- Chrome 访问
chrome://net-internals/#proxy点击重新加载
Q4:如何添加新的网站规则
方法 :编辑 proxy.pac 文件,添加新的规则,保存即可。
示例:
javascript
// 让 GitHub 走代理
if (shExpMatch(host, "*.github.com")) {
return "PROXY 10.11.12.222:8080";
}
Q5:如何停止后台服务
bash
# 查找进程
ps aux | grep agent-pac
# 你会看到类似这样的输出:
# root 12345 0.0 0.1 ... python3 agent-pac.py
# 停止进程(12345 是进程号)
kill 12345
快速参考
文件清单
agent-pac.py # 主程序(启动服务)
proxy.pac # 代理规则(定义哪些网站走代理)
启动命令
bash
cd /opt/pac-server
nohup python3 agent-pac.py &
检查命令
bash
netstat -tnpl | grep 22222
客户端配置地址
http://10.11.12.222:22222/proxy.pac
(请把 IP 改成你的实际服务器 IP)