Skip to content

lukuochiang/ClashFox-Helper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ClashFox-Helper Logo

ClashFox Privileged Helper

这个仓库提供了一个自定义的 macOS Privileged Helper,用于让桌面应用安全地执行需要 root 权限的网络操作(代理、DNS、TUN 前置能力)。

clashfox-helper 的代码分析(简述)

从仓库结构和入口实现可以看出,它的核心是:

  1. helper 常驻运行于系统级权限(root)。
  2. 对外暴露本地 API(用于 GUI 进程发起控制请求)。
  3. 核心能力通过调用系统命令实现(例如 networksetup),从而切换代理或网络相关设置。
  4. 服务部署依赖 launchd(系统服务模型)。

本仓库沿用这一设计思想,并加入了生产向加固:

  1. 仅监听本地 Unix Socket(/var/run/com.clashfox.helper.sock)。
  2. 所有 API 必须携带 X-Helper-Token
  3. 调用方约束:读取 Unix Socket peer 的 uid/pid/path,仅允许策略文件中的调用方。
  4. 命令白名单:仅允许 networksetup / sysctl / pfctl 的受限子命令与参数。
  5. 参数收紧:代理地址仅允许 loopback(127.0.0.1/::1/localhost),DNS 数量限制 1..3。
  6. 失败回滚:修改代理/DNS 前先读当前值,执行失败自动恢复。
  7. 幂等语义:目标状态已满足时返回 ok=true, code=NOOP,不重复执行系统命令。
  8. 异常自愈:周期性比对并恢复 state.json 的目标状态。
  9. 基线恢复:首次变更前保存 baseline.json,支持一键恢复。
  10. 并发互斥:同一 network service 串行执行,避免竞态覆盖。
  11. 防刷限速:按调用方做窗口限流(过载返回 RATE_LIMITED)。
  12. 失败熔断:连续失败触发临时封禁(返回 CIRCUIT_OPEN)。
  13. 漂移告警:自愈前记录 expected/current 差异到审计日志。
  14. 安装原子升级:失败自动回滚到旧二进制与旧 plist。
  15. 卸载安全:卸载前自动尝试恢复 baseline,避免残留代理/DNS。
  16. 审计日志:记录调用方身份、动作、结果、状态快照。

功能

  • POST /v1/proxy/enable: 开启系统 HTTP/HTTPS/SOCKS 代理
  • POST /v1/proxy/disable: 关闭系统 HTTP/HTTPS/SOCKS 代理
  • GET /v1/proxy/status: 查询系统代理状态(HTTP/HTTPS/SOCKS/AutoDiscovery/PAC)
  • POST /v1/core/start: 启动 mihomo 内核
  • POST /v1/core/stop: 停止 mihomo 内核
  • POST /v1/core/restart: 重启 mihomo 内核
  • GET /v1/core/status: 查询 mihomo 运行状态
  • GET /version: 获取 helper 版本信息(version/commit/buildTime/launchedAt)
  • GET /health: 健康检查

构建

bash scripts/build-helper.sh ./build/com.clashfox.helper

版本来源:仓库根目录 VERSION.txt

安装为系统服务(需要管理员权限)

sudo bash scripts/install-helper.sh ./build/com.clashfox.helper

安装后:

  • 二进制: /Library/PrivilegedHelperTools/com.clashfox.helper
  • 启动项: /Library/LaunchDaemons/com.clashfox.helper.plist
  • Socket: /var/run/com.clashfox.helper.sock
  • Token: /Library/Application Support/ClashFox/helper/token
  • 调用策略: /Library/Application Support/ClashFox/helper/policy.json
  • 期望状态: /Library/Application Support/ClashFox/helper/state.json
  • 基线状态: /Library/Application Support/ClashFox/helper/baseline.json
  • 版本信息: /Library/Application Support/ClashFox/helper/version.json
  • 版本历史: /Library/Application Support/ClashFox/helper/version-history.log
  • 旧版本备份: /Library/Application Support/ClashFox/helper/releases/
  • mihomo pidfile: /Library/Application Support/ClashFox/helper/clashfox-core.pid
  • mihomo lockfile: /Library/Application Support/ClashFox/helper/clashfox-core.lock
  • mihomo log: /Users/<name>/Library/Application Support/ClashFox/logs/clashfox.log
  • mihomo 受控二进制: /Users/<name>/Library/Application Support/ClashFox/core/mihomo
  • mihomo 配置文件: /Users/<name>/Library/Application Support/ClashFox/data/default.yaml
  • 运行日志: /var/log/clashfox-helper.log
  • 审计日志: /var/log/clashfox-helper-audit.log

说明:helper 会优先按当前登录用户(/dev/console)解析 core 路径到:

  • /Users/<name>/Library/Application Support/ClashFox/core/mihomo
  • /Users/<name>/Library/Application Support/ClashFox/data/default.yaml
  • /Users/<name>/Library/Application Support/ClashFox/logs/clashfox.log 涉及 mihomo 的安装和更新由 GUI 自己管理,helper 仅负责启停重启与状态查询。

卸载

sudo bash scripts/uninstall-helper.sh

说明:卸载脚本会停止服务并删除已安装的二进制/plist。

调用示例

TOKEN="$(cat '/Library/Application Support/ClashFox/helper/token')"

curl --unix-socket /var/run/com.clashfox.helper.sock \
  -H "X-Helper-Token: ${TOKEN}" \
  -H "Content-Type: application/json" \
  -X POST http://localhost/v1/proxy/enable \
  -d '{"service":"Wi-Fi","host":"127.0.0.1","port":7890}'

# 可选:返回一次性状态快照,避免 GUI 再请求 /v1/proxy/status
curl --unix-socket /var/run/com.clashfox.helper.sock \
  -H "X-Helper-Token: ${TOKEN}" \
  -H "Content-Type: application/json" \
  -X POST "http://localhost/v1/proxy/enable?withStatus=1" \
  -d '{"service":"Wi-Fi","host":"127.0.0.1","port":7890}'

说明:service 字段可省略。未提供时,helper 会自动按默认路由接口解析当前主网络服务(例如 Wi-Fi/Ethernet)。
分端口可用:port/httpPort(HTTP)、httpsPort(HTTPS)、socksPort(SOCKS),并兼容 socks-portmixed-port 这类连字符字段。若仅提供 mixed-port,则三类代理都使用该端口。 /v1/proxy/enable/v1/proxy/disable 支持 query 参数 withStatus=1,开启后响应会携带 data(即代理状态快照)。

查询版本:

curl --unix-socket /var/run/com.clashfox.helper.sock \
  -H "X-Helper-Token: ${TOKEN}" \
  -X GET http://localhost/version

操作 mihomo 内核:

curl --unix-socket /var/run/com.clashfox.helper.sock \
  -H "X-Helper-Token: ${TOKEN}" \
  -H "Content-Type: application/json" \
  -X POST http://localhost/v1/core/start \
  -d '{"configPath":"default.yaml"}'

curl --unix-socket /var/run/com.clashfox.helper.sock \
  -H "X-Helper-Token: ${TOKEN}" \
  -X GET http://localhost/v1/core/status

curl --unix-socket /var/run/com.clashfox.helper.sock \
  -H "X-Helper-Token: ${TOKEN}" \
  -X POST http://localhost/v1/core/restart

curl --unix-socket /var/run/com.clashfox.helper.sock \
  -H "X-Helper-Token: ${TOKEN}" \
  -X POST http://localhost/v1/core/stop

说明:/v1/core/start 支持可选 JSON 参数 configPath(兼容别名 config),可传相对文件名(例如 OneSmart.yaml)或绝对路径。
当省略该参数时,默认使用 /Users/<name>/Library/Application Support/ClashFox/data/default.yaml
为安全起见,配置路径仅允许位于 /Users/<name>/Library/Application Support/ClashFox/data/ 目录下。

完整调用示例(精简版):API_DEMO.md

约束说明(已内置):

  • 只允许白名单二进制路径:/usr/local/bin/mihomo/opt/homebrew/bin/mihomo/Applications/ClashFox.app/Contents/Resources/mihomo
  • core 启动参数:-d /Users/<name>/Library/Application Support/ClashFox/core -f <selected-config-path>-f/v1/core/start 动态决定)
  • pidfile + lockfile 防止重复实例
  • pidfile 为结构化记录(pid+binary+startedAt),并校验 PID 对应二进制路径,降低 PID 复用误操作风险
  • 退出码写入审计日志(act=core_exit
  • 鉴权 token 使用常量时间比较,降低时序侧信道风险
  • 默认策略仅放行 ClashFox 客户端路径(不再默认放行 /usr/bin/curl
  • token 与 unix socket 默认采用 root + ACL(按 allowedUIDs 下发最小权限)
  • 启动前仅清理已有 Unix Socket;若路径存在但不是 socket 文件则拒绝启动(防误删/路径投毒)
  • 请求调用方需可解析 peer pid(SO_PEERPID),不可解析则拒绝

生产建议

  1. 若要对接 Apple 官方授权安装链路,建议使用 SMJobBless + 签名校验(Team ID / Requirement)。
  2. 若 GUI 和 helper 分离,建议改为 NSXPC 并在 helper 侧加 audit token 校验调用方签名。
  3. 按实际 App 安装位置维护 policy.json 中的 allowedClientPathPrefixes,避免误拦截。
  4. 版本兼容测试建议包含 macOS 12/13/14/15(尤其 networksetup 输出和 pfctl 状态解析差异)。

许可证

本项目采用 GNU GPL v3.0GPL-3.0-only)开源许可,详见仓库根目录 LICENSE

常用操作

开启系统代理(service 可省略,自动解析主网络服务):

curl --unix-socket /var/run/com.clashfox.helper.sock \
  -H "X-Helper-Token: ${TOKEN}" \
  -H "Content-Type: application/json" \
  -X POST http://localhost/v1/proxy/enable \
  -d '{"host":"127.0.0.1","port":7890}'

关闭系统代理:

curl --unix-socket /var/run/com.clashfox.helper.sock \
  -H "X-Helper-Token: ${TOKEN}" \
  -H "Content-Type: application/json" \
  -X POST http://localhost/v1/proxy/disable \
  -d '{}'

查询系统代理状态(service 可选):

curl --unix-socket /var/run/com.clashfox.helper.sock \
  -H "X-Helper-Token: ${TOKEN}" \
  -X GET "http://localhost/v1/proxy/status?service=Wi-Fi"

About

ClashFox Privileged Helper - The privileged helper enables advanced features like Enhanced Mode (TUN). It runs as a system service and requires administrator privileges to install.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors