macOS & Windows

Two of the three routing modes run here. Pick from the table first — choosing the wrong one is the single most common way a first attempt fails, and it fails without saying so.

Which mode to choose

ModemacOS / WindowsWhat it costs
destinationsYesOnly the addresses you name go through us. Cannot receive connections from anywhere else.
fullYesEverything the machine sends goes through us, so all of its traffic takes our path and our latency.
sourceNoLinux only. See below.

If a partner has to see your address, choose Named destinations and list the partner. If you are hosting something the internet connects to, you need Full tunnel — see use cases.

Why source routing is not offered here

Source routing means “traffic from this address goes through the tunnel”, and that is a feature of the operating system, not of WireGuard. Linux has it as ip rule from …, which is what our source-routed file uses. Windows has no equivalent — its routing decides by destination only. macOS has no equivalent in route either.

So the file cannot work there, and it does not fail gracefully. The App Store and mobile clients have nowhere to run its PostUp lines at all. The Homebrew wg-quick does run them, they call ip, macOS has no such command, and wg-quick then deletes the interface it just made.

macOS

Install WireGuard from the Mac App Store, or brew install wireguard-tools for the command-line version. Both run the two supported modes.

In the app: Import tunnel(s) from file, choose your .conf, activate.

With Homebrew instead:

sudo mkdir -p /etc/wireguard
sudo install -m 600 anchoredip-42.conf /etc/wireguard/aip0.conf
sudo wg-quick up aip0
sudo /opt/homebrew/bin/wg show
The interface gets a name of its own — utun7 or similar — so wg show aip0 will say it cannot find it. Use wg show with no argument. And sudo drops Homebrew from the path, which is why the full path is spelled out above.

Windows

Install the official client from wireguard.com/install, then Add Tunnel → Import from file and activate.

Or from an elevated PowerShell, as a service that survives reboots:

wireguard.exe /installtunnelservice C:\path\to\anchoredip-42.conf

If the machine is on a corporate VPN

A managed device often carries an always-on VPN — Cloudflare WARP under a Zero Trust policy, Zscaler, Netskope. How it interacts with a tunnel of yours depends on how it works, and there are two kinds.

One installs a default route. A Named-destinations config survives beside it: every route it adds is more specific than a default one, so the kernel prefers it for those addresses and the corporate VPN keeps everything else. A full tunnel will fight it and lose.

The other captures traffic below the routing table, and then no tunnel on that machine can carry anything — ours included, whichever mode. Measured on a Mac under a locked WARP profile in exclude mode with an empty exclude list: the handshake completed normally and not one byte of payload ever reached us, because the packets never reached the routing table to begin with. The only fix is for whoever manages the policy to exclude our address range; it cannot be done from the machine.

The symptom is specific and worth recognising: the client reports a recent handshake, and every request still leaves from your ordinary address. If you see that, stop testing and ask your administrator.

AmneziaWG on a desktop

Use the AmneziaVPN client, which imports the same file. The obfuscation parameters travel in the config and must not be edited. It asks macOS for a VPN slot, so it will not start while another always-on VPN holds one; the Homebrew command-line tools do not, and can.

Verify

curl -s https://api.ipify.org

On a full tunnel this prints your leased address, with nothing to bind. On Named destinations it prints your own address, and that is correct — only the addresses you listed go through us. Test that mode by reaching one of them and asking what it saw. If neither behaves as described, check troubleshooting.