WireGuard
This document describes the WireGuard policy implemented by Surge, including its profile syntax, peer configuration, routing and DNS behavior, policy classification, native RTT testing, standard URL testing, lifecycle, ECN support, and diagnostics.
Important: A WireGuard policy in Surge is an application-level outbound policy. It does not install a system-wide WireGuard VPN. Only connections selected by Surge rules, policy groups, or manual policy selection are sent through the WireGuard tunnel.
1. Overview
Surge converts a layer-3 WireGuard tunnel into an outbound policy that can carry TCP and UDP traffic selected by Surge. It maintains an internal IP stack for each WireGuard policy, encrypts packets for the peer selected by allowed-ips, and transports the resulting WireGuard datagrams either directly or through another Surge policy.
A WireGuard policy can serve two logically different roles:
- Peer-to-peer policy: No
dns-serveris configured. Surge assumes the policy is intended for IP-based access to specific peers or private routes and does not assume that it provides general Internet egress. - General proxy policy: One or more
dns-servervalues are configured. Surge treats the policy as a normal outbound proxy policy and uses the standard URL test by default.
This distinction controls the default latency-test mechanism and the tests exposed by the runtime UI. It does not alter the WireGuard route table: actual reachability is always determined by peer allowed-ips, server-side routing, and server-side forwarding or NAT.
Supported use cases
- Accessing a remote private network through a WireGuard peer.
- Reaching one or more point-to-point tunnel addresses.
- Using a WireGuard gateway as a general outbound proxy.
- Splitting destinations across multiple WireGuard peers with different
allowed-ips. - Resolving destination names through DNS servers reachable inside the tunnel.
- Chaining WireGuard transport through another Surge policy.
- Connecting to services such as Cloudflare WARP that use WireGuard reserved bytes as a client or routing ID.
Scope and limitations
- Surge acts as a WireGuard client. It does not expose a general-purpose WireGuard server.
- Only traffic assigned to this policy enters the tunnel. The device's global route table is not replaced.
- Peer discovery, key distribution, address assignment, and server configuration are outside the WireGuard protocol and must be prepared separately.
- WireGuard does not return descriptive authentication or routing errors. Invalid keys, blocked UDP, missing routes, and missing server-side NAT commonly appear as timeouts.
- Surge provides only a small ICMP/ICMPv6 echo-response mechanism for the configured local tunnel address. The main supported payloads are TCP and UDP.
- The graphical editor supports one peer. Multiple peers can be configured in profile text.
2. Prerequisites
Before configuring the policy, obtain or prepare:
- A WireGuard private key for the Surge client.
- At least one peer public key.
- A unique client tunnel IPv4 address, IPv6 address, or both.
- The peer endpoint hostname or IP address and UDP port.
- The destination prefixes that should be routed to each peer.
- If the policy should be a general proxy, a DNS resolver reachable through the tunnel and a peer route that covers it.
- If Internet access is required, a peer that routes the default prefixes and performs any necessary forwarding and NAT.
Treat the private key and optional preshared keys as secrets. Reusing the same client address or private key on simultaneously active devices can cause route conflicts, handshake instability, or traffic delivery to the wrong device.
3. Quick Start
3.1 Peer-to-peer policy
The following policy reaches a private subnet by IP. Because it has no dns-server, Surge classifies it as peer-to-peer and uses the native WireGuard RTT probe by default.
[Proxy]
Office WG = wireguard, section-name=office-wg
[WireGuard office-wg]
private-key = <client-private-key>
self-ip = 10.20.0.2
mtu = 1280
peer = (public-key = <server-public-key>, allowed-ips = "10.20.0.0/24, 192.168.50.0/24", endpoint = vpn.example.com:51820)
Example rule:
[Rule]
IP-CIDR,192.168.50.0/24,Office WG,no-resolve
3.2 General proxy policy
The following policy routes IPv4 traffic through a WireGuard gateway. The presence of dns-server makes it a general proxy policy, so normal URL testing is used.
[Proxy]
WG Gateway = wireguard, section-name=wg-gateway
[WireGuard wg-gateway]
private-key = <client-private-key>
self-ip = 10.30.0.2
dns-server = 10.30.0.1
mtu = 1280
peer = (public-key = <server-public-key>, allowed-ips = 0.0.0.0/0, endpoint = gateway.example.com:51820, keepalive = 25)
The server must forward the traffic and normally must perform source NAT for Internet access. allowed-ips = 0.0.0.0/0 only selects a peer inside Surge; it does not configure the remote gateway.
4. Configuration Model
A complete WireGuard configuration consists of two parts:
- A policy declaration in
[Proxy]. - A named
[WireGuard <section-name>]section.
4.1 Policy declaration
[Proxy]
<Policy Name> = wireguard, section-name=<WireGuard Section Name>[, option=value ...]
Example:
[Proxy]
Office WG = wireguard, section-name=office, test-timeout=8, ecn=true
4.2 WireGuard section
[WireGuard office]
private-key = <client-private-key>
self-ip = 10.20.0.2
peer = (public-key = <peer-public-key>, allowed-ips = 10.20.0.0/24, endpoint = vpn.example.com:51820)
The section-name value must exactly match the suffix of the corresponding WireGuard section. Section names are profile identifiers; they are not sent to the peer.
A WireGuard section may be placed in a Detached Profile Section.
5. Policy-Line Fields
| Field | Required | Default | Description |
|---|---|---|---|
section-name |
Yes | None | Name of the [WireGuard <name>] section used by this policy. |
underlying-proxy |
No | DIRECT |
Surge policy used to transport encrypted WireGuard UDP datagrams. |
test-url |
No | See testing section | Explicit http:// URL that forces the standard URL-test path. |
test-timeout |
No | Global test-timeout, otherwise 5 seconds |
Timeout for the actual probe or HTTP test. L3 initialization receives an additional 10-second allowance. |
ecn |
No | Disabled | Preserves and merges ECN information for supported WireGuard traffic. |
no-error-alert |
No | false |
Suppresses normal policy error alerts. Errors remain visible in logs and runtime details. |
section-name
This field is mandatory. The referenced WireGuard section must exist and contain a private key, at least one local tunnel address, and at least one complete peer.
underlying-proxy
Without this field, Surge resolves peer endpoint hostnames with the normal Surge DNS resolver and sends encrypted WireGuard UDP datagrams directly from the selected physical network interface.
When underlying-proxy is configured:
- encrypted WireGuard datagrams are carried by a Surge UDP connector through the selected policy;
- endpoint hostname resolution can occur through that connector rather than locally;
- the selected policy group is evaluated to its current final policy; and
- a change in the effective underlying policy resets the WireGuard transport sockets.
Example:
[Proxy]
Office WG via Proxy = wireguard, section-name=office, underlying-proxy=Upstream
Avoid dependency loops in which the underlying policy eventually selects the same WireGuard policy.
The underlying-proxy field affects transport to the peer endpoint. It is unrelated to dns-server, which resolves destination names inside the WireGuard policy.
test-url
An explicit test-url forces the standard HTTP test even when the policy has no dns-server and would otherwise be classified as peer-to-peer.
Only plain HTTP URLs are supported by this field. The host must be resolvable and routable through the WireGuard policy. For a peer-to-peer configuration, an IP-literal URL or an internal URL reachable through the configured routes is usually required.
test-timeout
test-timeout is expressed in seconds. It limits the actual WireGuard RTT probe or HTTP operation. Surge additionally allows up to 10 seconds for L3 session startup, endpoint resolution, socket setup, and the first WireGuard handshake.
For example, test-timeout=5 can take up to approximately 15 seconds when the session must be initialized before the test.
ecn
See ECN Support for packet behavior and platform requirements.
6. WireGuard Section Fields
| Field | Required | Default | Accepted value / purpose |
|---|---|---|---|
private-key |
Yes | None | Client private key in WireGuard base64 or 32-byte hexadecimal form. |
self-ip |
Conditional | None | Client IPv4 tunnel address. At least one of self-ip and self-ip-v6 is required. |
self-ip-v6 |
Conditional | None | Client IPv6 tunnel address. At least one local address is required. |
dns-server |
No | None | Comma-separated DNS resolvers used inside the tunnel. Its presence classifies the policy as a general proxy. |
prefer-ipv6 |
No | false |
Prefer IPv6 when both IPv4 and IPv6 DNS answers can be used. |
mtu |
No | 1280 |
Layer-3 MTU from 576 through 1420 bytes. |
peer |
Yes | None | One or more peer definitions. |
6.1 private-key
private-key = <client-private-key>
The key can use standard WireGuard base64 encoding or a 64-character hexadecimal representation of 32 bytes. Surge normalizes valid hexadecimal keys internally.
The key is masked when Surge exports a profile without sensitive data. Do not share a profile containing the real private key.
6.2 self-ip and self-ip-v6
IPv4-only example:
self-ip = 10.20.0.2
Dual-stack example:
self-ip = 10.20.0.2
self-ip-v6 = fd00:20::2
At least one address family is required. These values are local tunnel addresses, not CIDR prefixes. They must match the client addresses expected by the remote WireGuard configuration.
Each simultaneously active client should use a unique tunnel address. Duplicate addresses can cause routing conflicts or IP preemption on the remote side.
The configured address families also determine which tunneled DNS resolver families are usable. An IPv4 DNS server requires self-ip; an IPv6 DNS server requires self-ip-v6.
6.3 dns-server
dns-server = 10.20.0.1
Multiple resolvers are comma-separated:
dns-server = 10.20.0.1, fd00:20::1
Accepted entries include plain IPv4 or IPv6 addresses, supported IP-and-port forms, and system. Multicast IPv4 addresses and encrypted-DNS URLs are not accepted here.
DNS queries to these resolvers are sent through the WireGuard layer-3 session. Each resolver therefore needs a matching allowed-ips route and must be reachable on the remote network.
The presence or absence of this field also defines the policy role:
- absent or empty: peer-to-peer policy;
- one or more resolvers: general proxy policy.
This classification is intentionally static and does not inspect live handshake state, default routes, or server-side NAT.
The DNS server configured here does not resolve the WireGuard peer's endpoint hostname. Endpoint lookup uses normal Surge DNS when transport is direct, or the underlying connector when underlying-proxy is used.
6.4 prefer-ipv6
prefer-ipv6 = true
When both local address families are configured and a destination name returns both A and AAAA records, this setting prefers IPv6. It does not add IPv6 routes or create IPv6 reachability by itself.
6.5 mtu
mtu = 1280
The valid range is 576 through 1420. The default is 1280.
Surge drops an outbound layer-3 packet that exceeds the configured tunnel MTU. A value that is too large may produce stalls or black holes on paths with additional encapsulation. A value that is unnecessarily small increases packet overhead.
6.6 peer
A peer is written as a parenthesized list:
peer = (public-key = <peer-public-key>, allowed-ips = "10.20.0.0/24, 192.168.50.0/24", endpoint = vpn.example.com:51820)
Multiple peers are separated by commas:
peer = (public-key = <peer-a-key>, allowed-ips = 10.10.0.0/16, endpoint = a.example.com:51820), (public-key = <peer-b-key>, allowed-ips = 10.20.0.0/16, endpoint = b.example.com:51820)
The graphical editor supports a single peer. Use profile text for multi-peer configurations.
7. Peer Fields
| Field | Required | Default | Description |
|---|---|---|---|
public-key |
Yes | None | Peer public key in WireGuard base64 or 32-byte hexadecimal form. |
allowed-ips |
Yes | None | Comma-separated IPv4/IPv6 CIDR routes assigned to the peer. |
endpoint |
Yes | None | Peer hostname or IP address followed by a UDP port. |
preshared-key |
No | None | Optional additional symmetric key. |
keepalive |
No | 0 |
WireGuard persistent keepalive interval in seconds, from 0 through 65535. |
client-id |
No | None | Three reserved bytes for compatible services that use them as a client or routing ID. |
7.1 public-key
The key identifies the remote peer. Like private-key, it may be base64 or 32-byte hexadecimal form.
7.2 allowed-ips
In Surge, allowed-ips defines which outbound destination prefixes select this peer. Peer authentication itself is determined by the configured keys.
Examples:
allowed-ips = 10.20.0.0/24
allowed-ips = "0.0.0.0/0, ::/0"
Surge builds separate IPv4 and IPv6 route tables and uses the most specific matching prefix. If no route matches a packet, the packet is not sent directly as a fallback; it is dropped by this policy.
A default route only makes all addresses select the peer. It does not prove that the peer forwards Internet traffic, and it does not by itself change Surge's P2P/general-proxy classification.
7.3 endpoint
endpoint = vpn.example.com:51820
The endpoint must include a UDP port. It may contain an IPv4 address, IPv6 address in supported host-and-port syntax, or domain name.
When no underlying-proxy is configured, endpoint domains are resolved using the normal Surge DNS resolver before sockets are opened. Surge periodically checks domain-based endpoints and updates the transport address if the DNS result changes.
Endpoint resolution is independent of the WireGuard dns-server field.
7.4 preshared-key
preshared-key = <optional-preshared-key>
This optional 32-byte key adds a symmetric secret to the WireGuard handshake. It must match the peer configuration exactly.
7.5 keepalive
keepalive = 25
This is the WireGuard persistent keepalive interval in seconds. It is commonly used when the Surge client is behind NAT and the remote peer needs the mapping to remain active.
0 disables persistent keepalive. Do not enable an unnecessarily short interval because it increases background traffic and power use.
7.6 client-id and reserved bytes
iOS 5.3.1+ Mac 4.10.3+
Some services use bytes 1 through 3 of the WireGuard packet's reserved area as a client ID or routing ID. Surge can write these bytes on outbound packets and clear them before passing inbound packets to the WireGuard core.
The common slash-separated form is:
client-id = 83/12/235
Three-byte hexadecimal and four-character base64 representations are also accepted by the profile parser.
Use this option only when required by the peer implementation. Standard WireGuard deployments should leave it unset.
8. Complete Configuration Examples
8.1 IPv6 peer-to-peer access
[Proxy]
WG IPv6 Lab = wireguard, section-name=wg-v6-lab
[WireGuard wg-v6-lab]
private-key = <client-private-key>
self-ip-v6 = fd00:100::2
peer = (public-key = <server-public-key>, allowed-ips = fd00:100::/64, endpoint = [2001:db8::10]:51820)
No DNS is configured, so the policy uses native handshake RTT testing.
8.2 Dual-stack Internet gateway
[Proxy]
WG Dual Stack = wireguard, section-name=wg-dual, ecn=true
[WireGuard wg-dual]
private-key = <client-private-key>
self-ip = 10.40.0.2
self-ip-v6 = fd00:40::2
dns-server = 10.40.0.1, fd00:40::1
prefer-ipv6 = true
mtu = 1280
peer = (public-key = <server-public-key>, allowed-ips = "0.0.0.0/0, ::/0", endpoint = gateway.example.com:51820, keepalive = 25)
The server must route both address families and provide appropriate Internet forwarding.
8.3 Multiple peers with split routes
[Proxy]
WG Private Networks = wireguard, section-name=wg-split
[WireGuard wg-split]
private-key = <client-private-key>
self-ip = 10.255.0.2
peer = (public-key = <site-a-key>, allowed-ips = 10.10.0.0/16, endpoint = site-a.example.com:51820), (public-key = <site-b-key>, allowed-ips = 10.20.0.0/16, endpoint = site-b.example.com:51820)
Packets for 10.10.0.0/16 select site A; packets for 10.20.0.0/16 select site B. Other destinations have no matching peer.
8.4 Specific route overriding a default peer
[WireGuard wg-routes]
private-key = <client-private-key>
self-ip = 10.60.0.2
dns-server = 10.60.0.1
peer = (public-key = <default-peer-key>, allowed-ips = 0.0.0.0/0, endpoint = default.example.com:51820), (public-key = <office-peer-key>, allowed-ips = 10.0.0.0/8, endpoint = office.example.com:51820)
Longest-prefix matching sends 10.0.0.0/8 to the office peer and other IPv4 destinations to the default peer.
8.5 Transport WireGuard through another policy
[Proxy]
WG via Upstream = wireguard, section-name=wg-upstream, underlying-proxy=Upstream Proxy
[WireGuard wg-upstream]
private-key = <client-private-key>
self-ip = 10.70.0.2
peer = (public-key = <server-public-key>, allowed-ips = 10.70.0.0/24, endpoint = vpn.example.com:51820)
The encrypted WireGuard UDP transport uses Upstream Proxy; tunneled destinations still follow the WireGuard allowed-ips table.
8.6 Cloudflare WARP-style client ID
[WireGuard warp]
private-key = <client-private-key>
self-ip = 172.16.0.2
self-ip-v6 = 2606:4700:110:0000::2
dns-server = 1.1.1.1, 2606:4700:4700::1111
peer = (public-key = <peer-public-key>, allowed-ips = "0.0.0.0/0, ::/0", endpoint = engage.cloudflareclient.com:2408, client-id = 83/12/235)
Use the actual addresses, keys, and client ID assigned by the service.
9. Routing and Peer Selection
For every outbound IP packet, Surge extracts the destination address and performs a route lookup:
- IPv4 and IPv6 use separate route tables.
- Routes come from every peer's
allowed-ips. - The most specific matching prefix wins.
- The packet is encrypted with the selected peer tunnel.
- The encrypted datagram is sent to that peer's endpoint, directly or through
underlying-proxy.
If no peer matches, Surge logs the missing route and drops the packet. It never bypasses the selected WireGuard policy by sending unmatched traffic directly.
Overlapping routes should be intentional. A narrow route on one peer overrides a broader route on another peer. Avoid duplicate prefixes of equal specificity because they make the intended ownership unclear.
10. DNS and Policy Classification
10.1 Peer-to-peer WireGuard policy
A WireGuard section with no dns-server is treated as peer-to-peer.
Expected behavior:
- The normal policy test uses a native WireGuard handshake RTT probe.
- The runtime test UI exposes the RTT test rather than tests that require general Internet egress.
- Destination names cannot normally be resolved through this policy; use IP addresses or an explicit test URL that is independently resolvable and routable.
allowed-ipsmay contain private routes, host routes, or even default routes, but the absence of DNS remains the classification signal.
10.2 General proxy WireGuard policy
When dns-server contains one or more values, Surge treats the policy as a general proxy.
Expected behavior:
- The normal policy test uses the standard URL-test process.
- General diagnostic tests remain available.
- Destination DNS queries use the configured resolvers through the tunnel.
This classification describes intended use, not guaranteed reachability. A general proxy still needs:
- a route covering each DNS server;
- routes covering tested and requested destinations, commonly
0.0.0.0/0and/or::/0; - a peer that forwards those packets; and
- any necessary server-side NAT and firewall rules.
10.3 Endpoint DNS versus tunnel DNS
There are two separate DNS paths:
- Endpoint DNS: Resolves
endpoint = vpn.example.com:51820so Surge can reach the WireGuard server. This uses normal Surge DNS or the underlying proxy connector. - Tunnel DNS: Resolves application destination names after the WireGuard policy has been selected. This uses
dns-serverand sends queries through WireGuard.
Changing dns-server does not change how the peer endpoint itself is resolved.
11. Startup, Handshake, and Lifecycle
WireGuard sessions are prepared when the profile is loaded, while network sockets and handshakes are started on demand.
The startup sequence is:
- Build peer tunnels and IPv4/IPv6 route tables from the profile.
- Resolve peer endpoint domains when transport is direct.
- Evaluate
underlying-proxywhen configured. - Create one UDP transport socket or connector per peer.
- Force initial WireGuard handshakes.
- Mark the session ready after a peer returns a valid WireGuard packet.
Surge advances WireGuard timers for retransmission, rekeying, keepalive, and expiration. If traffic requires an expired peer, Surge requests a new handshake.
For domain-based direct endpoints, Surge periodically resolves the hostname again. If the address changes within the same family, the peer address is updated. If the address family changes, the transport sockets are rebuilt.
A network change or an effective underlying-policy change invalidates existing sockets and triggers reconstruction. Errors frequently appear as timeouts because the WireGuard protocol intentionally does not provide detailed authentication failures.
12. Policy Testing and Latency Measurement
iOS 5.20.0+ Mac 6.7.0+
WireGuard testing is selected statically from the profile:
- no
dns-serverand no explicittest-url: native WireGuard RTT probe; - one or more
dns-servervalues: standard URL test; - explicit
test-url: standard URL test regardless of DNS classification.
12.1 Native WireGuard RTT probe
For a peer-to-peer policy, an Internet URL is not a reliable test target. Surge instead performs a tunnel-level test:
- Start or resume the WireGuard session.
- Resolve endpoints and create transport sockets if necessary.
- Complete an initial handshake if no peer is currently usable.
- Record a fresh start time and force a handshake to every configured peer.
- Complete when the first peer returns a valid WireGuard packet.
- Report the round-trip time and responding endpoint.
The result measures WireGuard peer reachability and handshake round-trip latency. It does not prove that every allowed-ips destination is routed, that DNS works, or that the peer provides Internet access.
With multiple peers, the fastest responding peer completes the test. Test individual routes separately when every peer must be verified.
12.2 Standard URL test
General proxy policies use the same HTTP test path as normal Surge proxies. The test includes destination resolution, route selection, WireGuard transport, remote forwarding, and the HTTP response.
A URL-test failure can therefore mean:
- tunnel handshake failure;
- missing
allowed-ipsroute; - unreachable tunnel DNS server;
- missing remote forwarding or NAT;
- blocked destination; or
- HTTP timeout.
An explicit test-url can point to a service inside the private network. This is useful when a peer-to-peer policy should be tested against a specific application rather than by handshake RTT.
12.3 Initialization allowance
Both native and standard tests allow an additional 10 seconds for L3 initialization. The configured test-timeout still governs the actual RTT or HTTP operation.
The first test after a network change or long period of inactivity may take longer than later tests because endpoint DNS, sockets, and handshakes must be recreated.
13. ECN and DSCP
13.1 ECN support
iOS 5.8.0+ Mac 5.4.0+
Enable ECN on the policy line:
[Proxy]
WG Gateway = wireguard, section-name=wg-gateway, ecn=true
For supported operating-system versions, Surge preserves ECN information for tunneled traffic and applies RFC 6040-style merging when processing received markings. If ECN causes connectivity problems on an incompatible network, disable it.
ECN is a policy-line option, not a field inside [WireGuard <name>].
13.2 Handshake DSCP
Following the WireGuard protocol recommendation, Surge marks handshake packets with DSCP 0x88 (AF41) to improve handshake success on networks that honor this class. Regular tunnel packets do not automatically receive the same DSCP marking.
14. Packet Handling
Surge provides an internal layer-3 stack for each WireGuard policy:
- TCP connections selected by Surge are represented inside the tunnel.
- UDP mappings are translated to tunneled IP/UDP packets.
- IPv4 and IPv6 are enabled according to
self-ipandself-ip-v6. - Incoming fragments can be reassembled before delivery.
- Packets larger than the configured MTU are dropped.
- A simple ICMP and ICMPv6 echo-response mechanism replies when the configured local tunnel address is pinged from the remote side.
The ICMP behavior is intended for basic reachability checks. It does not turn Surge into a general-purpose routed host for arbitrary ICMP traffic.
15. Runtime Status and Diagnostics
The WireGuard runtime detail view can show:
- effective underlying policy;
- active TCP connection count;
- active UDP mapping count;
- configured peer endpoints;
- whether a peer has completed a handshake;
- whether a peer tunnel is expired or has not yet been used; and
- recent policy errors and traffic counters.
For a peer-to-peer policy, tests that require Internet egress are not applicable. The UI keeps the RTT test available and diagnostics prints an explicit explanation when an Internet-dependent test is requested.
For a general proxy policy, the standard latency, DNS, UDP, external-address, and other applicable tests remain available. Their success still depends on routes and remote gateway behavior.
16. Troubleshooting
The native RTT test times out
Check:
- client private key and peer public key;
- optional preshared key on both sides;
- endpoint hostname, address, and UDP port;
- local or remote firewall rules;
- UDP reachability on the current network;
underlying-proxyUDP support when configured;- duplicate client keys or tunnel addresses; and
- whether at least one configured peer is online.
WireGuard authentication failures normally produce no descriptive remote error, so a timeout is expected for many configuration mistakes.
The handshake works but a private address is unreachable
Verify that the destination is covered by the intended peer's allowed-ips. Then verify remote routing and firewall policy. A successful handshake proves only that the peers can exchange authenticated WireGuard packets.
The standard URL test fails but RTT works
The tunnel is reachable, but the complete proxy path is not. Check:
dns-serverreachability throughallowed-ips;- default or destination-specific routes;
- remote IP forwarding;
- source NAT for Internet access;
- the selected test URL; and
- IPv4/IPv6 family compatibility.
Domain names do not resolve
Confirm that dns-server is present, uses a family for which a local tunnel address exists, and is covered by allowed-ips. The DNS service must listen on the tunneled address and permit queries from the client.
Remember that endpoint hostname resolution is separate. If only the peer endpoint fails to resolve, inspect the normal Surge DNS configuration or the underlying policy.
Only IP addresses work
This is expected for a peer-to-peer policy without dns-server. Add a tunneled DNS resolver to make it a general proxy policy, or continue using IP-based rules and destinations.
One of several peers never receives traffic
Inspect overlapping allowed-ips. Longest-prefix matching may always select another peer. Also confirm the inactive peer's endpoint, keys, and route ownership.
Connectivity breaks after changing networks
Surge rebuilds endpoint sockets after network changes. If recovery does not occur, retest the policy and inspect endpoint DNS, the selected interface, and any underlying policy. NAT or firewall rules may differ between Wi-Fi and cellular networks.
Large transfers stall
Lower mtu and retest. Encapsulation through another proxy or a path with a smaller effective MTU can create a black hole even though handshakes and small packets work.
The peer endpoint domain changes address
Surge periodically refreshes domain endpoints. Ensure the normal Surge DNS resolver returns an address permitted on the current network. If the result changes between IPv4 and IPv6, transport sockets must be recreated.
17. Security and Operational Guidance
- Generate a unique private key for each client.
- Assign unique tunnel addresses to simultaneously active clients.
- Protect private and preshared keys in profiles and backups.
- Restrict
allowed-ipsto the routes actually required when a default route is unnecessary. - Configure remote firewall rules according to least privilege.
- Treat
underlying-proxyas part of the trust and availability chain. - Use persistent keepalive only when NAT behavior requires it.
- Do not assume that a successful handshake proves DNS, routing, NAT, or application availability.
- Use
client-idonly with a service that explicitly requires nonzero reserved bytes. - Monitor runtime peer state and recent errors after profile or network changes.
18. Configuration Reference
Policy line
[Proxy]
<name> = wireguard, section-name=<section>[, underlying-proxy=<policy>][, test-url=http://...][, test-timeout=<seconds>][, ecn=true][, no-error-alert=true]
WireGuard section
[WireGuard <section>]
private-key = <base64-or-hex-key>
self-ip = <client-ipv4>
self-ip-v6 = <client-ipv6>
dns-server = <resolver>[, <resolver> ...]
prefer-ipv6 = true|false
mtu = 576..1420
peer = (<peer-fields>), (<peer-fields>)
At least one of self-ip and self-ip-v6 is required.
Peer definition
peer = (public-key = <base64-or-hex-key>, allowed-ips = "<cidr>, <cidr>", endpoint = <host>:<port>, preshared-key = <optional-key>, keepalive = <0..65535>, client-id = <byte>/<byte>/<byte>)
Required peer fields:
public-keyallowed-ipsendpoint
Optional peer fields:
preshared-keykeepaliveclient-id