# FoxPath **Repository Path**: yxd123456789/FoxPath ## Basic Information - **Project Name**: FoxPath - **Description**: GitHub 访问优化助手 · 本机网络分流 + PAC 精准接管 · 不依赖域名解析,直连当前实测可用的 GitHub 官方 IP · 免管理员、不改系统设置 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 3 - **Created**: 2026-10-09 - **Last Updated**: 2026-10-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 狐径 FoxPath > 作者:**海风(kele551)** · 仓库:https://github.com/kele551/FoxPath (Gitee 同名镜像:https://gitee.com/kele551/FoxPath ) ![License](https://img.shields.io/badge/license-MIT-blue) ![Platform](https://img.shields.io/badge/platform-Windows-blue) ![Version](https://img.shields.io/badge/version-v1.0.7-blue) ![Downloads](https://img.shields.io/github/downloads/kele551/FoxPath/total?label=downloads&color=green) GitHub 访问优化助手。本机网络分流 + PAC,不依赖域名解析,直连当前实测可用的 GitHub 官方 IP。 **主程序(`github_direct.py` / 发布的 exe)不用管理员权限,不改 hosts,不改系统 DNS。** 主程序从代码到运行都不碰 `hosts` 文件:它只把代理设置写进当前用户的注册表(HKCU), 代理范围与还原方式见下面「原理」「核心机制」两节。 > ⚠ 仓库里另有一个**独立的历史脚本** `Fix-GitHub.ps1`(配合 `Run-GitHubFix.bat`): > **只有它会改 `hosts`** —— 直接往系统 `hosts` 里钉 IP + 装一个计划任务定时换 IP, > **需要管理员权限**。它是上一代做法,与主程序**不共享代码、也不会一起运行**: > 用主程序就不需要它,两者**二选一**,别同时用(同时用会互相打架)。详见下方文件表。 ## 目录 - [解决什么问题](#解决什么问题) - [原理](#原理) - [用法](#用法) - [核心机制](#核心机制) - [从源码构建](#从源码构建) - [发版前自检(发布闸门)](#发版前自检发布闸门) - [已知边界](#已知边界) - [版本记录](#版本记录) - [联系与反馈](#联系与反馈) - [代码签名政策](CODE_SIGNING_POLICY.md) - [贡献指南](CONTRIBUTING.md) · [安全政策](SECURITY.md) - [路线图(Roadmap)](#路线图roadmap) · [参与贡献与治理](#参与贡献与治理) - [许可](#许可) ## 解决什么问题 国内访问 github.com 时通时断,典型症状: - 浏览器转圈半天最后超时,但手机开流量却能正常打开 - `api.github.com` 一直是通的,只有 `github.com` 网页打不开 - 手动往 hosts 里钉 IP,过两天又失效 根因通常不在网络本身,而在**本地域名解析出来的那个 GitHub IP 在当前线路上不通**。浏览器按解析结果走,就会卡住。 狐径不查 DNS——它自己拿着一批 GitHub 官方 IP 逐个实测握手,挑能用的直连。 ## 原理 ``` 浏览器 ──PAC──> 狐径本地代理 127.0.0.1:8787 ──> 实测可用的 GitHub 官方 IP (接管 github.com + raw/附件 + Pages) (不依赖域名解析) ``` | 传统做法 | 狐径 | | --- | --- | | 改 hosts(要管理员、IP 死了就失效) | 本机代理 + PAC,写在 HKCU,普通用户权限即可 | | 依赖系统 DNS 解析 | 不查 DNS,直连实测能用的官方 IP | | IP 失效后彻底打不开 | 每 5 分钟重测一轮,死 IP 自动换 | | 程序退出后系统代理指向空端口,比原来更糟 | 退出/点「退出并还原」都会还原;PAC 带 `DIRECT` 兜底;还有 `--restore` 一键收尾 | ## 用法 1. 从 [Releases](https://github.com/kele551/FoxPath/releases) 下载 `FoxPath.exe` 2. 双击运行 → 浏览器自动打开控制面板 `http://127.0.0.1:8788/ui` 3. 勾选「开机自启」即可后台常驻 **首次启动请等 15~20 秒**:程序要并发体检 49 个候选 IP,体检完成前代理还没完全生效。 ### 控制面板上有什么 控制面板 `http://127.0.0.1:8788/ui`,从上到下四块: | 区块 | 显示什么 | 能做什么 | |---|---|---| | **版本与升级** | 当前版本 `=====>` 新版本(没有新版时右边是 `—`);最下面一行是 **上次升级结果**(成功/失败 + 时间 + 失败原因) | `检查更新` 问一次升级源;真有新版才出现 `立即升级`。点了以后自动下载 → 校验 SHA256 → 覆盖 exe → 重启,下面一条渐变色进度条跟着走。卡片里另有 `自动升级`、`升级结果气泡` 两个勾选框(**都默认开**) | | **加速状态** | 出口 IP(含延迟)、加速状态(已启用 / 未启用)、上次体检时间 | `启用加速`、`停用并还原`、`立即重测`、`退出并还原`,以及 `开机自启` 勾选框 | | **当前可用 IP** | 按延迟排序的可用 IP 表,每 5 分钟自动刷新 | 看当前线路还剩几个能用。一个都没有时会自动重拉官方 IP 表并回退系统 DNS —— 反馈问题时把这栏的数字一起贴上 | | **日志** | `foxpath.log` 的尾部,自动滚到最新 | 打不开 GitHub 先看这里 | > 升级不用手动换文件:新版下完先校验 SHA256,通过后交给一个小助手 —— > 让旧程序退出并还原系统代理 → 覆盖 exe → 自动重启。校验不过就放弃,不会留半成品。 > 从 v1.0.3 起文件名不再带版本号(固定 FoxPath.exe),**版本号写进 exe 的属性里**(鼠标悬停或右键-属性-详细信息可见)。 > 下载文件名故意用 ASCII(`FoxPath.exe`)。GitHub / Gitee 上传附件时会把中文 > 文件名改坏(实测 `狐径-v1.0.0.exe` 传上去变成了 `-v1.0.0.exe`),所以对外一律用 ASCII 名。 **出过问题想自救**:`FoxPath.exe --restore` 只做一件事 —— 把系统代理里本程序留下的 PAC 设置清掉,不起代理、不开面板。万一程序被强杀、或者你直接把 exe 删了但 `AutoConfigURL` 还指向 `127.0.0.1:8788`,跑这一条就能收干净。 **日志在哪**:`%LOCALAPPDATA%\FoxPath\foxpath.log`(exe 是无窗口的,屏幕上什么都看不到, 有问题先看这个文件)。 ## 核心机制 - **体检**:每 5 分钟并发重测候选池,条件是 TCP 443 握手 + TLS 证书校验 + HTTP 首包必须返回 2xx/3xx。 最后这条很关键——有些 IP 证书是对的,但只服务 API/CDN,访问 github.com 首页会返回 400,必须过滤掉。 - **候选池刷新**:定期从 `api.github.com/meta` 重拉 GitHub 官方公布的 IP 段,官方换 IP 了也能跟上。 - **自愈**:候选全部失效时,依次尝试重拉官方表 → 查询系统 DNS → 放宽超时重测。三步都不通才判定真不通,此时退回系统解析(和没装本程序一样,不会更糟)。 - **退出安全**:正常退出和**静默模式(开机自启)**都会把系统代理恢复成运行前的状态; 还原备份固定存在 `%LOCALAPPDATA%\FoxPath\proxy-backup.json`(不再依赖 exe 同级是否可写); 备份写不进去时**不会**去改注册表(宁可不开,也不留下无法还原的状态)。 另有一条 `--restore`:即使备份没了、程序也删了,也能把残留的 PAC 设置收干净。 - **在线升级**:控制面板最上面那张卡片里检查更新,升级源读仓库的 `version.json`(Gitee raw 优先、GitHub 兜底); 新版下到 `.new`、比对 SHA256 通过后才交给小助手覆盖并重启。程序没有"安装"这一步,升级就是换 exe。 升级**成功或失败**都会在屏幕右下角弹一次气泡提醒(成功 =「狐径已自动升级到 vX.Y.Z」, 失败 = 一句人话 + 怎么重试),几秒后自己消失、不用点、不打断你;**平时不弹**(已是最新版、或没在升级时不弹)。 不想要气泡就在面板「版本与升级」卡片里取消勾选 `升级结果气泡`(设置里的 `notify_bubble`,默认开)—— 关掉后升级结果仍会留在卡片里的「上次升级结果」那一行。 - **单实例**:用 Windows 命名互斥保证只有一个实例;重复双击不会起两个进程去抢 8787/8788。 ## 从源码构建 ```bash pip install pyinstaller python build_exe.py # 打包成 FoxPath.exe ``` 主程序**零第三方依赖**(只用 Python 标准库),打包额外需要 `pyinstaller`, 发布流水线 `tools/publish.py` 需要 `requests` —— 依赖口径见仓库根目录的 `requirements.txt`。 > 图标不用管:`app.ico` 已经入库。仓库里那几个 `create_icon*.py` / > `make_icon_from_user_image.py` 是当初做图标用的一次性脚本,里面的输入输出路径都写死在 > 作者本机(还有一个依赖本机剪贴板缓存),**在别的机器上跑不通**,正常构建不需要它们。 | 文件 | 说明 | | --- | --- | | `github_direct.py` | 主程序:代理、PAC、体检、控制面板(推荐用这个) | | `Fix-GitHub.ps1` | **历史脚本,仓库里只有它会改 `hosts`**:往 `hosts` 里钉 IP + 装计划任务定时换;**需要管理员权限**,与主程序二选一(主程序不碰 `hosts`) | | `Run-GitHubFix.bat` | 以管理员身份拉起 `Fix-GitHub.ps1`(会弹 UAC) | | `build_exe.py` | PyInstaller 打包脚本 | | `make_version_json.py` | 生成升级源 `version.json`(版本号 + exe 指纹 + 字节数) | | `tools/preflight_release.py` | **发版前自检闸门**(发布前必须全绿),见下方「发版前自检」 | | `tools/compare_ips.py` | 把内置候选 IP 与 GitHub 官方 `meta` 网段对照(排查用) | | `tools/publish.py` | 一键发布流水线(Gitee 主 + GitHub 镜像),内置自检闸门 | | `requirements.txt` | 依赖口径:主程序零第三方依赖,只有发布脚本需要 `requests` | | `make_icon_from_user_image.py` | 图标生成(抠图 + 圆角底 + 多尺寸 ICO) | | `app.ico` | 程序图标 | | `release-notes.md` | 发行说明 | | `使用说明.txt` | 中文使用说明 | 打包注意: - PyInstaller 的 `--clean` 参数在某些受限环境下会因批量删缓存被拦,脚本里已去掉。 - 产物名与版本号都从 `github_direct.py` 的 `APP_VERSION` 推导,只有一个来源,不用改两处。 - **`.ps1` 文件必须保存为「UTF-8 带 BOM」**。PowerShell 5.1 对没有 BOM 的文件按 ANSI 读, 中文会变乱码,字符串/花括号被破坏后直接 ParserError —— `Fix-GitHub.ps1` 在 v1.0.1 之前 就是这样:文件本身完整,但因为没有 BOM 而**从未成功运行过**。 ## 发版前自检(发布闸门) **发版前自检脚本随仓库提供,位置 `tools/preflight_release.py`**(同目录的 `tools/compare_ips.py` 用于对照官方 `meta` 网段排查候选 IP): ```bash python tools/preflight_release.py # 默认拿仓库根目录的 FoxPath.exe 当候选 python tools/preflight_release.py --help # 看全部开关 python tools/preflight_release.py --dry-run # 只跑静态项:不写注册表、不拉程序、不碰系统代理 ``` 检查内容: | 类别 | 检查什么 | | --- | --- | | 版本一致性 | exe 文件版本 = 源码 `APP_VERSION` = `version.json` 版本,且 `version.json` 的 `sha256` / `size` 与候选 exe 对上 | | 冷启动演练 | 把候选 exe 复制成「刚下载落地」的样子,立刻用隐藏 PowerShell 启动,必须在限定时间内起来 | | 完整升级演练 | 旧版 → 本地升级源 → 检查更新 → 立即升级 → 必须自己起来(起不来则必须「重试过 + 明确提示用户」),并核对换上去的文件**指纹**等于候选 | | 失败分支 | 升级源里的 `sha256` 故意写错 → 必须拒绝并保留旧版 | | 接口与还原 | `/pac` 纯 ASCII、`/api/diag` 正常、非法 IP 被拒、连点两次启用不污染系统代理备份、退出后注册表还原、不留垃圾 | | 一致性警告(WARN) | ① 工作区副本与仓库副本 `tools/preflight_release.py` 的 **sha256 是否一致**(两份漂移了就警告);② **两平台发行版附件 SHA256 是否一致**(Gitee 请求间隔 ≥3 秒限速;网络或平台异常只警告,不判红) | > 自检会真的改注册表、拉起本机已装的狐径(结束时再把它重新启动),所以**别在有正式发布任务之外随手整轮跑**; > 只想确认脚本自己没坏,用 `--dry-run`(只做静态检查)。 > 警告级(WARN)不阻断发布,但会在结尾单独列出来,发布前应当看一眼。 > `tools/publish.py release` 已内置这道闸门:自检不全绿直接中止发布(`--skip-preflight` 只留给线上事故回滚,且要在 `logs\` 写明原因)。 ## 升级时请注意 - **不会把「降级」当「升级」**:升级前按版本号语义比较(`1.0.10 > 1.0.9` 这种也算得对), 只有线上确实比本地新才会提示「发现新版本」;线上不比本地新时,面板直接说明是 「已是最新版」还是「本地版本比线上新(线上尚未发布)」,**「立即升级」按钮置灰, 服务端也会拒绝执行**,日志里写一行「拒绝降级」。 - **升级失败会自动回滚**:新版连续起不来时,小助手会把旧版本放回去并重新启动它, 日志里能看到三步(覆盖失败 / 回滚 / 旧版已起来),**不会再出现「升级之后程序没了」**。 - 升级完成后程序会**自动重新打开**;万一它没有出现,**双击一下 `FoxPath.exe` 就能正常使用** —— 升级本身是完成的。程序退出前已经还原好系统代理,**不会影响上网,也不会让浏览器出错**。 - **历史说明更正(2026-10-09)**:v1.0.7 之前,这类「升级后起不来」曾被归因为杀毒软件拦截 (火绒实测)。真因已查清:升级小助手是从主程序里起的,会继承单文件 exe 的 `_PYI_*` 环境变量, 新版本的引导程序据此误判「已经解过包」,于是去找那个已被删掉的临时目录, 结果 `Failed to load Python DLL`。**该问题自 v1.0.7 起修复**(起新版本前先擦掉这些变量)。 - **从 v1.0.6 升到 v1.0.7 这一跳**用的仍是老版小助手(不重试、不回滚),所以**仍可能失败一次**; 失败了双击 `FoxPath.exe` 即可。**从 v1.0.7 往后,升级全程带护栏。** ## 已知边界 - 代理 `github.com` / `www.github.com`,以及 **`raw.githubusercontent.com` / `objects.githubusercontent.com`**(raw 文件与发布附件下载,v1.0.6 起)。 后两个走**专属 IP 池**(官方 `185.199.108.0/22`):以前不代理它们,是因为塞进 `github.com` 的池子会连到错误服务器、页面脚本全废 —— 那是池子不对,不是「不能代理」。 - **仍然直连**:`avatars.githubusercontent.com` / `camo.githubusercontent.com` / `githubassets.com`。这些是页面渲染用的,保持直连最稳,也避免重演当年的坑。 - 不代理 `api.github.com`(本来就通),Git 命令行操作不受影响。 - 绿色单文件,无需安装;但**不能**用 `nohup ... &` 在 shell 里后台启动,那样命令结束进程会被终止。要常驻就双击运行或开开机自启。 - 如果程序被**强制结束**(任务管理器结束进程、关机时强杀),`atexit` 不会执行,系统代理可能仍指向本程序。 下次启动本程序会自动接管;如果不再用了,跑一次 `--restore` 即可收干净。 - 控制面板只监听 `127.0.0.1`,不对局域网开放;接口已做 Host/Origin 同源校验(挡网页 CSRF 与 DNS rebinding), 但没有做用户鉴权 —— 本机上以你的身份运行的程序仍然可以调用它。 - **如果你原本设了「静态代理」(Internet 选项里手动填的代理服务器)**:一旦启用本程序,PAC 会优先于静态代理, 而你手动设的那个代理在启用期间不再生效(其它网站会直连)。停用/退出时会自动还原。程序检测到这种情况会在 日志里明确写一行提醒。 - 遇到端口被占用、启动失败等情况,exe 会弹一个错误框并写明日志位置,不再"点了没反应"。 - **两个平台发行版的附件个数可能不一样**:Gitee 侧比 GitHub 侧多一个中文名演示视频 (`演示视频-狐径.mp4`),GitHub 侧只有 ASCII 名的 `FoxPath-demo-v1.0.6.mp4` —— 这是**已知差异** (中文文件名在部分平台下载下来会乱码,所以对外链接一律给 ASCII 名)。 两个核心附件 `FoxPath.exe` / `version.json` 两平台逐字节一致;每次发布都会把附件下载回来比对 SHA256。 ## 版本记录 > 当前对外发布版本是 **v1.0.6**(2026-10-08,Gitee 与 GitHub 同步;v1.0.6 之后本地另有未发布的小改动, > 攒到下一个功能版一起发)。`v1.0.2` ~ `v1.0.4` 是本机迭代版本,未单独发版,改动已一并进 v1.0.5。 | 版本 | 日期 | 说明 | | --- | --- | --- | | v1.0.0 | 2026-09-19 | 首个版本:本地代理 + PAC、每 5 分钟 IP 体检、候选池自动刷新、全灭自愈、退出还原 | | v1.0.1 | 2026-09-22 | 修「还原不了系统代理」一类缺陷:重复启用不再污染备份、备份失败不再改注册表、静默模式也注册退出还原、加单实例与端口占用提示、日志落文件、新增 `--restore`;`Fix-GitHub.ps1` 补 UTF-8 BOM(此前无法运行);打包脚本改为 ASCII 产物名 + 版本号单一来源;修正文档与实现不一致之处 | | v1.0.2 | 2026-09-22 | 修「双击没反应」:程序已在后台时,第二次双击改为**直接打开正在运行的控制面板**再退出(以前只写一行日志就静默退出,用户以为程序坏了) | | v1.0.3 | 2026-09-22 | 重做图标(去白底卡片、清掉残留边框、裁到狐狸本体居中放大,重出七档尺寸);产物改名 `FoxPath.exe` 不带版本号,版本号写进 exe 属性 | | v1.0.4 | 2026-09-22 | 加作者署名(源码文件头、控制面板底部、日志、exe 属性、README 统一为「海风(kele551)」);README 里的私人邮箱换成 Issues 链接 | | v1.0.5 | 2026-09-22 | **网页版在线升级**:控制面板里检查更新、版本迁移动画 + 渐变色进度条,下载到 `.new` 校验 SHA256 后由独立小助手接管(先让旧程序退出并还原系统代理 → 覆盖 → 重启) | | v1.0.6 | 2026-10-08 | **联通/移动友好**:内置候选池扩到官方全量 45 个 IPv4;IP 表三源依次兜底(官方 `meta` → Gitee 上的 `meta.json` → GitHub raw);`raw.githubusercontent.com` / `objects.githubusercontent.com` 改走**专属 IP 池**(官方 `185.199.108.0/22`),raw 文件与发布附件也能加速(回应 Issue #1);429 限流视为存活(实测可用 19/49 → 31/49);面板新增「线路体检」与「手动指定 IP」;升级小助手加固(覆盖后轮询确认新实例真的起来、递增重试、失败弹窗提示手动双击);对外文案措辞中性化 | 详细发行说明见 [release-notes.md](release-notes.md)。 ## 联系与反馈 遇到打不开、体检全灭、或者觉得哪里不好用,欢迎直接提 Issue,我会看: [GitHub Issues](https://github.com/kele551/FoxPath/issues) · [Gitee Issues](https://gitee.com/kele551/FoxPath/issues) 反馈时如果能顺手附上控制面板里「当前可用 IP」那一栏的数字,定位会快很多。 ## 许可 MIT ## 路线图(Roadmap) 按优先级从高到低,都是已经排进计划、能落到代码上的事: 1. **自动升级 + 升级结果气泡(代码已就绪,待发版)**:启动后静默检查新版本,**默认自动下载、校验 SHA256、替换并重启,不弹确认框**; 设置里的 `auto_update` 可以关掉,关掉后回到"发现新版只在面板提示一句"。三道护栏:只对打包版 exe 生效、只认 https 升级源、同版本 24 小时内最多 2 次。 升级**成功或失败**会弹一次气泡并在面板留一行状态,详见「核心机制 → 在线升级」。 2. **IPv6 实测地址池**:候选池目前只有 IPv4(内置 45 个 + 官方 `meta` 补充)。 要加的是"真的握手成功过才入池"的 IPv6 地址,而不是把段表直接塞进去。 3. **线路自适应**:按当前线路的历史成败给候选排序,换网(宽带 ↔ 热点)后不从头再摸一遍。 4. **代码签名申请**:产物已自带 SHA256 与可复现构建说明,下一步申请免费代码签名, 缓解"首次运行被安全软件拦一下"的体验问题。详见 [CODE_SIGNING_POLICY.md](CODE_SIGNING_POLICY.md)。 > 路线图只列真实在办的事,做完一项改一项;临时想到的、还没验证的想法不写在这里。 ## 参与贡献与治理 | 项目 | 说明 | | --- | --- | | 维护者 | [@kele551](https://github.com/kele551)(海风),一人维护,同时担任提交者、审查者与发布批准者 | | 响应预期 | Issue / PR 一般 **7 天内**给第一次答复;安全类问题按 [SECURITY.md](SECURITY.md) 私下走,**3 天内**响应 | | 许可 | MIT(见 [LICENSE](LICENSE));提交贡献即表示同意按同一许可发布 | | 怎么参与 | 提 Issue / PR 之前先看 [CONTRIBUTING.md](CONTRIBUTING.md):Issue 模板、PR 流程、代码风格、本地构建与自查、提交信息规范都在里面 | | 安全 | 漏洞请**不要**开公开 Issue,按 [SECURITY.md](SECURITY.md) 私下报告 | | 发布纪律 | 主程序零第三方依赖;每次发布都要先跑发版前自检 `tools/preflight_release.py`(版本一致性、冷启动演练、升级演练、失败分支、退出还原)全绿,才允许上传附件 | | 合规 | 本项目的法律与知识产权边界见 [COMPLIANCE.md](COMPLIANCE.md):只在本机运行、不提供代理服务、只连接服务方公开地址、不采集用户数据;不使用他人商标作为品牌名 |