OpenSurge-for-Mac
OpenSurge for Mac
把 Mac 变成可导入规则、可按设备分流的全屋透明代理网关——支持 DHCP/DNS 自动接管
简体中文 · English
下载 · App 指南 · 能力 · 每设备策略 · Web GUI · Agent 工作区
|
|
OpenSurge for Mac 是一个开源的 Surge 风格 macOS 网关与控制面。它把 Mac 变成 整个局域网的代理出口:同一网络下的手机、电视、PS5、游戏机、VR 设备、虚拟机等终端, 都可以从 Mac 获取 DHCP/DNS,并共享由策略控制的网络连接;你也可以为每台设备 单独配置不同的出口策略:手机走代理、游戏机直连,设备啥都不用配。
- 可导入已有的 mihomo 配置或订阅,保留原有节点、代理组和规则
- Web GUI 实时展示每台设备的连接、上下行流量和实际出口链;菜单栏随时查看网关状态与恢复提醒。
底层由 dnsmasq 提供 DHCP/DNS,mihomo 作为代理引擎,macOS pf 与 IPv4 forwarding 提供原生网关路径。
这个仓库也被有意设计成一个 AI Agent 友好工作区:项目知识与代码一起版本化,高风险 网络行为有可执行的证据门槛,Virtual Lab 与真实设备产生的证据会回流到下一轮工程 循环。
友好的 App 体验
- 通过 macOS 菜单栏 App 随时查看状态、接收网络恢复提醒并打开本地 Web GUI;再次打开
/Applications/OpenSurge.app会直接展开与菜单栏图标相同的状态面板; - 在一个控制面中完成订阅导入、网络设置、设备分流、节点健康、连通性检查与诊断;
- 使用恢复状态机引导局域网 DHCP 接管的启动、客户端验收、停止和网络恢复。
第一次使用请参阅 OpenSurge for Mac App 使用指南。
网关与代理
- 启停 DHCP/DNS、mihomo、pf NAT 与 IPv4 forwarding,并带 rollback;
- 通过 mihomo
mixed-port提供显式代理; - 通过 mihomo TUN 提供 macOS 透明代理;
- DHCP 接管模式为登记设备生成 MAC 绑定的固定 IPv4 租约;旁路由模式(手工网关) 使用主路由侧保持稳定的静态 IPv4,两者都可使用独立出口策略。
可观测性
- 把活跃会话流量归属到 DHCP 设备或同 LAN 的静态登记/当前观察设备,显示每设备 连接数、实时上下行速率、累计字节与占主要流量的 mihomo 出口链;
- 集中检测代理节点可达性/延迟,并从健康视图切换已应用的 Selector;
- 通过 applied mihomo mixed-port 路径探测固定真实服务目录,展示三轮中位延迟、 命中规则与实际出口链;
- 查看与切换策略组、查看 imported proxy/rule provider 状态、查看当前连接;
- 输出文本/JSON 形式的 status / doctor / logs / snapshot,并收集允许局部失败的 JSON snapshot 供诊断与 UI 使用。
安全与验证
- 配置校验、TUN-only 透明代理、rollback 与明确的恢复契约;
- 在接触普通 LAN 前,先用隔离的虚拟 LAN lab 验证高风险网络行为。
每设备策略
一个 mihomo 进程可以对已登记的 LAN 设备应用独立策略。DHCP 接管模式会为每台设备
配置 MAC 绑定的固定 IPv4 租约;旁路由模式则使用主路由侧保持稳定的静态
IPv4,并从当前经过 Mac 的流量与 ARP 邻居观察辅助登记。两种模式都会生成每设备的
mihomo selector group 和 SRC-IP-CIDR 规则。可选 JSON 策略文件让每台设备要么跟随 Mac/全局规则,要么在
全局规则之前走设备专属 selector;它也支持 REJECT 这类设备专属动作,以及按
域名/IP/协议/端口/rule-provider 叠加的规则覆盖。dedicated 模式下,本地/私有目标
保持直连。
OpenSurge 有意不内置家庭模板或第三方规则列表;策略内容由操作者提供,空 starter 文件也是合法配置。JSON 模型、优先级、CLI 命令和验证边界见 每设备策略覆盖。
Web GUI 与菜单栏 App
通过安装包使用 OpenSurge 时,请从 OpenSurge for Mac App 使用指南开始。
本地 Control API、React Web GUI 和只读 SwiftUI 菜单栏 launcher 已进入仓库。开发构建:
make web-install
make control-build
./bin/opensurge-control --config examples/config.example.yaml
make menubar-build
控制服务只监听 127.0.0.1,启动时会输出一次性 Web GUI 链接。菜单栏 App 显示
状态、恢复警报并打开 Web GUI,不提供网关 start/stop 或策略切换。它区分“只退出菜单栏
App”和“退出 OpenSurge”:后者只在网关数据面已经停止时退出菜单栏 App 与用户级
Control Service;系统 launchd 托管的 root Helper 保持空闲加载,下次打开无需再次授权。
架构、安全边界与构建说明见 Web GUI 与菜单栏 App。
Web GUI 内置 applied 网关策略路径的连通性页面,并提供 Net.Coffee 的独立浏览器本机
检测入口;两者都不会被描述成下游设备 DHCP/DNS/TUN 路径已经验收。
make gui-installer 会在取得真实 mihomo、dnsmasq 二进制后构建 macOS 安装包。
Developer ID 签名和 notarization 必须显式提供发布凭据。GitHub 正式发布同时提供文件名中
明确带有 arm64-unsigned.pkg 与 x86_64-unsigned.pkg 的架构专用构建,但不能把正式
Release 描述成已经签名、已经 notarize 或可被 Gatekeeper 直接放行的安装包。
安装 GitHub 未签名正式发布包
当前正式发布同时提供 Apple Silicon 与 Intel Mac 安装包。请从对应 GitHub Release 下载
arm64-unsigned.pkg(Apple Silicon)或 x86_64-unsigned.pkg(Intel),以及
SHA256SUMS。可运行 shasum -a 256 -c SHA256SUMS 核对已下载文件,并使用以下命令
验证所选安装包的 GitHub 构建来源:
gh attestation verify OpenSurge-for-Mac-*-arm64-unsigned.pkg \
-R YTwsy/OpenSurge-for-Mac
gh attestation verify OpenSurge-for-Mac-*-x86_64-unsigned.pkg \
-R YTwsy/OpenSurge-for-Mac
双击安装包。如果 Gatekeeper 阻止安装,进入系统设置 → 隐私与安全性,选择
仍要打开并完成身份验证,然后再次打开同一个安装包。不要全局关闭 Gatekeeper,
也不要递归删除 quarantine。使用管理员账户完成 Installer 后,从 /Applications
打开 OpenSurge。安装过程会启动本地 helper 与 Control Service,但网关
仍保持停止,只有在控制面中明确操作才会启动。
pkg 升级会在同一 LAN DHCP 恢复未完成时拒绝执行。替换 payload 前,preinstall 先停止
用户级 Control Service 与菜单栏 App,再使用当前已安装的 omg stop 清理网关,最后
卸载 root helper。升级会保留现有配置、导入源、策略数据和 runtime 历史;只有首次安装
才会用包内示例生成 config.yaml。
透明代理
macOS 上支持的透明代理路径是 TUN。mihomo redir-port 和 PF TCP 重定向被
有意禁用,因为当前 Darwin 构建在运行时报告 redir 不受支持。请保持
mihomo.redir_port 和 pf.redirect_tcp_to 为 0,并通过
transparent.mode: "tun" 启用透明代理。
mihomo profile
OpenSurge for Mac 可以渲染托管的 mihomo 配置,也可以导入已有 mihomo profile。
在 imported 模式下,OpenSurge 仍然接管 LAN 绑定、allow-lan、DNS 监听与
fake-IP 网段、TUN、external-controller 和 runtime 路径等网关关键字段。导入的
profile 会贡献 proxies、proxy-providers、proxy-groups、rule-providers、
rules,以及不改变网关边界的 DNS 解析器/过滤字段。保留
nameserver-policy、proxy-server-nameserver、fake-ip-filter 等字段,可以让依赖
专用 DNS 的代理节点域名继续正确解析,同时不允许 profile 替换网关 DNS 监听或
TUN DNS 契约。
mihomo:
profile_mode: "imported"
profile: "./profiles/home.yaml"
相对形式的 mihomo.profile 会基于 OpenSurge 配置文件所在目录解析。导入的
proxy-providers 和 rule-providers 内部如果有相对 path:,会基于被导入的
mihomo profile 所在目录解析。OpenSurge 会渲染 profile.store-selected: true,
让 mihomo 可以跨重启保存策略组选择。
启动网关服务前,可以先预览最终生成的 mihomo 配置:
go run ./cmd/omg doctor --config examples/config.imported-profile.example.yaml
go run ./cmd/omg render-mihomo --config examples/config.example.yaml
go run ./cmd/omg render-mihomo --config examples/config.imported-profile.example.yaml
当 mihomo.binary 指向已安装的 mihomo 二进制时,可以使用
validate-mihomo。它会渲染最终配置,并运行 mihomo 自己的 -t 校验,但不会
启动网关服务。
go run ./cmd/omg validate-mihomo --config examples/config.imported-profile.example.yaml
CLI 使用方式
下面的命令适合开发、自动化和诊断。普通安装包用户可以直接使用 App 使用指南中的图形界面流程。
状态与诊断
go run ./cmd/omg doctor --config examples/config.example.yaml
go run ./cmd/omg status --config examples/config.example.yaml
go run ./cmd/omg status --config examples/config.example.yaml --format json
go run ./cmd/omg logs --config examples/config.example.yaml --tail 50 --format json
go run ./cmd/omg snapshot --config examples/config.example.yaml --tail 50 --format json
策略、设备与 Provider
go run ./cmd/omg policies --config examples/config.imported-profile.example.yaml
go run ./cmd/omg policy-select \
--config examples/config.imported-profile.example.yaml \
--group Proxy \
--policy DIRECT
# 配置 device_policy.file 后:
go run ./cmd/omg devices --config ./config.yaml --format json
go run ./cmd/omg device-policy-select \
--config ./config.yaml \
--device alice-phone \
--slot default \
--policy DIRECT
go run ./cmd/omg connections \
--config examples/config.imported-profile.example.yaml \
--format json
go run ./cmd/omg providers \
--config examples/config.imported-profile.example.yaml \
--format json
go run ./cmd/omg provider-update \
--config examples/config.imported-profile.example.yaml \
--provider demo-provider \
--format json
配置渲染
go run ./cmd/omg render-mihomo --config examples/config.example.yaml
go run ./cmd/omg validate-mihomo \
--config examples/config.imported-profile.example.yaml
网关生命周期
以下操作会修改 DHCP、DNS、PF、IPv4 forwarding 或 mihomo 运行状态,需要 sudo:
sudo go run ./cmd/omg start --config examples/config.example.yaml --format json
sudo go run ./cmd/omg reload --config examples/config.example.yaml --format json
sudo go run ./cmd/omg restart-mihomo --config examples/config.example.yaml --format json
sudo go run ./cmd/omg stop --config examples/config.example.yaml --format json
补充说明:
policy-select会读取 live mihomo 策略组,并在发送切换请求前拒绝未知 group 或 policy;provider-update --provider <name>会请求 mihomo 刷新指定 proxy provider,并返回 刷新后的 provider 状态;logs --tail N --format json会返回最近的 dnsmasq 和 mihomo 日志行,并标出每个 日志文件的存在状态和读取错误;snapshot --format json会聚合 status、doctor、leases、日志、策略组、连接和 provider 状态;mihomo API 失败不会阻止其余 snapshot 返回;restart-mihomo只重启代理核心,不会停止 dnsmasq、卸载 PF、恢复 IPv4 forwarding 或修改本机网络设置;--format json会保留非零失败退出码,并在 stderr 输出结构化错误。成功的start和stop会返回包含command、ok和config_path的 payload。
AI Agent 友好工作区
OpenSurge 把仓库本身也视为工程系统的一部分,而不只是存放代码的地方。目标是让 产品意图、网络安全规则、运行时证据与积累下来的项目知识,都能被人类贡献者和 Coding Agent 直接理解和使用。
Harness Engineering:设计 Agent 周围的工程环境
这个工作区实践了 Harness Engineering 的核心思想: Agent 是否可靠,不只取决于模型,还取决于模型周围的上下文、约束、工具、可观测性 与验收门槛。
AGENTS.md是精简的入口地图:它定义产品身份、硬性网络不变量,并告诉 Agent 针对不同任务必须继续阅读哪些文档。docs/agent-wiki/以渐进披露的方式提供架构、决策与 验证上下文,避免每个任务都从全仓库重新拼装心智模型。status、doctor、logs、snapshot等机器可读 CLI,加上确定性的make入口与保留的 artifacts,让 Agent 能直接观察正在运行的系统。- 配置校验、只允许 TUN 的透明代理、rollback、隔离 Lab 与明确的恢复契约,把安全 指引变成可以执行和检查的边界。
Loop Engineering:用可执行证据闭环
OpenSurge 实践 Loop Engineering 的核心:设计一套 能够反复执行、观察、验证、恢复,并把结果带入下一轮的系统,而不是依赖一次写得很 漂亮的 prompt。
目标 + 约束
↓
AGENTS.md → Agent Wiki → 事实来源
↓
实现 → 快速测试 → Virtual LAN Lab
↓
ADB 辅助或人工真实设备验证
↓
日志 + artifacts + 清理/恢复证据
↓
可复用知识回写 sources/ 与 wiki/
↺
这些验证层互相补充:
make test与聚焦的 UI/控制面 gate 构成快速内循环。- 基于 Lima + socket_vmnet 的 Virtual LAN Lab,把需要权限的 DHCP、DNS、pf/NAT、 forwarding、TUN、策略、rollback 与清理行为放进可复现的隔离环境,不冒险干扰 普通 LAN。
- 真实设备与 same-LAN/same-WiFi runner 负责闭合物理拓扑循环。ADB 可以收集 Android 路由、DNS 与连通性证据,Mac 侧同时关联 dnsmasq/mihomo 日志;当操作者 需要保留手机侧直接控制时,也支持人工检查点。
- 对 DHCP 接管等高风险流程,恢复本身就是验收的一部分。流量探针成功,但路由器、 Mac 或客户端无法回到已知正常状态,仍不能算闭环完成。
Virtual Lab 不能替代真实设备行为,一次真机 smoke 也不能替代确定性的 Lab gate。 每个门槛究竟允许支持什么结论,见 验证契约。
Agent Wiki:外置的项目记忆
Agent Wiki 融入了 LLM Wiki 思想:把可复用的长期记忆 从短暂的上下文窗口移到小型、版本化、带来源的知识层中。
docs/agent-wiki/sources/保存稳定的项目简报、决策与验证契约。docs/agent-wiki/wiki/把来源材料整理成短小、互相链接的页面,让 Agent 按任务 渐进加载。.codex/hooks.json在本机安装 Session Wiki hook 后,把 session 延续与 compaction 接入项目本地记忆,同时不把私有 session 状态提交到仓库。
这个知识层只收录可复用、已经验证的内容;一次性日志、临时输出、未经验证的猜测和 普通 TODO 不进入 Agent Wiki。
许可证
OpenSurge for Mac 自有代码以及未另行声明的资产采用
GNU General Public License version 3 only(GPL-3.0-only)。随包分发的
第三方程序与库继续保留各自许可证;详见
第三方声明,其中包含内置 mihomo、dnsmasq 准确版本的
对应源码链接。
安全
start 和 stop 需要用 sudo 运行,因为它们会管理 DHCP、pf 和 IPv4
forwarding。运行时文件会写入配置文件中的 runtime.dir。
开发流程
把 make test 作为快速默认门禁。CI 当前只运行这个单元测试门禁,所以普通
push 和 pull request 不需要主机网络、免密 sudo、Lima 或 socket_vmnet。
在提交或评审高风险网络改动前,请本地运行 make lab-test。这包括 DHCP、
DNS、mihomo 启动/配置渲染、pf 规则、forwarding/rollback 行为、网关生命周期、
lab 脚本,以及会影响运行时流量的示例配置。除非有专用 macOS runner 能提供同样
受控的主机权限和网络隔离,否则虚拟 LAN lab 应保持为本地、夜间或手动门禁。
使用 make lab-test-tun 验证支持的透明代理路径。该测试会让客户端不配置代理,
并要求 mihomo 日志中出现通过 TUN inbound 观察到的直连 HTTPS 请求。修改
mihomo profile 导入或 overlay 行为时,使用
make lab-test-tun-imported-profile;它会用 imported profile fixture 跑同一个
TUN 门禁。修改 imported provider 或会影响透明 TUN 流量的策略选择行为时,使用
make lab-test-tun-imported-egress;它会使用本地 HTTP provider 和受控 HTTP
CONNECT proxy,证明 policy-select 可以把 TUN 出口路径在 DIRECT 与受控代理
之间切换。
修改 MAC 租约、每设备 selector 或设备覆盖的数据路径时,使用
make lab-test-tun-device-policy。它会证明两个客户端获得各自的固定租约、可独立
选择不同的 TUN 出口,并验证设备级域名 REJECT 生效。域名/协议规则编译、模板和
HTTP/MRS rule-provider 配置由单元测试覆盖;不需要为每条操作者规则运行 Lab。
策略组控制面和机器可读 CLI 改动优先使用 make policy-control-test。它会启动真实
mihomo 二进制,但不使用 sudo、dnsmasq、pf 或 TUN,并通过 live external-controller
API 检查 policies、policy-select、mihomo 重启后的策略选择恢复、通过
mixed-port 进行的本机 DIRECT/代理出口切换,以及 connections、providers、
针对 file 与 HTTP proxy provider 的 provider-update 和 snapshot;其中也会验证
未知 policy 会被 policy-select 拒绝。
使用 make same-lan-start-tun 和 make same-lan-adb-check 验证窄范围的同
LAN 默认网关 smoke。这个 gate 会保持 DHCP disabled,要求 TUN,并通过 ADB 检查
一台默认网关和 DNS 指向 Mac LAN IP 的 Android 测试设备。需要先验证单个域名的
真实代理出口时,可以配合 OMG_SAME_LAN_* 上游代理环境变量使用
make same-lan-start-tun-proxy,例如先测 api.ipify.org,再讨论完整订阅导入。
更接近真实设备路径的 imported provider 策略切换 smoke 使用
make same-lan-start-tun-imported-egress 和
make same-lan-adb-check-imported-egress:它会导入 provider-backed TunEgress
group,并把同 LAN TUN 流量从 DIRECT 切到受控本地 HTTP CONNECT proxy。这些 gate
不宣称已经具备全 LAN 上线能力或真实远端订阅出口。
如果明确不使用 ADB,也可以通过人工 Android 浏览器探针收集同一 imported egress
证据;见tests/same-lan/README.zh-CN.md。
对于专门测试 Wi-Fi,路由器 DHCP 已由人工关闭后,可使用
make same-wifi-dhcp-start-imported-egress,让 Android 以 DHCP 模式重新加入,再运行
make same-wifi-dhcp-adb-check-imported-egress。这个独立高风险 runner 使用
gateway.mode: "same_wifi_dhcp",要求显式提供受保护的静态地址列表和路由器 DHCP
已关闭的操作确认。其 stop gate 会验证 OpenSurge 清理,但路由器 DHCP 与客户端自动
获取仍需人工恢复;详见
tests/same-lan/WIFI-DHCP-RUNNER.zh-CN.md。
虚拟 LAN lab
集成 lab 会用两个轻量 Linux 客户端测试真实的 macOS 网关。Lima 提供客户端,
socket_vmnet 创建一个没有竞争 DHCP 服务器的隔离二层主机网络。测试覆盖 DHCP、
DNS、ICMP/NAT、直连 HTTPS,以及通过 mihomo mixed-port 的显式 HTTPS。
make lab-install
make lab-up
sudo -v
make lab-test
make lab-test-tun
make lab-test-tun-imported-profile
make lab-test-tun-imported-egress
make lab-test-tun-device-policy
make lab-down
一次性安装器会添加一个 root 拥有、功能固定的网络 helper,并添加一个很窄的
sudoers 规则,只允许启动、停止和查看 lab 网络状态。网关二进制本身不会获得免密
root 权限;端到端测试前请用 sudo -v 刷新 sudo ticket。拓扑、安全检查和排障
步骤见 tests/lab/README.zh-CN.md。
