YTwsy/OpenSurge-for-Mac

GitHub: YTwsy/OpenSurge-for-Mac

把 Mac 变成局域网全屋透明代理网关,支持 DHCP/DNS 接管、mihomo 配置导入和每设备独立分流策略。

Stars: 398 | Forks: 18

OpenSurge for Mac App 图标

OpenSurge for Mac

把 Mac 变成可导入规则、可按设备分流的全屋透明代理网关——支持 DHCP/DNS 自动接管

最新版本 macOS 13+ 提供 Apple Silicon 与 Intel 安装包 GPL-3.0-only

简体中文 · English

下载 · App 指南 · 能力 · 每设备策略 · Web GUI · Agent 工作区

OpenSurge 全屋网关主界面 OpenSurge 策略与节点健康页面
OpenSurge 每设备策略页面
OpenSurge for Mac 是一个开源的 Surge 风格 macOS 网关与控制面。它把 Mac 变成 整个局域网的代理出口:同一网络下的手机、电视、PS5、游戏机、VR 设备、虚拟机等终端, 都可以从 Mac 获取 DHCP/DNS,并共享由策略控制的网络连接;你也可以为每台设备 单独配置不同的出口策略:手机走代理、游戏机直连,设备啥都不用配。 - 可导入已有的 mihomo 配置或订阅,保留原有节点、代理组和规则 - Web GUI 实时展示每台设备的连接、上下行流量和实际出口链;菜单栏随时查看网关状态与恢复提醒。 底层由 dnsmasq 提供 DHCP/DNS,mihomo 作为代理引擎,macOS pf 与 IPv4 forwarding 提供原生网关路径。 这个仓库也被有意设计成一个 [AI Agent 友好工作区](#ai-agent-友好工作区):项目知识与代码一起版本化,高风险 网络行为有可执行的证据门槛,Virtual Lab 与真实设备产生的证据会回流到下一轮工程 循环。 ## 能力 **友好的 App 体验** - 通过 macOS 菜单栏 App 随时查看状态、接收网络恢复提醒并打开本地 Web GUI;再次打开 `/Applications/OpenSurge.app` 会直接展开与菜单栏图标相同的状态面板; - 在一个控制面中完成订阅导入、网络设置、设备分流、节点健康、连通性检查与诊断; - 使用恢复状态机引导局域网 DHCP 接管的启动、客户端验收、停止和网络恢复。 第一次使用请参阅 [OpenSurge for Mac App 使用指南](docs/app-user-guide.zh-CN.md)。 **网关与代理** - 启停 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 命令和验证边界见 [每设备策略覆盖](docs/device-policy.zh-CN.md)。 ## Web GUI 与菜单栏 App 通过安装包使用 OpenSurge 时,请从 [OpenSurge for Mac App 使用指南](docs/app-user-guide.zh-CN.md)开始。 本地 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](docs/gui-architecture.zh-CN.md)。 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 使用指南](docs/app-user-guide.zh-CN.md)中的图形界面流程。 ### 状态与诊断 ``` 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 ` 会请求 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](https://openai.com/index/harness-engineering/) 的核心思想: Agent 是否可靠,不只取决于模型,还取决于模型周围的上下文、约束、工具、可观测性 与验收门槛。 - `AGENTS.md` 是精简的入口地图:它定义产品身份、硬性网络不变量,并告诉 Agent 针对不同任务必须继续阅读哪些文档。 - [`docs/agent-wiki/`](docs/agent-wiki/README.md) 以渐进披露的方式提供架构、决策与 验证上下文,避免每个任务都从全仓库重新拼装心智模型。 - `status`、`doctor`、`logs`、`snapshot` 等机器可读 CLI,加上确定性的 `make` 入口与保留的 artifacts,让 Agent 能直接观察正在运行的系统。 - 配置校验、只允许 TUN 的透明代理、rollback、隔离 Lab 与明确的恢复契约,把安全 指引变成可以执行和检查的边界。 ### Loop Engineering:用可执行证据闭环 OpenSurge 实践 [Loop Engineering](https://addyosmani.com/blog/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。 每个门槛究竟允许支持什么结论,见 [验证契约](docs/agent-wiki/wiki/concepts/validation-gates.md)。 ### Agent Wiki:外置的项目记忆 [Agent Wiki](docs/agent-wiki/wiki/index.md) 融入了 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](LICENSE)(`GPL-3.0-only`)。随包分发的 第三方程序与库继续保留各自许可证;详见 [第三方声明](THIRD_PARTY_NOTICES.md),其中包含内置 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`](tests/same-lan/README.zh-CN.md#不使用-adb-的手动手机检查)。 对于专门测试 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`](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`。
标签:DHCP/DNS, EVTX分析, mihomo, 按设备分流, 日志审计, 网络网关, 透明代理