Wireguard tunnel via TCP

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?

2 Likes

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:
https://balaskas.gr/blog/2019/07/20/a-dead-simple-vpn/

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

5 Likes

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:
https://forum.openwrt.org/t/solved-gre-tunnel-routing/25644

https://openwrt.org/docs/guide-user/network/tunneling_interface_protocols#protocol_gre_gre_tunnel_over_ipv4

and

https://openwrt.org/docs/guide-user/network/routing_in_gre

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.

2 Likes

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.

I looked into UDPTunnel, for some reason it doesn't work in openwrt. GRE is an option, hopefully this forum will bring more attraction and other ideas.

akari190

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

Port 53 (DNS) worked fine for me, from a hotel with paranoid firewall settings.

Cheers!

That is not paranoid at all.
A firewall can easily intercept plain DNS and NTP.
And redirected it the local service as already mentioned above.
So this is not an option in general case.