[HACK] UDP tunneling over TCP for WireGuard

Luca Beltrame lbeltrame at kde.org
Wed Apr 18 13:55:33 CEST 2018


at one of the places I use WireGuard, outgoing UDP is *completely* blocked by 
the perimeter firewall. In addition, only a handful of ports are open. (Not 
that this has helped security in any way, but I digress)

This meant that I could not connect to my WireGuard-using OpenWRT router which 
is somewhere else. 

As a happy WireGuard user, I thought about how to handle this. Port was an 
easy solution: 587 is open, so I could just have the router redirect it to the 
actual endpoint port. UDP, not so much.

What came out was a horrid hack involving socat and sacrifices to the Great 
Old Ones, but that it worked enough for me.

tl;dr: Use socat to tunnel local UDP port via TCP to a remote port, then 
redirect UDP there to the actual WireGuard endpoint port.

First of all, I set a systemd unit to have this running continuously:

Description=UDP over TCP forwarder
After=autossh at tsugumi.service

ExecStart=/usr/bin/socat -t600 -T600 -d -d UDP4-LISTEN:51821 tcp4:ENDPOINT_IP:


I set fairly high timeouts because WireGuard is not very chatty and socat 
usually exists when there's no traffic for a while.

Then, I set the relevant bits in wg0.conf:

ListenPort = 51820
PrivateKey =<redacted>
Address =

PublicKey = <redacted>
AllowedIPs =,<internal router LAN IP range>
Endpoint =
PersistentKeepalive = 60

As you notice, it goes to localhost then it's pushed via TCP to the remote 
endpoint. At this time, I had to lower the MTU to adjust for overhead (as 
discussed on IRC) that I introduced with this monstrosity. 

On the remote side, I have (running through openWRT's init):

/usr/bin/socat -d -d tcp4-listen:587,reuseaddr,fork UDP4:

which brings packets back to port 51820, where wg is listening.

And voila', it works:

interface: wg0
  public key: <redacted>
  private key: (hidden)
  listening port: 51820

peer: <redacted>
  allowed ips:, <LAN>
  latest handshake: 30 seconds ago
  transfer: 300.68 MiB received, 175.78 MiB sent
  persistent keepalive: every 1 minute

Very hacky, but gets the job done. Any suggestions on how to make it better?

Luca Beltrame - KDE Forums team
KDE Science supporter
GPG key ID: A29D259B
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.zx2c4.com/pipermail/wireguard/attachments/20180418/10e859b2/attachment.asc>

More information about the WireGuard mailing list