computerscot.github.io

WireGuard through WebSocket Tunnel

September 16, 2023

Here is a way to use WireGuard while overcoming network restrictions that detect the WireGuard UDP protocol. wstunnel uses the WebSocket protocol, which is compatible with HTTP, in order to bypass firewalls and proxies.

References:

Linux Server

You will need a server and a domain name. Our example hostname will be vps7.example.com.

1. Calculate your WireGuard AllowedIPs for the client side using the calculator at https://www.procustodibus.com/blog/2021/03/wireguard-allowedips-calculator. The initial value of Allowed IPs should be 0.0.0.0/0, ::/0. The Disallowed IPs should be YOUR.SERVER.IP.ADDRESS. Press Calculate to get your AllowedIPs. You'll feed that line into the WireGuard install script in a moment.

2. Open port tcp/443 on your server's firewall.

3. Update your server's existing software packages:

apt update && apt upgrade -y

4. Install WireGuard using the script from https://github.com/angristan/wireguard-install. When prompted, specify your server public IP address, port 51820, your calculated AllowedIPs, and at the end give your first client a name, e.g. windows.

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

5. Edit /etc/wireguard/wg0.conf, and reduce the [Interface] MTU to 1300:

MTU = 1300

6. Restart WireGuard with your revised /etc/wireguard/wg0.conf:

systemctl restart wg-quick@wg0

7. Download the wstunnel executable:

wget https://github.com/erebe/wstunnel/releases/download/v5.1/wstunnel-linux-x64

8. Copy wstunnel into your execution path:

cp wstunnel-linux-x64 /usr/local/bin/wstunnel

9. Make it executable:

chmod +x /usr/local/bin/wstunnel

10. Allow wstunnel to bind to privilged ports:

setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/wstunnel

11. Create the systemd service unit file /etc/systemd/system/wstunnel.service like this. This will listen for a TLS connection on port 443 and forward packets to the WireGuard port on localhost.

[Unit]
Description=WebSocket Tunnel
After=network.target

[Service]
Type=simple
User=nobody
ExecStart=/usr/local/bin/wstunnel -v --server wss://0.0.0.0:443 --restrictTo=127.0.0.1:51820
Restart=no

[Install]
WantedBy=multi-user.target

12. Start wstunnel on reboot and also start it now:

systemctl enable --now wstunnel

Windows client

1. Download the latest Windows client, https://github.com/erebe/wstunnel/releases/download/v5.0/wstunnel-windows-x64.zip or a more recent one if there is one.

2. Unzip the .zip file.

3. Open a Command Prompt window. Change into the Downloads\wstunnel-windows-x64 directory. The next command will listen on port 51820 on localhost and forward these packets to port 51280 on vps7.example.com.

.\wstunnel.exe -v --udp --udpTimeoutSec -1 -L 127.0.0.1:51820:127.0.0.1:51820 wss://vps7.example.com

4. Leave the Command Prompt window open with wstunnel running in it and waiting for UDP datagrams on localhost port 51820.

5. Open PowerShell, and securely download the generated client configuration file from the server, e.g.:

scp root@vps7.example.com:/root/wg0-client-windows.conf Downloads

6. Edit Downloads\wg0-client-windows.conf. Change the [Peer] Endpoint from YOUR.SERVER.IP.ADDRESS:51820 to be 127.0.0.1 port 51820:

Endpoint = 127.0.0.1:51820

7. Reduce the [Interface] MTU from 1420 (the default) to 1300:

MTU = 1300

8. If you have not already done so, install the WireGuard client from https://www.wireguard.com/install.

9. Import the tunnel defined in your revised client configuration file Downloads\wg0-client-windows.conf.

10. Press Edit and uncheck the checkbox to block untunneled traffic (kill-switch).

11. Activate the tunnel.

macOS client

1. Get your wstunnel from https://github.com/erebe/wstunnel/releases/download/v5.0/wstunnel-macos.zip.

2. Get your WireGuard client from the App Store (link at https://www.wireguard.com/install).

3. Apart from that, it should be similar to the Windows client. The reference https://kirill888.github.io/notes/wireguard-via-websocket refers to macOS clients.

Linux client

The reference https://nerdonthestreet.com/wiki?find=Set+Up+a+WireGuard+VPN+Server+with+WebSocket+Tunneling refers to Linux clients.