Daemon for creating a simple VPN over UDP.
Go Shell
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
misc Initial commit of udptunnel Apr 18, 2017
README.md Mention support for Linux only Apr 19, 2017
logger.go Support user-configured heartbeat intervals Apr 16, 2018
main.go Support user-configured heartbeat intervals Apr 16, 2018
tunnel.go Support user-configured heartbeat intervals Apr 16, 2018
tunnel_test.go Add support for running on OSX Feb 26, 2018


UDP virtual private tunnel daemon


This repository contains a simple implementation of a point-to-point virtual private network by opening a TUN device and transferring raw traffic over UDP. This VPN was designed to create a tunnel between two hosts:

  1. A client host operating behind an obtrusive NAT which drops TCP connections frequently, but happens to pass UDP traffic reliably.
  2. A server host that is internet-accessible.

TUN traffic is sent ad-verbatim between the two endpoints via unencrypted UDP packets. Thus, this should only be used if a more secure protocol (like SSH; see github.com/dsnet/sshtunnel) is running on top of this VPN. In order to prevent attackers from connecting to other locally binded sockets on the endpoints, a simple port filter is built-in to restrict IP traffic to only the specified ports. Users of udptunnel should also setup iptable rules as a secondary measure to restrict malicious traffic.

This only supports Linux.


Build the daemon:

go get -u github.com/dsnet/udptunnel

Create a server configuration file:

	"TunnelAddress": "",
	"NetworkAddress": ":8000",
	"AllowedPorts": [22],

The NetworkAddress with an empty host indicates that the daemon is operating in server mode.

Create a client configuration file:

	"TunnelAddress": "",
	"NetworkAddress": "server.example.com:8000",
	"AllowedPorts": [22],

The host server.example.com is assumed to resolve to some address where the client can reach the server.

Start the daemon on both the client and server (assuming $GOPATH/bin is in your $PATH):

root@server.example.com $ udptunnel /path/to/config.json
root@client.example.com $ udptunnel /path/to/config.json

Try accessing the other endpoint (example is for client to server):

user@client.example.com $ ping
PING ( 56(84) bytes of data.
64 bytes from icmp_req=1 ttl=64 time=56.7 ms
64 bytes from icmp_req=2 ttl=64 time=58.7 ms
64 bytes from icmp_req=3 ttl=64 time=50.1 ms
64 bytes from icmp_req=4 ttl=64 time=51.6 ms

user@client.example.com $ nmap
Host is up (0.063s latency).
22/tcp open  ssh

user@client.example.com $ ssh
Password: ...

The above example shows the client trying to communicate with the server, which is addressable at The example commands can be done from the server by dialing the client at, instead.