Wireguard tunnel via TCP

Actually code works very well. But it's abandoned...

WG intentionally doesn't use TCP for a variety of reasons. Probably the two most important factors are performance and stealth (it is not 'chatty' so it will never respond to probes or any packets unless the cryptographic payload is correct). Of course, WireGuard allows TCP to be turned within the UDP stream.

Wrapping TCP around the UDP WireGuard stream that encapsulates TCP+UDP data will reduce performance and negate part of the stealth component.

That said, you will not find a way to run WG via TCP in the native context. If you want to encapsulate the WG stream in TCP, you will need to have that connection established first (on both sides) and then you can initiate the WG connection. For example, if you were to use something like stunnel, your peers would have to first connect via stunnel and then open the WG session. This will make it considerably harder (or maybe impossible) to operate this on mobile OSs, but it could be done with desktop systems and/or another OpenWrt (or similar) system.

Returning back to your original ask -- can you describe why you want to do the TCP wrapper for your WireGuard setup? It is unnecessary in many/most contexts, but there are certainly outlier situations that may require a different approach.

1 Like

Due to ISP restriction I am looking to see if we can use the TCP wrapper. UDP is blocked.

I would guess the fact that encapsulating TCP packets in a TCP tunnel is problematic, because lost packets will trigger recovery/retransmission independently for the outer and the inner TCP connection, resulting in loads of duplicate data transfers that eat up bandwidth without delivering goodput... one could subsume this under "performance" but IMHO worth spelling out exlicitly, no?


Very much worth the explicit call out. Thanks for adding it.

If you're really need TCP-over-TCP then it's good to take one look on DSVPN:

and explanation how it works:

But this is one-to-one VPN. One client connect to one server.

Than it would make more sense to use openvpn instead of a wireguard forced into TCP


Everyone here mentioned a good point; but let's think outside the box.
there are other values if we start thinking about how to accomplish this.
Openvpn cuts your bandwidth by 2/3 and it is terrible of handling packet loss. wireguard uses latest encryption and it's written in 4000 lines of code where openvpn it stacks up to 100,000 lines of code. I am looking for, is it possible to implement wireguard over TCP and if so how.... The rest we can debate once we identify a way of getting it done.

Thinking outside the box, how about a GRE tunnel to a VPS and wireguard over UDP inside of that tunnel? Unless your ISP only allows TCP that might work....

I like where this is going, but GRE is not encrypted and you'll need to add IPsec on top of it if you want the traffic to be encrypted. Also will GRE without IPsec allows the ISP to determine the protocol being used. I think so.

Your ISP blocks all UDP traffic? That seems excessive. What ISP is it?

Blocking UDP entirely would only disrupt important things such as DNS & NTP (for time sync).
So it makes sense if they (the ISP) won't interfere with that.

Instead of using TCP, why don't try to use UDP port 53 & UDP port 123?
I'm pretty sure it won't get blocked

1 Like

Well, the idea is to use GRE to get around your IPS UDP block. GRE is basically IIUC IP in IP, so instead of IP->UDP your ISP will see IP->IP->UDP and that might be enough to work around its filter rules. And if that works, you just use wireguard for the inner UDP traffic so that things are encrypted. Te outer IP header will have a fixed address pair, as will the inner IP header, and the UDP traffic will use (relatively) fixed UDP ports, so not much information that can leak to your ISP....

Using IPsec to transport wireguard encrypted packets, seems sub-optimal, because you are doing crypto twice then; I can construct scenarios in which double encryption might be a sane solution, but it is a stretch ;)....

That would be DNS and NTP, blocking UDP/53 would not affect clients since DNS falls back to TCP if UDP does not work and for NTP rate-limiting by the ISP would work (hopefully with a simply dropping policer and not with a traffic shaper+queue, but I digress).

Well yes, there's a possibility to rate-limit NTP packets, but I don't think it would apply on all ISP (maybe they forgot to do it)

Ok, I am onboard; anything I can reference to get this done using openwrt?

What makes you believe that the fantasy solution you are creating by putting Wireguard into some kind of TCP tunnel would not have the same issues?

1 Like

Mmmh, a quick search revealed:




But you will need to rent a server/VPS somewhere "in the cloud" to terminate your GRE tunnel...

Personally, I have no first hand experience with GRE (or wireguard) so I will not be of much help from here on....

GRE requires both endpoint IPs, expecting public addresses over the internet.
Also, a domain endpoint is not supported by netifd, so it may need custom scripts with DDNS.
Thus I'm afraid GRE is not suitable in this case, and other VPNs should fit better.


Yeah this is a bit annoying with Wireguard. I fully understand why, the TCP back off is not great with TCP connections running over a TCP tunnel. Sadly there is sometimes no choice, lots of people block UDP.

You can basically:
1/ Go hunting for open UDP ports NTP, DNS or Traceroute (also a good one). This is increasingly hard with more deep packet inspection (even light packet inspection can detect things like too much traffic over these). I have seen (increasingly) networks that just allow TCP port 80 and 443, and UDP 53 to only their local DNS server.

2/ Use udptunnel, no magic solution either. It doesn't look very HTTPS or HTTP to any deep packet inspection, so can be blocked easily, especially by state actors.

3/ For OpenVPN I have two servers, the UDP listener when allowed for good performance. And a TCP listener I connect via "stunnel" to. The stunnel wraps a TLS connection on top of the OpenVPN, so looks quite HTTPS to DPI. This pretty much always works for me.

But no option to do this with the UDP of Wireguard. And things are starting to get messy if you layer Wireguard -> udptunnel -> stunnel. It would be nice if stunnel were to offer a UDP option.

This is what stops me going full Wireguard. There are lots of places I need to use TCP VPN, so long as the network is stable it works pretty well, and maybe my only option.