Is your Wireguard server not as fast as you thought? Does it suffer from constant disconnects and packet drops? Sometimes, it is simply caused by Wireguard using UDP instead of TCP.

In some public networks, the ISP loves interrupting UDP traffic. With a technique called Quality of Service, they deliberately slow down UDP traffic to avoid network congestion in busy hours.

As much as I hate it, they are probably doing the right thing. Most UDP traffic comes from video games, torrents, etc. And they do slow down the network as a whole. Why would you use a public network for competitive gaming anyway? However, apparently HTTP/3 uses UDP now, so I hope this situation against UDP can at least ease up a little.

But what if I am using my home network? Surely the ISP has no reason to interfere with UDP packets there. Spoilers: some of them still do. For some reason, I can never achieve the same speed with UDP when I can go for several hundred megabits per second in TCP! Some ISP even went out to drop my DNS query packets (DNS uses UDP at port 53).

That is why I hate ISP.

What about using Wireguard over TCP? ISP seems mostly nice with TCP.

What even is UDP

Cool image about UDP

UDP, or User Diagram Protocol, is a low-latency network protocol. If TCP is a regular car with maximum safety measures, UDP is like a car with a rocket engine. Usually, you want TCP for its reliability.

However, UDP is more lightweight and flexible, which is perfect for a VPN protocol. Holding TCP packets in UDP packets is also easy. That is why Wireguard uses UDP in the underlying protocol.

Why does OpenVPN support TCP, not Wireguard

OpenVPN suffers from multiple design flaws, and being able to tunnel via TCP is definitely one of them.

For the same reason, tunneling Wireguard over real TCP is a bad idea.

The solution

Tunneling Wireguard over TCP won’t work perfectly. But faking a TCP packet is definitely possible! ISP cannot easily identify fake TCP from real TCP, and fake TCP can bypass the OS level’s reordering and congestion control. The only downside is that faking TCP needs root priviledge on most *NIX systems.

Actually, programs that fakes TCP already exist! udp2raw is a good one.

Installing udp2raw

If your servers runs Arch Linux or Manjaro,

sudo pacman -S udp2raw-tunnel

Otherwise, you can download the latest release from the Github page.

Running udp2raw

After installing it, execute the following command on your server.

udp2raw -s -l "0.0.0.0:<desired port>" -r "127.0.0.1:<Wireguard server's port>" -k "<desired password>" --raw-mode faketcp -a

Here, <desired port> is the server port listened by udp2raw. <desired password> is a secret password for udp2raw.

Also, start udp2raw on your client.

udp2raw -c -l "127.0.0.1:5634"  -r "<Wireguard server's IP address>:<server_port>"  -k "<server password>" --raw-mode faketcp -a

Here, <server port> and <server password> are from last step.

Config Wireguard to use the tunnel

Open your Wireguard client’s config.

In section [Peer], change value of entry Endpoint into 127.0.0.1:5634, the local Wireguard endpoint tunneled through udp2raw.

example config file in my Wireguard client on macOS

Restart your Wireguard client.

Did it work?

Welp, it definitely worked (for me)!

Technically, udp2raw can hide all kinds of UDP traffic. So maybe you can…hide your video game traffic from your company?