Skip to content

Guide

How to route one browser through WireGuard.

On this page

The WireGuard app picks routes by destination address only, so with AllowedIPs = 0.0.0.0/0 every app on your computer uses the tunnel. Donut Browser runs WireGuard inside the app for one browser profile at a time. The tunnel needs no administrator rights and adds no network adapter, and your other apps keep their normal connection. You need Donut Browser installed and a WireGuard .conf file from your VPN provider or your own server.

How it works

Donut runs WireGuard in user space, as a separate background process for each VPN config. The process opens a SOCKS5 port on 127.0.0.1, and profiles that use the VPN connect to it through Donut’s local relay. Nothing changes your system routes. Profiles that share one VPN share one process.

All of the profile’s traffic goes through the tunnel, host name lookups included. UDP goes through it too, so WebRTC and QUIC work.

1. Get a config with one peer

Download a WireGuard config from your provider, or export the client config of your own server. It looks like this:

[Interface]
PrivateKey = <base64 private key>
Address = 10.66.0.2/32
DNS = 10.66.0.1

[Peer]
PublicKey = <base64 public key>
Endpoint = de.vpn.example.com:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Donut reads these keys:

KeyRequiredWhat Donut does with it
PrivateKey, AddressYesAddress can hold an IPv4 and an IPv6 address, separated by a comma.
PublicKey, EndpointYesExactly one [Peer] section. A config with more peers is refused.
DNSNoOne IPv4 address. Anything else (a list, an IPv6 address or a host name) is replaced with 1.1.1.1. Lookups go through the tunnel either way.
PresharedKey, PersistentKeepaliveNoUsed as given.
AllowedIPs, MTUNoRead but not used. All of the profile’s traffic uses the tunnel, with an MTU of 1420.

Other keys, such as ListenPort or PostUp, are ignored. Keys must use this exact spelling.

2. Import the config

  1. Open Network in the sidebar (Cmd/Ctrl+Shift+N) and switch to the VPNs tab.
  2. Click Import. The dialog Import VPN Config opens.
  3. Drop the .conf file on it, click to browse, or paste the text with Cmd/Ctrl+V.
  4. Check the VPN Name, which comes from the file name, and click Import VPN.

Without a file, click New VPN and fill in Create WireGuard VPN by hand: Private Key, Address, Peer Public Key, Peer Endpoint, and the optional fields. After you save a VPN, you can only rename it. To change a key or the endpoint, delete the VPN and import it again.

3. Test the tunnel

Click the check pill in the Status column of the VPN. Donut starts the tunnel, asks for your public IP through it up to three times, and shows Valid when an IP comes back. This is a live connection test, so Invalid also covers a server that does not answer.

4. Give the VPN to a profile

For a new profile, click New on the Profiles page (Cmd/Ctrl+N). In Create new profile, open the proxy picker. VPNs are listed under VPNs, each with a WG badge. Donut tests the VPN again before it makes the profile.

For an existing profile, stop it, open its panel with the info button on its row, and choose the VPN in Network → VPN. A profile uses a proxy or a VPN, not both, so choosing a VPN removes its proxy.

5. Set the timezone and language

Donut cannot measure a VPN’s exit when it creates a profile. A profile made with a VPN therefore gets no timezone or language from the exit. The browser then reports its own value, which is your computer’s timezone. At launch, Donut shows “Nothing was verified against the exit” with the exit’s location. A site that compares your IP with your timezone sees the gap.

Choose one of these fixes:

  • On Pro, Team or Enterprise, open the profile panel → Fingerprint and set Timezone (IANA), Primary Language (navigator.language) and Languages (JSON array) to the exit’s country. Stop the profile before you edit it.
  • On any plan, create the profile with the local API and pin the location to the exit IP with wayfern_config.geoip. Donut looks the IP up in its local GeoIP database and writes the timezone, language and coordinates. Find the exit IP by opening What is my IP in a profile that uses the VPN.
curl -sS -X POST http://127.0.0.1:10108/v1/profiles \
  -H "Authorization: Bearer $DONUT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "DE via WireGuard",
    "browser": "wayfern",
    "vpn_id": "<vpn id>",
    "wayfern_config": { "geoip": "203.0.113.80" }
  }'

Generate random fingerprint on every launch also reads the location through the VPN, but it gives the profile a new device at every start. Do not use it for accounts that must keep one device.

6. Launch and confirm

Launch the profile and open What is my IP and the WebRTC leak test. Both must show the VPN’s exit, never your own IP. Open the same page in another browser on your computer: it still shows your normal IP.

Import the VPN with the API

POST /v1/vpns/import takes the file text and its name. VPN routes work on every plan.

curl -sS -X POST http://127.0.0.1:10108/v1/vpns/import \
  -H "Authorization: Bearer $DONUT_API_KEY" \
  -H "Content-Type: application/json" \
  --data "$(jq -n --rawfile conf de.conf '{filename: "de.conf", name: "DE WireGuard", content: $conf}')"

Then set vpn_id on a profile with PUT /v1/profiles/{id}. An empty string removes the VPN. A parse error comes back as a bare 400, so test a new config in the app first. See Import a VPN.

Troubleshooting

MessageWhat to do
“Content does not appear to be a valid VPN configuration”The text has no [Interface] or [Peer] section. Paste the whole file.
“Invalid WireGuard config: Missing Endpoint in [Peer]” (or PrivateKey, Address, PublicKey)Add the missing key. Check its spelling and capitals.
”… is not valid base64 …” or ”… decoded to N bytes (expected 32) …”A key is cut or has extra characters. Copy it again.
“Config declares 2 [Peer] sections; exactly one peer is supported”Keep one [Peer] section, or make one config per peer.
“VPN does not respond” before a launchThe server did not answer the handshake. Check the endpoint and port, and that your network allows outbound UDP.
“Couldn’t start the VPN connection: …”The tunnel failed at launch. The detail often reads “Handshake failed after 5 attempts”. Check the keys and the endpoint.
“The selected VPN isn’t working, so the profile wasn’t created.”The test before profile creation failed. Fix the VPN first.

Donut Browser is free, and WireGuard works on every plan. Download it for macOS, Windows or Linux.

Last updated .