Open main menu

Funtoo β

Tinc

Tinc is a Virtual Private Network (VPN) daemon that uses tunnelling and encryption to create a secure private network between hosts on the Internet.

Here are main features at a glance:

  • Encryption, authentication and compression
    • All traffic is optionally compressed using zlib or LZO, and LibreSSL or OpenSSL is used to encrypt the traffic and protect it from alteration with message authentication codes and sequence numbers.
  • Automatic full mesh routing
    • Regardless of how you set up the tinc daemons to connect to each other, VPN traffic is always (if possible) sent directly to the destination, without going through intermediate hops.
  • NAT traversal
    • As long as one node in the VPN allows incoming connections on a public IP address (even if it is a dynamic IP address), tinc will be able to do NAT traversal, allowing direct communication between peers.
  • Easily expand your VPN
    • When you want to add nodes to your VPN, all you have to do is add an extra configuration file, there is no need to start new daemons or create and configure new devices or network interfaces.
  • Ability to bridge ethernet segments
    • You can link multiple ethernet segments together to work like a single segment, allowing you to run applications and games that normally only work on a LAN over the Internet.
  • Runs on many operating systems and supports IPv6
    • Currently Linux, FreeBSD, OpenBSD, NetBSD, OS X, Solaris, Windows 2000, XP, Vista and Windows 7 and 8 platforms are supported.

Required Kernel Options

Network device support
<M> Universal tun/tap device driver support

Installing tinc

in Funtoo Linux as easy as:

root # emerge -av net-vpn/tinc
These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild  N     ] dev-libs/lzo-2.10:2::dev-kit  USE="-examples -static-libs" ABI_X86="32 (64) (-x32)" 587 KiB
[ebuild  N     ] net-vpn/tinc-1.1_pre15::net-kit  USE="lzo ncurses readline ssl zlib -gui -libressl -uml -upnp -vde" PYTHON_TARGETS="python2_7" 688 KiB

Total: 2 packages (2 new), Size of downloads: 1,275 KiB

Would you like to merge these packages? [Yes/No]

Configuring tincd

Basic two node setup

We're going to deploy two servers to talk to each other via tinc vpn, let's call them serverA and serverB for now. Note that technically tinc is a mesh network, so there's no 'master' server, simply a node which doesn't connect to any others, but is connected to. This is great because we can use multiple ConnectTo statements in tinc.conf to achieve a highly-available VPN. We will be using 10.10.0.0/24 as VPN network. We will set the serverA on 10.10.0.1 and the serverB on 10.10.0.2.

We're going to call our VPN interface funvpn, so on both servers install Tinc as per the above instructions and then let's init some directories/files:

root # tinc -n funvpn init
Enter the Name you want your tinc node to have: serverA
Generating 2048 bits keys:
..............................+++ p
............+++ q
Done.
Generating Ed25519 keypair:
Done.

This is going to init the files on both servers and generate secret/public keypairs, the files are stored in /etc/tinc/funvpn. First, let's edit tinc.conf on the serverA:

root # cat /etc/tinc/funvpn/tinc.conf
 Name=serverA
 Mode=switch
 
 ConnectTo=serverB

And on the serverB:

root # cat /etc/tinc/funvpn/tinc.conf

 Name=serverB
 Mode=switch
 
 ConnectTo=serverA

Now we have to edit /etc/tinc/funvpn/hosts/serverA serverB files. Put the address of serverA in hosts/serverA and do the same for serverB. Leave the rest of the file intact.

root # cat /etc/tinc/funvpn/hosts/serverA

 Address=YOUR IP

Next you need to copy the hosts/server{A,B} files so both nodes have both files. That's everything directly Tinc related complete!

However, the network won't run yet, we need to edit tinc-up and tinc-down scripts on each node to setup the interface. These files will look very similar on both servers, only the IP of the interface will change:

root # cat tinc-up
root #!/bin/sh
IP=`which ip`
user $IP link set dev $INTERFACE up
user $IP addr add dev $INTERFACE 10.10.0.1/24 broadcast 10.10.0.255 scope link

All you do is replace <10.10.0.1 OR 10.10.0.2> with the IP of whichever node you are on. Finally:

root # cat tinc-down:
root #!/bin/sh
IP=`which ip`
user $IP addr del dev $INTERFACE 10.10.0.1/24 broadcast 10.10.0.255 scope link
user $IP link set dev $INTERFACE down

We are almost done. Now we need to do just couple of last config changes.

Modify /etc/conf.d/tinc.networks:

root #  cat /etc/conf.d/tinc.networks
NETWORK: funvpn

And add tincd to default group of startup scripts.

root # rc-update add tincd
root # rc

And, that should be it! Now you should be able to ping each of the servers.

root # ip a show funvpn
2: funvpn: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/ether 52:d3:ef:32:f7:68 brd ff:ff:ff:ff:ff:ff
    inet 10.10.0.1/24 brd 10.10.0.255 scope link funvpn
       valid_lft forever preferred_lft forever
    inet6 fe80::50d3:efff:fe32:f768/64 scope link 
       valid_lft forever preferred_lft forever
root # ping -c3 10.10.0.2
PING 10.10.0.2 (10.10.0.2) 56(84) bytes of data.
64 bytes from 10.10.0.2: icmp_seq=1 ttl=64 time=0.200 ms
64 bytes from 10.10.0.2: icmp_seq=2 ttl=64 time=0.413 ms
64 bytes from 10.10.0.2: icmp_seq=3 ttl=64 time=0.404 ms

--- 10.10.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2065ms
rtt min/avg/max/mdev = 0.200/0.339/0.413/0.098 ms
root # tinc --pid /run/tinc.funvpn.pid 
tinc> dump nodes
serverA id 69e6a1655650 at MYSELF port 655 cipher 0 digest 0 maclength 0 compression 0 options 700000c status 0858 nexthop serverA via serverA distance 0 pmtu 9018 (min 0 max 9018)
serverB id 5ec1fc5912bb at 10.214.101.59 port 655 cipher 0 digest 0 maclength 0 compression 0 options 700000c status 08da nexthop serverB via serverB distance 1 pmtu 1439 (min 1439 max 1439)
tinc>

Multi-node setup

Now let's add another 2 nodes to the setup.