Skip to content

Instantly share code, notes, and snippets.

@insdavm
Last active May 12, 2024 03:28
Show Gist options
  • Save insdavm/90cbeffe76ba4a51251d83af604adf94 to your computer and use it in GitHub Desktop.
Save insdavm/90cbeffe76ba4a51251d83af604adf94 to your computer and use it in GitHub Desktop.
WireGuard over TCP with udptunnel

WireGuard over TCP with udptunnel

udptunnel is a small program which can tunnel UDP packets bi-directionally over a TCP connection. Its primary purpose (and original motivation) is to allow multi-media conferences to traverse a firewall which allows only outgoing TCP connections.

Server

# udptunnel -s 443 127.0.0.1/51820

Client

# udptunnel -c [SERVER PUBLIC IP]/443 127.0.0.1 50001
  • Remember to open TCP port 443 on the server's firewall
  • In the WireGuard client config file, replace the server's public IP (endpoint) with 127.0.0.1:50001
@testingnic
Copy link

I've been facing the same issues with "Address already in use". Other projects did not work for me as well.... So, I've created https://github.com/arkq/wg-tcp-tunnel which handles everything properly. Also, one does not need root privilege to run it. I'm using it on RPi4 (behind NAT using ngrok) and not-rooted Android phone (via Termux). On Android the wg-tcp-tunnel is compiled in Termux as well, since it only depends on Boost and STL. The README explains how to use it.

Bro can this be used with ovpn?

@andrew-aladjev
Copy link

andrew-aladjev commented Apr 21, 2024

Ok, I've figured it out. udptunnel is trying to bind on 0.0.0.0 and after that it is trying to bind on :: using the same port. Second bind will fail if /proc/sys/net/ipv6/bindv6only is 0. You can disable this flag using sysctl net.ipv6.bindv6only = 1, but don't do it, because you will ruin other applications that may depend on bindv6only = 0, they may expect that binding on 0.0.0.0 implies binding on ::.

I am going to provide pull request to udptunnel that will fix it.

@testingnic
Copy link

Ok, I've figured it out. udptunnel is trying to bind on 0.0.0.0 and after that it is trying to bind on :: using the same port. Second bind will fail if /proc/sys/net/ipv6/bindv6only is 0. You can disable this flag using sysctl net.ipv6.bindv6only = 1, but don't do it, because you will ruin other applications that may depend on bindv6only = 0, they may expect that binding on 0.0.0.0 implies binding on ::.

I am going to provide pull request to udptunnel that will fix it.

I HOPE YOU PROVIDE A GUIDE ON THIS

@patrickzzz
Copy link

Sounds good.. would be nice to find a solution.
https://manpages.ubuntu.com/manpages/focal/man1/udptunnel.1.html shows that IPv6 is not supported, maybe due to this or even bigger problems..

@andrew-aladjev
Copy link

I've added issue and pull request.

@testingnic My patch is trivial, and it fixes a well-known problem with ipv6. You can email the maintainer of your distro (Ubuntu, OpenWrt, etc) and it will add this patch for sure. I will also send emails to Ubuntu and OpenWRT distro so they may release a patched version of udptunnel soon.

For now you can't do anything except net.ipv6.bindv6only = 1, but please don't do it.

@andrew-aladjev
Copy link

I've investigated openwrt udptunnel and found that its version is really ancient, maybe udptunnel from 1999, it supports only IPv4 (it is specified in sin_family).

@patrickzzz, Ubuntu uses the same ancient version as OpenWRT.
@testingnic We need to wait until package maintainers start using the recent udptunnel from github. For now, we can only build it manually and install it locally.

Gentoo has tamiko overlay with same ancient version of udptunnel.

So everything is pretty bad for regular user, you need to build recent udptunnel from github manually and install it locally.

@testingnic
Copy link

but how do I download the latest update if it hasn't been updated in 9 years ahaha

@testingnic
Copy link

https://twitter.com/rfc1036

twitter creator

@andrew-aladjev
Copy link

andrew-aladjev commented Apr 22, 2024

@testingnic, please just download it from github, apply important important patches and build it.

git clone https://github.com/rfc1036/udptunnel.git
cd udptunnel

curl https://patch-diff.githubusercontent.com/raw/rfc1036/udptunnel/pull/5.patch -o /tmp/5.patch
git apply /tmp/5.patch

curl https://patch-diff.githubusercontent.com/raw/rfc1036/udptunnel/pull/14.patch -o /tmp/14.patch
git apply /tmp/14.patch

make

sudo ./udptunnel -s 443 127.0.0.1/51820

@andrew-aladjev
Copy link

andrew-aladjev commented Apr 22, 2024

@testingnic, I've made the udptunnel-1.2.0 release in my own fork with deb and rpm packages, because we can wait for @rfc1036 almost forever. You can now just download and install it.

@andrew-aladjev
Copy link

andrew-aladjev commented Apr 22, 2024

I've added here my gist with configs. I've tested it on several machines and it works perfect. Please try it.

PS From my experience TCP tunnel is a bit faster than UDP in several countries, because of QOS.

@patrickzzz
Copy link

well done so far.. although i don't like to use unmaintained software-packages for this purposes.. ;-(

@andrew-aladjev
Copy link

@patrickzzz I am also using wstunnel. It is maintainable and easy. Of course he can't bypass GFC, but it can provide good experience in any country except China.

udptunnel is required for low memory devices like old routers with openwrt. I don't really see any requirement for further udptunnel updates and maintenance.

@testingnic
Copy link

Tranks bro 💖

@andrew-aladjev
Copy link

I've made additional work on wireguard routing. You may be interested in it. Question is here, gist with route scripts and configs here.

@testingnic
Copy link

I've made additional work on wireguard routing. You may be interested in it. Question is here, gist with route scripts and configs here.

udp puncher could be added

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment