VPNonly how it works guides faq install github

How it works

Most VPN apps take over the whole machine. They replace your default route, so every app's traffic goes through another country whether that helps or not. VPNonly does the opposite: your Mac never joins the VPN, individual apps do.

1. A tunnel nobody uses

wireguard-go opens a tunnel to your VPN provider, and no default route is installed. The tunnel just sits there until you send something into it. So when something breaks, one app goes offline rather than your whole internet.

2. The firewall picks who goes in

macOS ships with PF, a packet filter that can't match traffic by application, but can match by unix group. So each app you add gets its own private group, and two rules do the work:

pass out quick route-to (utunN 10.5.0.2) inet proto { tcp udp } \
    from any to any group vpn_a1b2c3 keep state
block return out quick proto { tcp udp } from any to any group vpn_a1b2c3

macOS chooses a free utunN; VPNonly records the exact interface and process it created instead of assuming a fixed name. These rules live in the dedicated com.apple/vpnonly PF anchor, so normal connect and disconnect operations never replace another product's main firewall rules. The pass sends the group into the tunnel. The block is the kill switch when an owned tunnel is unavailable.

A process's group is fixed when it starts, but firewall rules aren't. That's why an app has to restart once to join, and never again. After that, toggling it is just rewriting rules.

3. A very small launcher

A 30-line C program starts your app under its group and immediately drops root. Helper processes inherit the group, so apps that spawn a dozen subprocesses are covered too.

About the password prompt

Creating network interfaces and firewall rules needs admin rights. That's true of any VPN software. VPNonly installs a small engine owned by root; first setup and security-sensitive engine upgrades can ask for approval. From version 1.9.8 onward, the exact privileged source is published with each release.

What I haven't solved

A version with no restarts at all needs Apple's Network Extension framework, which sees every connection along with the app that made it. That's the plan, it's just a much bigger build.

Get it for Mac — $19