Many authoritarian states try to censor free speech. To do this, they block access to web sites, commercial VPNs, VPN protocols, and in some cases even block complete internet access. I will explain how to bypass protocol blocking for Wireguard on this post.
To bypass blocking, you need to encapsulate Wireguard packets in a TCP tunnel, hiding them from the firewall appliances of the state. For minimum overhead, maximum performance and the least stress on your servers, you can do this with a simple
xor encryption. Since Wireguard is already encrypted with a strong cypher, this is only used for hiding its traffic, thus creating no weakness in security. As most censors block the protocol on all UDP ports, trying different ports with while using Wireguard without any hiding mechanism will be futile.
For this solution to work, you’ll need to have your own Wireguard routers on both your server side and client side. If you don’t have a router on your client side, you can get a cheap Raspberry Pi 4 and install Wireguard on it. From this point on, this post assumes that you have correctly configured Wireguard installations on both client and server sides which have the
systemd infrastructure (Debian/Ubuntu etc). NOTE: If you will be routing all your traffic over Wireguard, you need to have
PostDown configurations, which are not discussed here. But you can find a sample configuration on this page.
udp2rawbinary archive from this link. When you extract the tar.gz file, you’ll see that there are different binaries for different computer architectures. Select the correct binary for both your client and server architectures and copy or link it under
- On your server, create the file
/etc/udp2raw.confand enter the following configuration into it. You’ll need to change the following according to your own configuration:
TCP_PORT, an unused port on your server to listen to,
WIREGUARD_PORT, the current port that your Wireguard instance on your server listens to and
PASSWORD, an alphanumeric password that you will create now.
- On your client, again create the file
/etc/udp2raw.confand enter the following configuration into it. Again, you’ll need to change the following according to your own configuration:
LOCAL_PORT, a UDP port that your router will listen to,
SERVER_IP, the IP address of your server,
SERVER_TCP_PORT, the TCP port that you just entered on your server above and
PASSWORD, again the same alphanumeric password you created above.
- On both the server and client, create the file
/etc/systemd/system/udp2raw.serviceand enter the following into it:
ExecStart=/usr/local/bin/udp2raw --conf-file /etc/udp2raw.conf
- On both devices, run the following commands:
systemctl enable udp2raw.service
systemctl start udp2raw.service
- If you have used the correct binaries, your
udp2rawconfiguration should be up and running. The only thing that you need to do now is, changing the Wireguard configuration of your client and adding itself as the new server, using the
LOCAL_PORTinformation on its
udp2rawconfiguration and setting
1280. You’ll need to add something like below:
Endpoint = 127.0.0.1:LOCAL_PORT
MTU = 1280
Also if you use Wireguard on iOS or Android, you can change their configuration to the port of your client side router’s
udp2raw port and have them use the same TCP tunnel. This will only work when they are on the same network as the client side router though. So on cellular it would not work.
When you make all these changes, you’ll be able to access your Wireguard server with very little performance penalty.