WireGuard
User-space WireGuard protocol implementation for establishing a WireGuard tunnel with a peer and sending outbound traffic through the tunnel.
DANGER
The WireGuard protocol is not designed specifically for bypassing firewalls. If used as the outer layer to cross the firewall, its distinct characteristics may lead to the server being blocked.
OutboundConfigurationObject
OutboundConfigurationObject corresponds to the settings item in OutboundObject.
{
"outbounds": [
{
// ...
"protocol": "wireguard",
"settings": {
"secretKey": "CLIENT_PRIVATE_KEY",
"address": [
"10.0.0.1",
"fd59:7153:2388:b5fd:0000:0000:0000:0001",
"and more..."
],
"peers": [
{
"endpoint": "SERVER_ADDR",
"publicKey": "SERVER_PUBLIC_KEY",
"allowedIPs": ["0.0.0.0/0", "::/0"]
// ...
}
],
"noKernelTun": false,
"mtu": 1420,
"reserved": [0, 0, 0],
"remoteDNS": [
"1.1.1.1",
"1.0.0.1",
"2606:4700:4700::1111",
"2606:4700:4700::1001"
]
}
}
]
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
secretKey: string
Client private key. Required.
You can generate a client key pair with the xray wg command. Enter the generated PrivateKey here; the accompanying Password (PublicKey) is the client public key. When using Xray as a WireGuard server, enter the client public key in inbounds[].settings.peers[].publicKey.
address: [ string ]
Specifies the local source addresses used in the inner IP packets generated by the WireGuard outbound—that is, the client's in-tunnel IP addresses. One or more IPv4 or IPv6 addresses can be configured.
The default is ["10.0.0.1", "fd59:7153:2388:b5fd:0000:0000:0000:0001"].
Xray automatically selects a source address from the appropriate address family based on the destination address. If multiple addresses from the same family are configured, it selects a suitable address according to its internal rules.
The WireGuard server's inbound configuration must allow these addresses, and each address must be unique in the server's WireGuard inbound configuration.
noKernelTun: true | false
Whether to disable TUN. The default is false; you may need to set it to true in LXC or Docker environments.
Do I need to enable noKernelTun?
When set to false, Xray automatically selects how to process inner IP packets: on Linux, if the Xray process has the CAP_NET_ADMIN capability, it creates a TUN interface and uses the kernel network stack; on other platforms or when permissions are insufficient, it uses the in-process gVisor network stack. When set to true, only the gVisor network stack is used and no TUN interface is created. Using TUN generally provides better performance.
This option only selects how inner IP packets are processed. The WireGuard protocol itself is still handled by Xray's user-space implementation and is unrelated to the kernel WireGuard module.
The automatic detection described above is not always accurate. For example, some LXC environments may be unable to use TUN even when they have the CAP_NET_ADMIN capability, causing the outbound to fail. In this case, set this option to true.
When TUN is used, it occupies IPv6 routing table 10230. Each additional WireGuard outbound uses the next routing table in sequence; for example, the second one uses routing table 10231, and so on.
If a second Xray instance is started on the same machine, it does not continue allocating routing table numbers. Instead, it also tries to use routing table 10230. Because that table is already occupied by the first Xray instance, the second instance cannot connect. If multiple instances are necessary, use this option to disable TUN.
mtu: int
The MTU of the inner IP packets carried by the WireGuard tunnel. The default is 1420.
How to calculate the MTU
The structure of a WireGuard packet is as follows:
- 20-byte IPv4 header or 40 byte IPv6 header
- 8-byte UDP header
- 4-byte type
- 4-byte key index
- 8-byte nonce
- N-byte encrypted data
- 16-byte authentication tag2
3
4
5
6
7
N-byte encrypted data is the MTU value. Depending on whether the endpoint uses IPv4 or IPv6, the value can be 1440 (IPv4) or 1420 (IPv6). Reduce it further for special network environments if necessary (for example, subtract an additional 8 bytes for home broadband using PPPoE).
reserved[ byte ]
The three WireGuard reserved bytes. All three default to 0; set them as needed.
peers: [ PeersObject ]
List of WireGuard servers, where each item is a server configuration. When multiple servers are configured, Xray prefix-matches the destination IP address against each server's allowedIPs and routes the traffic to the matching server, allowing different destination networks to be forwarded through different WireGuard servers.
Packet model of an Xray WireGuard outbound
TCP and UDP connections entering the WireGuard outbound are converted by the network stack into inner IP packets. The inner source address is selected from address, while the inner destination address is the destination IP of the proxied traffic.
Xray prefix-matches the inner destination address against each peer's allowedIPs. The matching peer encrypts and encapsulates the packet, and Xray sends the resulting outer UDP packet to that peer's endpoint. Therefore, address specifies the inner source addresses used by the client, allowedIPs acts as the destination routing table used to select a peer, and endpoint is the server address used by the outer connection.
TIP
Each WireGuard server must allow all addresses in address that belong to the same address family as its allowedIPs: if allowedIPs contains only IPv4 networks, allow all IPv4 addresses listed in address; if it contains only IPv6 networks, the same rule applies to the IPv6 addresses; if it contains both IPv4 and IPv6 networks, allow all listed addresses.
When using Xray as the WireGuard server, list these addresses in inbounds[].settings.peers[].allowedIPs.
remoteDNS: [ string ]
Used to resolve proxied target domain names. Each item must be an IP address. The default is ["1.1.1.1", "1.0.0.1", "2606:4700:4700::1111", "2606:4700:4700::1001"].
DNS queries are sent through the WireGuard tunnel; every server IP must be included in a peer's allowedIPs and reachable through the tunnel.
remoteDNS and targetStrategy
Unlike other outbounds, targets inside a WireGuard tunnel must be IP addresses. When the proxied target is a domain name, the outbound's targetStrategy determines which DNS is used to resolve it:
AsIs: usesremoteDNS.UseIP*: tries Xray's built-in DNS first and falls back toremoteDNSif resolution fails.ForceIP*: uses Xray's built-in DNS and fails immediately if resolution fails.
The results returned by UseIP* or ForceIP* must contain at least one IP whose address family matches an address in address; otherwise, the connection fails. An address-family mismatch is not treated as a resolution failure and does not trigger any fallback.
Which should you choose? remoteDNS works out of the box and sends queries through the WireGuard tunnel, usually producing CDN resolution results suited to the tunnel's exit location. Achieving the same result with Xray's built-in DNS usually requires additional DNS server and routing rules. However, if the built-in DNS resolved the target domain earlier—for example, when using a RealIP setup with TUN/TProxy, or when sniffing is enabled and routing.domainStrategy is not AsIs—using Xray's built-in DNS is recommended to avoid the additional RTT of a second resolution.
PeersObject
{
"endpoint": "SERVER_ADDR",
"publicKey": "SERVER_PUBLIC_KEY",
"preSharedKey": "PRE_SHARED_KEY",
"keepAlive": 0,
"allowedIPs": ["0.0.0.0/0", "::/0"]
}2
3
4
5
6
7
endpoint: address
Server address. Required.
URL:Port format, for example, engage.cloudflareclient.com:2408
IP:Port format, for example, 162.159.192.1:2408 or [2606:4700:d0::a29f:c001]:2408
publicKey: string
Server public key used for verification. Required.
When using Xray as a WireGuard server, enter the Password (PublicKey) paired with the server's inbounds[].settings.secretKey here.
preSharedKey: string
Optional additional symmetric encryption key. It must match the server configuration.
keepAlive: int
Interval, in seconds, at which the client sends persistent keepalive packets to this server. This maintains any NAT mappings or firewall state during idle periods. Enable it only in special situations and only on the client. The default is 0, which disables keepalive packets.
allowedIPs: [ string ]
Specifies the destination IP networks forwarded by this server, with each item expressed in CIDR notation. This field can be omitted when only one server is configured because the default is ["0.0.0.0/0", "::/0"], meaning that the server forwards all IPv4 and IPv6 destination traffic. When multiple servers are configured, explicitly set allowedIPs for each server to assign different destination networks to the appropriate server; Xray selects the server by prefix-matching the destination IP address.