---
title: "Using udp2raw to bypass censoring on Wireguard protocol"
description: "UPDATE: I now recommend using AmneziaWG. I have moved to it instead of using udp2raw and it works wonderfully. Many states block access to web sites, commercial VPNs, VPN protocols, and in some cases…"
date: 2026-07-17
canonical: https://keremerkan.dev/posts/udp2raw-bypass-censoring-wireguard-protocol/
---

**UPDATE:** I now recommend using [AmneziaWG](https://docs.amnezia.org/documentation/amnezia-wg/). I have moved to it instead of using **udp2raw** and it works wonderfully.

* * *

Many states 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](https://www.raspberrypi.org/products/raspberry-pi-4-model-b/)** 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 `PostUp` and `PostDown` configurations, which are not discussed here. But you can find a sample configuration on [this page](https://keremerkan.dev/posts/wireguard-mtu-fixes/).

-   Download `udp2raw` binary archive from [this link](https://github.com/wangyu-/udp2raw-tunnel/releases). 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 `/usr/local/bin/` as `udp2raw`.
-   On your server, create the file `/etc/udp2raw.conf` and 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.

```ini
-s
# Local
-l 0.0.0.0:TCP_PORT
# Remote
-r 127.0.0.1:WIREGUARD_PORT
# Key
-k PASSWORD
--auth-mode hmac_sha1
--raw-mode faketcp
-a
--fix-gro
--cipher-mode xor
```

-   On your client, again create the file `/etc/udp2raw.conf` and 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.

```ini
-c
# Local
-l 0.0.0.0:LOCAL_PORT
# Remote
-r SERVER_IP:SERVER_TCP_PORT
# Key
-k PASSWORD
--auth-mode hmac_sha1
--raw-mode faketcp
-a
--fix-gro
--cipher-mode xor
```

-   On both the server and client, create the file `/etc/systemd/system/udp2raw.service` and enter the following into it:

```ini
[Unit]
Description=udp2raw service
ConditionFileIsExecutable=/usr/local/bin/udp2raw
ConditionPathExists=/etc/udp2raw.conf
After=network.target
[Service]
Type=simple
User=root
Group=root
#LimitNOFILE=32768
PIDFile=/run/udp2raw.pid
AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN
ExecStart=/usr/local/bin/udp2raw --conf-file /etc/udp2raw.conf
Restart=on-failure
[Install]
WantedBy=multi-user.target
```

-   On both devices, run the following commands:  
    `systemctl enable udp2raw.service`  
    `systemctl start udp2raw.service`
-   If you have used the correct binaries, your `udp2raw` configuration 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_PORT` information on its `udp2raw` configuration and setting `MTU` to `1280`. You'll need to add something like below:

```ini
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.
