Bypassing a network firewall with VPN which only lets TCP 80/443 through

Hi Pico,

I'm aware that WireGuard cannot tunnel through TCP out of the box however I am (and have successfully been) able to use a program like Mullvad's udp-to-tcp or Erebe's wstunnel to do this.

The problem lies that I'm unable to do this on my OpenWrt router. I can successfully pull it off on my windows machine hence I'm asking for help on this forum.

Furthermore, you suggested OpenVPN;
This won't work since the firewall uses Deep Packet Inspection (DPI) to block OpenVPN packets (specifically the handshake)
Either way, I need to set up a tunnel on OpenWrt to bypass this firewall, preferably WireGuard over TCP since I get no loss of speed and the firewall doesn't block traffic on TCP 80/443

Thank you for your reply :slight_smile:


I did not seem to get it in the first place.

So it looks like a 2-part problem:

  1. having a homegrown VPN endpoint that does the proprietary packet-inspection-proof tunneling in outbound direction as you described. This was already solved by you as a proof of concept (though on Windows)
  2. having a router in your local subnet that forwards and likely NAT any outbound traffic of your local clients via your proprietary VPN endpoint service.

So you are as a minimum looking for a solution for the second part + optionally also a way, to host the first part on OpenWRT instead of Windows.

For the second part, I would google the Internet and this forum for posts, who wanted all outbound traffic of devices connected to a OpenWRT router to get tunneled through OpenVPN or Wireguard. Though of course OpenVPN is not what you want, the forwarding part of those recipes of those posts/blogs is likely still a viable match for your requirement. That is a very common scenario, you should find lots of infos about it.
Maybe change the thread title to "forward OpenWRT router outbound traffic to a custom VPN server", as this might give users a better understanding of your issue, who could answer upcoming OpenWRT traffic forwarding questions.

And if you are keen on the first part:

developing/compiling is done differently: There is a dev SDK available for OpenWRT. Used on a regular Linux distro on a PC, output then gets cross-compiled for your desired target platform.

Hey @Rat
See my approach with lxc

1 Like

if you have 128MB RAM, running a container can be tight.

looks like it actually runs a vendor fork of OpenWRT 22.

So it likely has some not further specified modifications. Though some people in parallel still seem to work on a community port (which will be some future version). So there might be a theoretical gap between recommendations here and how the device actually behaves. You could also try the GL iNet forum. Not to force you to leave here, but the actual experts for that version fork might rather be found over there.

Hi guys,

I've looked into @maurer's post and have tried to install lxc but I run into an issue with the first command (yes, I did run opkg update)!!
I get:

$ opkg install xz tar gnupg cgroupfs-mount cgroup-tools
Unknown package 'xz'.
Unknown package 'tar'.
Unknown package 'gnupg'.
Unknown package 'cgroupfs-mount'.
Unknown package 'cgroup-tools'.
Collected errors:
 * opkg_install_cmd: Cannot install package xz.
 * opkg_install_cmd: Cannot install package tar.
 * opkg_install_cmd: Cannot install package gnupg.
 * opkg_install_cmd: Cannot install package cgroupfs-mount.
 * opkg_install_cmd: Cannot install package cgroup-tools.

I don't believe I'm able to do this since I can't install lxc in the first place, and as @Pico mentioned, running a container is very tight on this very low powered machine with limited RAM and storage

Also, @Pico

I think there is still a misunderstanding. The server (my Linode VPS) is running WireGuard listening on as well as an instance of wstunnel which forwards TCP packets to UDP

The client, which in my tests was a Windows machine, used wstunnel and WireGuard again but as a client. The WireGuard config used as the VPN endpoint and ws tunnel would then listen on UDP and forward it to TCP [my vps ip]:443 over a pre-established websocket.

Still not getting any luck, furthermore the GL.iNet forum seems to be pretty hostile and dead.

Either way, my end goal is to successfully use my OpenWrt router as a WireGuard client over a TCP tunnel so that all of my router's clients are automatically VPN'd to the WireGuard server.

Thank you,

Same thread as maurer sent me above. Didn't work unfortunately.


How about ?
If this doesn't work maybe it's time for a different approach like openvpn over tcp443 or sstp vpn.

1 Like

I already suspected in in the previous post, that your device runs some vendor-specific fork of OpenWRT with unknown modifications (it is not da real thing). The vendor was probably just too lazy, to add some „modified by…“ note.

You may need to clarify this with GL net support or GL net forum people. Or wait until a regular open OpenWRT version gets released for the device

1 Like

If you have allowed_ips '' and route_allowed_ips '1' options set on the router, you'll need to define a static route for the VPS through the wan interface. This is because in order to pass the wireguard traffic through the udp2raw-tunnel, the endpoint ip address must be set to, so the wireguard service will not automatically create the route for you.

I ran some tests using udp2raw and wireguard on two OpenWrt devices, but the result was very disappointing - 40÷60% packet loss.

1 Like

Hi Pavel,

Very interesting!

I indeed had allowed_ips '' but not route_allowed_ips '1' set up on the router's WireGuard client.

the endpoint ip address must be set to

I understand why this makes sense, but what I don't understand is that wstunnel worked without any additional configuration to the WireGuard server...

so the wireguard service will not automatically create the route for you.

Ah, this makes sense why the tunnel tries to go over WireGuard itself. Shouldn't static routes be defined on both the router and VPS though, or just VPS? I apologize for my silly questions

I ran some tests using udp2raw and wireguard on two OpenWrt devices, but the result was very disappointing - 40÷60% packet loss.

Is this situational to how stable the internet is? Both the VPS's uplink and the firewall'd networks are pretty stable (I think?). Often very little packet loss and never above 0.5ms jitter latency. Also, udp2raw in TCP mode (I think it's called FakeTCP), doesn't TCP prevent packet loss? Or is it literally a FakeTCP that are actually UDP packets with TCP headers?

Thanks for your very insightful response


Alright.. It is indeed a vendor fork of OpenWrt, and comes with some inbuilt programs that control the fans, LEDs and random stuff related to the hardware/firmware interface.

It is not a very stable OS + hardware pair for sure, and under even a little bit of CPU load (not network load) gets very slow and sometimes straight up doesn't work until you yank the power cable out.


Hi Maurer,

I'll have a lot at wireguard-proxy soon. It seems interesting and it could work..

OpenVPN will never work - It's handshake is blocked by deep packet inspection

Additionally, you said sstp vpn

I had a look at the sstp protocol on wikipedia, and saw this clause:

SoftEther VPN, an open-source VPN server program which supports SSTP-VPN protocol.

I have historically used SoftEther in the past, and it did work!! However, one day, it got entirely blocked. I'm unsure how they blocked SoftEther since it used SSTP/HTTPS as per:

But nonetheless it got blocked - I assume since the Firewall/Proxy decrypts the traffic between the VPN server and itself, thus can realize it is a VPN packet and drop it between my computers connection to the proxy.

My implementation of WireGuard over WebSockets probably worked since the proxy didn't realize the WebSocket was a VPN packet since its unlikely it has seen wstunnel on the network before.

I'm unsure,


Then wireguard disconnects for some other reason.

I can tell how udp2raw works:

./udp2raw_mips24kc_be -s -l <server_wan_IP>:443 -r -k "passwd"

Requests coming on tcp port 443 on the wan interface of the server are forwarded to udp port 51820 (the wireguard listening port) on localhost.

That's why the endpoint address shown is<some_random_port>.

root@Office:~# wg
interface: wg0
  public key: =
  private key: (hidden)
  listening port: 51820

peer: =
  preshared key: (hidden)
  allowed ips:,
  latest handshake: 1 minute, 42 seconds ago
  transfer: 1.34 MiB received, 6.44 MiB sent
  persistent keepalive: every 25 seconds

You need to create a static route only on the router and it should look like this:


config route
        option target '' # VPS public ip
        option gateway '' # wan gateway
        option interface 'wan' # wan interface logical ifname

Unfortunately no. For the tests I used an existing permanent wireguard connection, which usually works flawlessly. The problems started as soon as udp2raw was involved...

I've tested WireGuard over shadowsocks-libev proposed by @maurer and it works.
The tunnel endpoint is best routed with PBR as it eliminates the need for WAN gateway.


Probably easiest to use XTLS/VLESS. There's even a LUCI module available :slight_smile:

Hey Vladislav,

I appreciate your response and I apologize for my late reply - been busy with life things...

Regarding your solution, what do you mean by this?

Particularly, what's a PBR and what do you mean by WAN gateway?

I understand what both acronyms mean however why would I need to eliminate the WAN gateway, if, what WAN gateway? The router is acting as a repeater so I can secure the repeated (public/corporate) network and use my own devices while on a VPN, thus I assume the WAN gateway in this instance is the gateway on the repeated network?


Hello Bogorad,

Too many acronyms!
And what's an Xray client?

Is this like a very feature-rich multi-protocol reverse proxy?

Much appreciated,

This is not specific to your setup, but it is generally a better option as it fits both static and dynamic setups where the WAN gateway may change over time.

It's a topic for a long afternoon :slight_smile:

In short, XTLS is also known as "Project X", a sorta-kinda unifying umbrella (and packet soft-router) for a bunch of protocols developed by (mostly) Chinese devs to bypass The Great Firewall. The Great Firewall is fully integrated into the state-controlled national internet, so it knows a lot - including traffic patterns, directions, ownership of IP address blocks, etc etc etc. It also does active probing (e.g., if it sees a lot of traffic originating from an IP address, it actively probes if this IP has open ports, and if it does, considers it a proxy/VPN endpoint). And so much more.

So, to hide from it (bypass it) effectively, they came up with a host of technologies. Currently, the most effective one is XTLS-Reality+VLESS.

XTLS is a simple packet router, basically a hack of TLS-1.3 that enables concealed VPN endpoint access. The way the Reality part works is (I'm oversimplifying, obviously): if it sees an HTTPS request for a website, say, from a source it knows (signatures, salted hashes, etc.) - it allows the client VPN access. Otherwise, the requestor gets content from, so even a replay attack won't reveal the VPN endpoint.

VLESS is a very simple and efficient protocol without encryption - it's done on the TLS level.

Another thing to keep in mind - the whole thing is serverless. The client usually runs the same code as the server.

So you set up the server, define client IDs, then set up clients. Clients access the server via port 443, claiming to request the URL of your choice, and no one is the wiser.

The LUCI app I mentioned does it all but only allows one user-ID for now. They promised to fix it, though.

The configuration (if you choose to do it all manually) is explained in painstaking detail here

Also, there are many example configs, mostly in Chinese though :slight_smile:

P.S. Oh, and Russians use it too, here's an article in Russian (google translate does a decent job)


Hi everyone, Rat again,

[in reply to @maurer @Pico @pavelgl]

I believe I've fixed it for the time being, I'll have to run a "production" test since it works on my local network.

I found a wstunnel Armv7 executable and have ran that using a custom init script that runs on startup with a 20s delay to ensure the router gains a connection first.

I also (with the Gl.iNet software) added a VPN bypass rule which contained my VPS IP which prevented wstunnel tunnelling through a broken VPN connection (this was so silly haha)

I didn't have to do any additional config, however finding a working wstunnel executable that actually ran was the hardest part of this whole journey. Unfortunately, the version of WireGuard this proprietary OS ships with does not allow PreUp, PostDown etc scripts, so I had to write an init script that I mentioned above, and this was a bit challenging since I've never done this before.

Anyways, thank you all for your suggestions and patience with me, I'll keep you updated if there is anything that goes wrong

If any newcomers want additional info/configs, feel free to mention me. I won't add them to this reply since it's already gotten to big.


1 Like