Open-source project
YTwsy/OpenSurge-for-Mac avatar
YTwsy/OpenSurge-for-Mac

OpenSurge for Mac: turning a Mac into a per-device Surge-style gateway with dnsmasq and mihomo

Surge-style whole-home gateway and control plane for macOS with IPv4/IPv6 support— mihomo TUN, dnsmasq-powered DHCP/DNS, per-device routing, and an agent-friendly validation workspace.

2,366 stars166 forksGoGPL-3.0

At a glance

What is it?
OpenSurge for Mac is a GPL-3.0 whole-home gateway and control plane that makes a Mac route traffic per device. It layers dnsmasq DHCP/DNS and a mihomo engine over macOS pf, and treats high-risk network changes as things to validate first.
Who is it for?
Adopt OpenSurge for Mac if you want per-device, Surge-style routing across a household driven from a Mac you already run, with a Web GUI that shows each device's real egress chain and a lab harness behind the risky operations: the dnsmasq-plus-mihomo stack over macOS pf and the per-MAC selector policies are the core of it.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 17, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

A Mac as the household gateway, not just a proxy on one machine

OpenSurge for Mac makes a Mac act as a Surge-style gateway and control plane for a whole home network, routing each device through its own outbound policy. The README's framing is that most users start in bypass-router mode: the main router keeps serving DHCP, and only the devices you choose point their gateway and DNS at the Mac using a stable IPv4 address.

The target user is someone who wants per-device routing across a household, a phone and a Mac on rule-based splitting, a game console on a US node, a TV on a streaming node, without flashing a router or buying dedicated hardware. It assumes a comfort with gateways, DHCP and DNS that a casual user will not have, and the documentation is Chinese-first with an English README alongside.

What separates this from a proxy client is that it manages the network layer itself. The README lists three modes with escalating intrusiveness: bypass-router, which changes nothing on the main router; LAN DHCP takeover, where you disable the main router's DHCP under guidance and the Mac serves it instead; and an independent downstream LAN for a separate AP, SSID or VLAN. Each can optionally enable experimental IPv6 takeover.

dnsmasq for addressing, mihomo for egress, pf for the native path

The mechanism is a stack of well-known parts wired together rather than a monolith. The README states that dnsmasq provides DHCP and DNS underneath, while mihomo is the proxy engine. For IPv4, the native gateway path is built from macOS pf and packet forwarding, so ordinary v4 traffic takes a kernel route rather than being tunnelled.

Per-device policy is where the design earns the Surge comparison. A single mihomo process applies independent policies to registered LAN devices: in DHCP takeover mode it hands each device a fixed IPv4 lease keyed to its MAC, and in bypass mode it only needs a stable static IPv4, with the MAC left optional and inferable from observed traffic and ARP neighbours. Devices with enough identity get their own mihomo selector group and a `SRC-IP-CIDR` rule, which is exactly how you make one engine send different sources to different exits.

The experimental IPv6 path is deliberately different and worth understanding before enabling it. The README says downstream IPv6 does not go through the macOS system TUN. Instead a BPF packet broker feeds it into a mihomo gVisor data plane built from the project's own patches, covering TCP, UDP and QUIC carried over UDP/443, while preserving each device's MAC identity for per-device policy. That is a custom userspace data plane, not a stock configuration.

Getting it: a release package for most, a source build for the rest

The README does not give shell install commands; it points to the GitHub Releases page and the project website, and the badges state macOS 13 or newer with separate Apple Silicon and Intel packages. For most users the path is downloading the package and opening `/Applications/OpenSurge.app`, whose menubar icon expands the same status panel and local Web GUI.

Building from source is documented through the `Makefile`, and the targets are concrete. The Go control binaries and the web UI build like this:

bash
make build
make web-build
make control-build

`make build` compiles the core gateway to `bin/omg` from `./cmd/omg`, `make web-build` builds the Web GUI under `web/` with pnpm, and `make control-build` produces the `opensurge-control` and `opensurge-helper` binaries. The patched proxy engine is built separately:

bash
make mihomo-build

which runs `./scripts/build-opensurge-mihomo.sh` to produce the mihomo build the IPv6 data plane depends on. Running `make test` executes `go test ./...`. The module is `open-mihomo-gateway` on Go 1.25 per `go.mod`, so a source build needs a current Go toolchain and pnpm. For diagnostics the README notes the tool emits `status`, `doctor`, `logs` and `snapshot` output in text or JSON, which is the first place to look when a mode misbehaves.

Evidence gates and a virtual lab as first-class features

The part of this project that is unusual for a home-network tool is how seriously it treats the danger of its own actions. The README describes the repository as an AI-agent-friendly workspace where project knowledge is versioned with the code, high-risk network behaviour has executable evidence thresholds, and evidence from a Virtual Lab and from real devices flows back into the next engineering loop.

Concretely, the README's security-and-validation section says high-risk network behaviour is validated in an isolated virtual LAN lab before it touches an ordinary LAN, and the `Makefile` bears this out with an extensive set of `lab-` targets: `lab-up`, `lab-test-tun`, `lab-test-ipv6-same-lan`, `lab-test-tailscale` and many more, plus `real-device-` and `same-lan-` targets that run the same checks against actual hardware.

This matters because the failure mode here is severe. A tool that takes over DHCP for a household can, if it gets it wrong, knock every device offline at once. Building the validation harness into the repository, rather than leaving correctness to the operator, is the right response to that risk, and it is the reason the topic list includes tags like harness-engineering and loop-engineering rather than only networking terms.

The costs: an experimental v6 path, a Mac that must stay awake, and disruptive takeover

Three limitations deserve to be weighed before adopting this. First, IPv6 takeover is labelled experimental throughout the README, and it rides on a patched mihomo build and a custom BPF-fed gVisor data plane. That is the least proven part of the system, and it is the part most likely to behave differently across macOS versions.

Second, the gateway is only up while the Mac is. The README documents a keep-running-on-lid-close toggle in both the menubar and the Web GUI, but it is off by default, does not save a preference, and reverts after quitting or rebooting. So sleep and lid-close are real operational hazards: if the Mac sleeps, the devices routed through it lose their gateway. A machine acting as household infrastructure needs to be treated like infrastructure.

Third, LAN DHCP takeover is intentionally intrusive. The README says it requires disabling the main router's DHCP under guidance and following a recovery flow to re-enable it when stopping. That is a change to shared home network state, which is why the project wraps it in a recovery state machine and steers first-time users toward bypass mode instead. None of this is hidden, but it means the advanced modes are not something to switch on casually.

Against Surge itself, and against an OpenWrt bypass router

Two alternatives frame what this is. Surge, the commercial macOS app it is styled after, is a mature single-machine proxy with polished rule handling, but it is fundamentally about the Mac it runs on. Extending Surge to route other devices per-policy, with DHCP leases and per-MAC selectors, is not its model. OpenSurge takes on that whole-home, per-device gateway job, at the cost of managing dnsmasq, pf and takeover flows that Surge never touches.

The other alternative is a dedicated bypass router: an OpenWrt or GL.iNet box running mihomo or clash. That is the sturdier place to put always-on network infrastructure, because a router is built to stay up and route, which is exactly the weakness of a Mac that sleeps. What OpenSurge offers instead is no extra hardware, a real GUI and menubar app, and the per-device observability the README describes, live connection counts, up and down rates and the actual egress chain per device, that a headless router usually lacks. Choose the OpenWrt box for a permanent, always-on gateway. Choose OpenSurge when you want per-device routing driven from a Mac you already run, with a visible control plane and a validation harness behind the risky operations.

GPL-3.0, a bundled patched engine, and what to verify first

OpenSurge for Mac is GPL-3.0-only, and it ships a `THIRD_PARTY_NOTICES.md` because it builds on mihomo, dnsmasq and other components. The GPL-3.0-only choice means derivatives distributed to others must be released under the same terms, and the patched mihomo built by `scripts/build-opensurge-mihomo.sh` is part of that obligation. Anyone forking this to ship a product inherits the copyleft, which for a tool assembled from other GPL and open components is the consistent outcome.

The Tailscale integration adds a credential-handling detail the README calls out: an OpenSurge-managed Tailscale outbound writes its Auth Key only to a permission-restricted file and does not echo it in config or API responses. For a tool that already asks to run as household infrastructure, keeping that secret out of the observable surface is the right default.

The concrete thing to verify first is which mode you actually need. The README is emphatic that bypass-router mode is the recommended starting point precisely because it leaves the main router's DHCP untouched, so the safe first step is to route one device that way, confirm its egress chain in the Web GUI, and only consider DHCP takeover once you have read the recovery flow in the app guide. Do not begin with the experimental IPv6 path.

Editorial conclusion

Adopt OpenSurge for Mac if you want per-device, Surge-style routing across a household driven from a Mac you already run, with a Web GUI that shows each device's real egress chain and a lab harness behind the risky operations: the dnsmasq-plus-mihomo stack over macOS pf and the per-MAC selector policies are the core of it. It is the wrong choice for always-on infrastructure, since the gateway dies when the Mac sleeps and the lid-close keep-alive is off by default, or if you need proven IPv6, which the README marks experimental and builds on a patched mihomo data plane. Start in bypass-router mode with a single device and confirm its egress in the Web GUI before touching LAN DHCP takeover, which requires disabling your main router's DHCP under a documented recovery flow.

Frequently asked questions

What are the three network modes in OpenSurge for Mac?

Bypass-router mode, recommended for first use, leaves the main router's DHCP on and only redirects chosen devices. LAN DHCP takeover has the Mac serve DHCP after you disable the router's. An independent downstream LAN serves a separate AP, SSID or VLAN.

What does OpenSurge for Mac use under the hood?

The README says dnsmasq provides DHCP and DNS and mihomo is the proxy engine. IPv4 uses macOS pf and forwarding for a native gateway path, while the experimental downstream IPv6 uses a BPF packet broker feeding a patched mihomo gVisor data plane.

What are the requirements to run OpenSurge for Mac?

The README states macOS 13 or newer, with separate Apple Silicon and Intel packages available from GitHub Releases. Building from source uses the Makefile and needs a Go 1.25 toolchain and pnpm for the Web GUI.

Official sources

  1. License: GPL-3.0
  2. Project website
  3. README
  4. Releases
  5. YTwsy/OpenSurge-for-Mac on GitHub
Community notes

Community notes