How to install tinc VPN on Ubuntu Linux 16.04 to secure traffic

Posted on in Categories , , , last updated June 27, 2017

I have two VPS running in the cloud. The first one is the database, and another one is the web server. I want to secure traffic that flows between private network which is insecure by design and I do not want to use OpenVPN due to complex settings. How do I install and setup tinc VPN server and secure my traffic over VPN on Ubuntu Linux 16.04 LTS server?

tinc is a Virtual Private Network (VPN) server that uses tunneling and encryption to create a secure private network between hosts on the Internet or private insecure LAN. tinc is a Free Software and licensed under the GNU General Public License version 2 or later. tinc has the following features:

  1. Easy to setup
  2. Encryption, authentication and compression
  3. Automatic full mesh routing
  4. NAT traversal
  5. Easily expand your VPN
  6. Ability to bridge ethernet segments
  7. Runs on many operating systems and supports IPv6 including Linux, FreeBSD, OpenBSD, NetBSD, OS X, Solaris, Windows 2000, XP, Vista and Windows 7/8/10.

This tutorial shows you how to install tinc on Ubuntu Linux 16.04 LTS server and create a secure VPN between two nodes either connected over the Internet or private LAN running in the cloud setup.

Our sample setup

Fig.01: Here is a sample diagram of the VPN for our setup
Fig.01: Here is a sample diagram of the VPN for our setup

You need two servers as follows in the same data center:

  • serverA: Our main server and all VPN client will connect to serverA i.e. server B and serverC and so on. It runs database server and memcached.
  • serverB: Our client. It runs web server too. Web server will connect to the mysql using vpn0 link.

WARNING: You must have an adequate understanding of networks in general. This tutorial deals with making changes to the firewall, and you must understand IP address/subnets and firewall rules. An excellent resource on networking is the Networking for Systems Administrators book.

Installation

Us the following apt-get command or apt command to install the tinc on both serverA and serverB:
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install tinc

Sample outputs:

Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  tinc
0 upgraded, 1 newly installed, 0 to remove and 7 not upgraded.
Need to get 165 kB of archives.
After this operation, 655 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu xenial/universe amd64 tinc amd64 1.0.26-1 [165 kB]
Fetched 165 kB in 1s (85.6 kB/s)     
Selecting previously unselected package tinc.
(Reading database ... 42846 files and directories currently installed.)
Preparing to unpack .../tinc_1.0.26-1_amd64.deb ...
Unpacking tinc (1.0.26-1) ...
Processing triggers for systemd (229-4ubuntu17) ...
Processing triggers for ureadahead (0.100.0-19) ...
Processing triggers for man-db (2.7.5-1) ...
Processing triggers for install-info (6.1.0.dfsg.1-5) ...
Setting up tinc (1.0.26-1) ...
Processing triggers for systemd (229-4ubuntu17) ...
Processing triggers for ureadahead (0.100.0-19) ...

tinc configuration on serverA

Type the following command as root user on serverA only.

Step 1: Create directories on serverA

Type the following mkdir command:
$ sudo mkdir -p /etc/tinc/vpn0/hosts/

Step 2: Create the config file on serverA

Type the following vi command:
$ sudo vi /etc/tinc/vpn0/tinc.conf
Append the following:
Name = serverA
Device = /dev/net/tun
BindToAddress = 192.168.4.5
AddressFamily = ipv4

Step 3: Create the public and private key for serverA

$ sudo tincd -n vpn0 -K4096
Sample outputs:

Generating 4096 bits keys:
...........................................................................
.........................................................................++ q
Done.
Please enter a file to save private RSA key to [/etc/tinc/vpn0/rsa_key.priv]: 
Please enter a file to save public RSA key to [/etc/tinc/vpn0/hosts/serverA]:

Step 4: Setup IP addresses to the host files that tinc created on serverA

$ sudo vi /etc/tinc/vpn0/hosts/serverA
Add the following at the top of the file:

Address = 192.168.4.5
Subnet = 172.16.1.1/32

-----BEGIN RSA PUBLIC KEY-----
.....
...
your random key here
....
-----END RSA PUBLIC KEY-----

Step 5: Create network interface control scripts on serverA

Create a tinc-up script:
$ sudo vi /etc/tinc/vpn0/tinc-up
Append the following:

#!/bin/sh
#
# Must use IP 172.16.1.1, which is setup in /etc/tinc/vpn0/hosts/serverA
#
/sbin/ifconfig $INTERFACE 172.16.1.1 netmask 255.255.255.0

Create a tinc-down script:
$ sudo vi /etc/tinc/vpn0/tinc-down
Append the following content:

#!/bin/sh
/sbin/ifconfig $INTERFACE down

Finally setup executable permission using the chmod command:
$ sudo chmod -v +x /etc/tinc/vpn0/tinc-{up,down}

Step 6: Update firewall rules on serverA

Type the following ufw command to open port tcp 655:
$ sudo ufw allow from 192.168.4.6 to 192.168.4.5 port 655 proto tcp comment 'Allow serverA tincd to talk vpn client'
Type the following ufw command to open port udp 655:
$ sudo ufw allow from 192.168.4.6 to 192.168.4.5 port 655 proto udp comment 'Allow serverA tincd to talk vpn client'
You must allow vpn traffic between two IP address set using vpn0 tunnel:
$ sudo ufw allow from 172.16.1.2 to 172.16.1.1 comment 'Allow serverB to talk serverA fully'

tinc configuration on serverB

Type the following command as root user on serverA only.

Step 1: Create directories on serverB

Type the following mkdir command:
$ sudo mkdir -p /etc/tinc/vpn0/hosts/

Step 2: Create the config file on serverB

Type the following vi command:
$ sudo vi /etc/tinc/vpn0/tinc.conf
Append the following:
Name = serverB
Device = /dev/net/tun
ConnectTo = serverA
BindToAddress = 192.168.4.6
AddressFamily = ipv4

Step 3: Create the public and private key for serverB

$ sudo tincd -n vpn0 -K4096
Sample outputs:

Generating 4096 bits keys:
...........................................................................
.........................................................................++ q
Done.
Please enter a file to save private RSA key to [/etc/tinc/vpn0/rsa_key.priv]: 
Please enter a file to save public RSA key to [/etc/tinc/vpn0/hosts/serverB]:

Step 4: Setup IP addresses to the host files that tinc created on serverB

$ sudo vi /etc/tinc/vpn0/hosts/serverB
Add the following at the top of the file:

Subnet = 172.16.1.2/32

-----BEGIN RSA PUBLIC KEY-----
.....
...
your random key here
....
-----END RSA PUBLIC KEY-----

Step 5: Create network interface control scripts on serverB

Create a tinc-up script:
$ sudo vi /etc/tinc/vpn0/tinc-up
Append the following:

#!/bin/sh
#
# Must use IP 172.16.1.2, which is setup in /etc/tinc/vpn0/hosts/serverB
#
/sbin/ifconfig $INTERFACE 172.16.1.2 netmask 255.255.255.0

Create a tinc-down script:
$ sudo vi /etc/tinc/vpn0/tinc-down
Append the following content:

#!/bin/sh
/sbin/ifconfig $INTERFACE down

Finally setup executable permission using the chmod command:
$ sudo chmod -v +x /etc/tinc/vpn0/tinc-{up,down}

Step 6: Update firewall rules on serverB

Type the following ufw command to open port tcp 655:
$ sudo ufw allow from 192.168.4.5 to 192.168.4.6 port 655 proto tcp comment 'Allow serverB tincd to talk to serverA'
Type the following ufw command to open port udp 655:
$ sudo ufw allow from 192.168.4.5 to 192.168.4.6 port 655 proto udp comment 'Allow serverB tincd to talk to serverA'
You must allow vpn traffic between two IP address set using vpn0 tunnel:
$ sudo ufw allow from 172.16.1.1 to 172.16.1.2 comment 'Allow serverA to talk serverB fully'

Combined step 7: You must copy host files to the other hosts

You must copy /etc/tinc/vpn0/hosts/serverA to serverB. Use the scp command (type command on serverA):
$ scp /etc/tinc/vpn0/hosts/serverA [email protected]:/tmp/
$ ssh -t [email protected] sudo mv -v /tmp/serverA /etc/tinc/vpn0/hosts/

You must copy /etc/tinc/vpn0/hosts/serverB to serverA. Use the scp command (type command on serverB):
$ scp /etc/tinc/vpn0/hosts/serverB [email protected]:~/
$ ssh -t [email protected] sudo mv -v /tmp/serverB /etc/tinc/vpn0/hosts/

Combined step 8: Enable and start tinc service (type it on both serverA and serverB)

Type the following commands to append vpn0 service to /etc/tinc/nets.boot file using sudo command:
$ echo 'vpn0' | sudo tee -a /etc/tinc/nets.boot
Enable it:
$ sudo systemctl enable tinc
Restart it:
$ sudo systemctl restart tinc
Verify it:
$ ps aux | grep tincd
Sample outputs:

root 2334 0.0 0.0 15724 2940 ? Ss 16:40 0:04 /usr/sbin/tincd -n vpn0

Make sure port is opened:
$ netstat -tulpn | grep tincd
Sample outputs from serverA:


tcp   0  0 192.168.4.5:655   0.0.0.0:*   LISTEN  22334/tincd     
udp   0  0 192.168.4.5:655   0.0.0.0:*           22334/tincd  

Use ping command to send ICMP ECHO_REQUEST to network hosts to verify that vpn working:
$ ping 172.16.1.1
$ ping 172.16.1.2

You can now modify sshd and mysqld daemon/service to listen on 172.16.1.1 or 172.16.1.2 to accept traffic from VPN host only. For example, edit the /etc/sshd/sshd_config on serverA to listen on LAN, VPN and public IP address:
# listen to LAN, VPN, and Public IP
ListenAddress 192.168.4.5
ListenAddress 172.16.1.1
ListenAddress 202.54.3.5

And reload the sshd service:
$ sudo systemctl reload ssh
For more info see tinc-vpn project site.

This entry is 2 of 4 in the Open Source Virtual Private Network (VPN) series. Keep reading the rest of the series:
  1. How To Setup OpenVPN Server In 5 Minutes on Ubuntu Server
  2. How to install tinc VPN on Ubuntu Linux 16.04 to secure traffic
  3. Run two or multiple networks instance of Tinc VPN
  4. How to import a OpenVPN .ovpn file with Network Manager

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on Twitter, Facebook, Google+.

Share this on (or read 5 comments/add one below):

5 comment

  1. Does tinc require any kernel modules? I’d like to install it on a Raspberry Pi-like device (Next Thing Co’s Chip), but it is missing some kernel modules that are needed to run OpenVPN, so I’m looking for an alternative solutions. Chip IPTables, so that’s not a problem.

  2. Hi, very good info on tinc and its setup.

    But out of curiousity, why not use WireGuard?!
    It’s in kernel and is really fast. Doesn’t need connection setup and daemons and is really secure.
    And with using `wg-quick`, the setup is even simpler!!

Leave a Comment