How to use TUN to create a tunnel between two servers
An example in FreeBSD
Introduction
VPNs are the normal way to connect several systems to the same network and behind the scenes VPN software often creates a virtual interface. In this post we explore how to configure a tunnel without any VPN. It will not provide ciphering but it will allow two nodes to be connected to the same network.
These are some of my notes on TUN tunnels. I managed to get a host within a LAN to establish a tunnel against an external server with NAT (so the host was effectively geolocated within the IP of the server and not within the IP of the LAN) but for example I have not managed yet to configure that host as a valid gateway for other hosts in the LAN.
TUN and TAP
TUN and TAP are the virtual interfaces that create tunnels for Layer 3 (IP) and Layer 2 (Ethernet) respectively. In this post I will provide an example of TUN.
There are several use case for TUN and TAP virtual interfaces. The scenario thats I will cover here will be as follows: we want Host B1 in LAN B to use the Public IP address of Server A1. We basically want Host B1 to route all traffic via Server A1.
The example is pretty basic and can be used as it is for geo-blocking bypass and more generally as a basic example that can be enhanced to create custom point to point tunnels between networks.
Create TUN interface in the server
To create a TUN interface we will use ifconfig. 192.168.100.1 will be the address of the server and 192.168.100.2 the address of the client.
# ifconfig tun0 create
# ifconfig
...
tun0: flags=8010<POINTOPOINT,MULTICAST> metric 0 mtu 1500
options=80000<LINKSTATE>
groups: tun
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
...
# ifconfig 192.168.100.1/24 192.168.100.2
Server configuration
A TUN interface is just a virtual interface that exposes the interface to the user space. To actually transport traffic you need a program which links both interfaces (for example via a TCP Socket). TUN interfaces are used under the hood by VPNs such as OpenVPN.
In this example we will use a simple tunneling application named vtun. The configuration file is:
$ cat /etc/vtund-server.conf
options {
port 22222; # Listen on this port # Command path
ifconfig /sbin/ifconfig;
route /sbin/route;
}
default {
speed 0; # By default maximum speed, NO shaping
type tun;
proto tcp;
keepalive yes;
}
client1 {
passwd myPassword;
keepalive yes;
type tun;
proto tcp;
}
And the launch command is:
$ vtund -f /etc/vtund-server.conf -s
Create TUN interface in the client
# ifconfig tun0 create
# ifconfig
...
tun0: flags=8010<POINTOPOINT,MULTICAST> metric 0 mtu 1500
options=80000<LINKSTATE>
groups: tun
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
...
# ifconfig 192.168.100.2/24 192.168.100.1
Client configuration
The configuration file is:
$ cat /etc/vtund-client.conf
options {
port 22222;
ifconfig /sbin/ifconfig;
route /sbin/route;
}
client1 {
passwd myPassword;
keepalive yes;
type tun;
proto tcp;
}
And the launch command is:
$ vtund -f /etc/vtund-client.conf client1 X.Y.W.Z
Where X.Y.W.Z
is the public IP of the server (firewall port 22222 must be open).
Routing
If the client is in another network (for example 192.168.0.0/24) we will have to adapt routing, for example setting a default route through 192.168.100.1 will forward all traffic through the server 1. A NAT roule can be later set up at the server so we will effectively have a point to point gateway.
Remember that a specific rule to access X.Y.W.Z
must be in place to ensure that the rule goes through the standard gateway.
Resources
https://www.lixu.ca/2014/04/linux-how-to-setup-vtun-between-ubuntu.html
https://backreference.org/2010/03/26/tuntap-interface-tutorial/