WireGuard through Xray relay server

This architecture is a result of discussion #2530 on GitHub.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
+-------------------+
| Client device |
| |
| WireGuard peer |
| |
+---------+---------+
|
|
V
+-------------------+
| Relay server |
| |
| Xray client |
| |
+---------+---------+
|
|
V
+-------------------+
| Final server |
| |
| Xray server |
| WireGuard peer |
+-------------------+

Final server

Install WireGuard using https://github.com/angristan/wireguard-install:

1
2
3
curl -O https://raw.githubusercontent.com/angristan/wireguard-install/master/wireguard-install.sh
chmod +x wireguard-install.sh
./wireguard-install.sh

The generated server configuration file /etc/wireguard/wg0.conf looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[Interface]
Address = 10.66.66.1/24,fd42:42:42::1/64
ListenPort = 51820
PrivateKey = mNsFzYlqLAbgo5CiD3PUuhziLTq/huHJSa2GHfQd2nA=
PostUp = iptables -I INPUT -p udp --dport 51820 -j ACCEPT
PostUp = iptables -I FORWARD -i ens3 -o wg0 -j ACCEPT
PostUp = iptables -I FORWARD -i wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostUp = ip6tables -I FORWARD -i wg0 -j ACCEPT
PostUp = ip6tables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostDown = iptables -D INPUT -p udp --dport 51820 -j ACCEPT
PostDown = iptables -D FORWARD -i ens3 -o wg0 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE
PostDown = ip6tables -D FORWARD -i wg0 -j ACCEPT
PostDown = ip6tables -t nat -D POSTROUTING -o ens3 -j MASQUERADE

### Client ipad
[Peer]
PublicKey = x3gUQWXY/xwDpnwYWnY74YaHiSedwpq8PO6JUkWKzCA=
PresharedKey = a9gptxKx6tpSlBHJp26jGBgbCbwjJewXTQByq1gjuHo=
AllowedIPs = 10.66.66.2/32,fd42:42:42::2/128

The generated client configuration file /root/wg0-client-ipad.conf, original and unaltered, looks like this:

1
2
3
4
5
6
7
8
9
10
[Interface]
PrivateKey = cJ+nZUGp83hV/KSysP91YpahDJ293wiiQ6TZRrDiT3k=
Address = 10.66.66.2/32,fd42:42:42::2/128
DNS = 1.1.1.1,1.0.0.1

[Peer]
PublicKey = t6JhTWXw2HXVgiY8NW2AZfugQd5KYZmq18d3AFwcECs=
PresharedKey = a9gptxKx6tpSlBHJp26jGBgbCbwjJewXTQByq1gjuHo=
Endpoint = FINAL.SERVER.IP.ADDRESS:51820
AllowedIPs = 0.0.0.0/0,::/0

Install Xray from https://github.com/XTLS/Xray-install:

1
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install --beta -u root

Generate UUID:

1
xray uuid

Example:

1
6a0ce07a-6e2c-43a1-9e46-db287f74d34a

Generate public-private key pair:

1
xray x25519

Example:

1
2
Private key: 4JLxQQ9axlmz5sRAGvxwV4zSOiA-uwUfLc0HuGT6RH4
Public key: JglJK7YsfQYWfGFqIs9r9Uz8WPxjReiqYFFeISielg4

Generate short id:

1
openssl rand -hex 8

Example:

1
2f35d1c3636c2b2e

Edit the Xray server configuration file /usr/local/etc/xray/config.json and make it look like this:

1
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
35
36
37
38
39
40
41
42
43
44
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"listen": "0.0.0.0",
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "6a0ce07a-6e2c-43a1-9e46-db287f74d34a",
"flow": ""
}
],
"decryption": "none"
},
"streamSettings": {
"network": "h2",
"security": "reality",
"realitySettings": {
"show": false,
"dest": "www.cisco.com:443",
"xver": 0,
"serverNames": [
"www.cisco.com"
],
"privateKey": "4JLxQQ9axlmz5sRAGvxwV4zSOiA-uwUfLc0HuGT6RH4",
"shortIds": [
"2f35d1c3636c2b2e"
]
}
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "direct",
"redirect": "127.0.0.1:51820"
}
]
}

Restart the Xray systemd service with this configuration file:

1
systemctl restart xray

Open port tcp/443 in this server’s firewall.

You now have Xray listening on tcp/443 and WireGuard listening on udp/51820 (which need not be open in this server’s firewall).

Relay server

Install Xray from https://github.com/XTLS/Xray-install:

1
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install --beta -u root

Edit the Xray server configuration file /usr/local/etc/xray/config.json and make it look like this. Note that the Xray client will accept dokodemo-door input on port udp/51820.

1
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag":"wireguard",
"port": 51820,
"protocol":"dokodemo-door",
"settings":{
"address":"0.0.0.0",
"port":51820,
"network":"udp"
}
}
],
"outbounds": [
{
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "FINAL.SERVER.IP.ADDRESS",
"port": 443,
"users": [
{
"id": "6a0ce07a-6e2c-43a1-9e46-db287f74d34a",
"encryption": "none",
"flow": ""
}
]
}
]
},
"streamSettings": {
"network": "h2",
"security": "reality",
"realitySettings": {
"show": false,
"fingerprint": "chrome",
"serverName": "www.cisco.com",
"publicKey": "JglJK7YsfQYWfGFqIs9r9Uz8WPxjReiqYFFeISielg4",
"shortId": "2f35d1c3636c2b2e",
"spiderX": ""
}
},
"tag": "proxy"
}
]
}

Restart the Xray systemd service with this configuration file:

1
systemctl restart xray

Open port udp/51820 in this server’s firewall.

This server is now listening for public input on udp/51820, and whatever it gets will be sent by dokodemo-door to the Xray server.

Client device

Securely download the generated client configuration file from the final server.

Edit the apparent destination to be your relay server IP address, not your final server IP address:

1
2
3
4
5
6
7
8
9
10
[Interface]
PrivateKey = cJ+nZUGp83hV/KSysP91YpahDJ293wiiQ6TZRrDiT3k=
Address = 10.66.66.2/32,fd42:42:42::2/128
DNS = 1.1.1.1,1.0.0.1

[Peer]
PublicKey = t6JhTWXw2HXVgiY8NW2AZfugQd5KYZmq18d3AFwcECs=
PresharedKey = a9gptxKx6tpSlBHJp26jGBgbCbwjJewXTQByq1gjuHo=
Endpoint = RELAY.SERVER.IP.ADDRESS:51820
AllowedIPs = 0.0.0.0/0,::/0

If you have not already done so, install WireGuard on the client as per https://www.wireguard.com/install.

Add a tunnel (i.e., your edited configuration file).

Connect your client to the relay server, which will in turn whisk your traffic over Xray to the final server.

WireGuard client on an iPad