Simple VPN network mesh with tinc

From Wikipedia:

Tinc is an open-source, self-routing, mesh networking protocol, used for compressed, encrypted, virtual private networks.

Network graph:

tinc mesh

 

Hosts:

storage-01:

public ip:   123.123.123.100
vpn ip:      10.0.0.1
connects to: media01, router01

media-01:

public ip:   123.123.123.200
vpn ip:      10.0.0.2
connects to: storage01, router01

router-01:

public ip:   123.123.123.300
vpn ip:      10.0.0.3
connects to: storage01, media01

Note: Using dashes (-) in tinc hostname files does not work.

VPN name:

myvpn

tinc setup:

Identical directory tree on all servers after setup:

/etc/tinc/
└── myvpn
     ├── hosts
     │   ├── media01
     │   ├── router01
     │   └── storage01
     ├── rsa_key.priv
     ├── tinc.conf
     ├── tinc-down
     └── tinc-up

storage-01 (centos 7):

# Install tinc
yum install tinc -y

# Create directories
mkdir -p /etc/tinc/myvpn/hosts/

/etc/tinc/myvpn/hosts/storage01:
    Address = 123.123.123.100
    Subnet = 10.0.0.1/32
    
/etc/tinc/myvpn/tinc.conf:
    Name = storage01
    Interface = tun8
    AddressFamily = ipv4
    ConnectTo = router01
    ConnectTo = media01

/etc/tinc/myvpn/tinc-up:
    #!/bin/sh
    ip link set $INTERFACE up
    ip addr add 10.0.0.1/32 dev $INTERFACE
    ip route add 10.0.0.0/24 dev $INTERFACE

/etc/tinc/myvpn/tinc-down:
    #!/bin/sh
    ip route del 10.0.0.0/24 dev $INTERFACE
    ip addr del 10.0.0.1/32 dev $INTERFACE
    ip link set $INTERFACE down

media-01 (centos 7):

# Install tinc
yum install tinc -y

# Create directories
mkdir -p /etc/tinc/myvpn/hosts/

/etc/tinc/myvpn/hosts/media01:
    Address = 123.123.123.200
    Subnet = 10.0.0.2/32

/etc/tinc/myvpn/tinc.conf:
    Name = media01
    Interface = tun8
    AddressFamily = ipv4
    ConnectTo = storage01
    ConnectTo = router01

/etc/tinc/myvpn/tinc-up:
    #!/bin/sh
    ip link set $INTERFACE up
    ip addr add 10.0.0.2/32 dev $INTERFACE
    ip route add 10.0.0.0/24 dev $INTERFACE

/etc/tinc/myvpn/tinc-down:
    #!/bin/sh
    ip route del 10.0.0.0/24 dev $INTERFACE
    ip addr del 10.0.0.2/32 dev $INTERFACE
    ip link set $INTERFACE down

router-01 (centos 7):

# Install tinc
yum install tinc -y

# Create directories
mkdir -p /etc/tinc/myvpn/hosts/
    
/etc/tinc/myvpn/hosts/router01:
    Address = 123.123.123.300
    Subnet = 10.0.0.3/32
    
/etc/tinc/myvpn/tinc.conf:
    Name = router01
    Interface = tun8
    AddressFamily = ipv4
    ConnectTo = storage01
    ConnectTo = media01

/etc/tinc/myvpn/tinc-up:
    #!/bin/sh
    ip link set $INTERFACE up
    ip addr add 10.0.0.3/32 dev $INTERFACE
    ip route add 10.0.0.0/24 dev $INTERFACE

/etc/tinc/myvpn/tinc-down:
    ip route del 10.0.0.0/24 dev $INTERFACE
    ip addr del 10.0.0.3/32 dev $INTERFACE
    ip link set $INTERFACE down

On all servers:

# Create private/public keypair
tincd -n myvpn -K4096

/etc/firewalld/services/tinc.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <service>
        <short>tinc</short>
        <description>tinc VPN daemon</description>
        <port protocol="udp" port="655"/>
        <port protocol="tcp" port="655"/>
    </service>

firewall-cmd --add-service=tinc --permanent
firewall-cmd --reload

All servers should have a copy of all host files with the public keys, so copy them.

[root@media-01 ~]# rsync /etc/tinc/myvpn/hosts/ router-01:/etc/tinc/myvpn/hosts/ -av
[root@media-01 ~]# rsync /etc/tinc/myvpn/hosts/ storage-01:/etc/tinc/myvpn/hosts/ -av
[root@router-01 ~]# rsync /etc/tinc/myvpn/hosts/ media-01:/etc/tinc/myvpn/hosts/ -av 
[root@router-01 ~]# rsync /etc/tinc/myvpn/hosts/ storage-01:/etc/tinc/myvpn/hosts/ -av
[root@storage-01 ~]# rsync /etc/tinc/myvpn/hosts/ media-01:/etc/tinc/myvpn/hosts/ -av
[root@storage-01 ~]# rsync /etc/tinc/myvpn/hosts/ router-01:/etc/tinc/myvpn/hosts/ -av

On all servers:

# Set executable bit on tinc-up and tinc-down
chmod +x /etc/tinc/myvpn/tinc-up
chmod +x /etc/tinc/myvpn/tinc-down
# Enable and start tinc:
systemctl enable tinc@myvpn
systemctl start tinc@myvpn

Now all three servers should be able to communicate on 10.0.0.0/24.
If communication between any two drops, it’ll route through the third one.

Note on Debian 8:

Debian 8 dosen’t have a systemd unit for tinc yet, so to get tinc up and running /etc/tinc/nets.boot should contain names of all networks to be started. You can then start it normally with init/systemd.

For example:

/etc/tinc/
 ├── myvpn
 │   ├── hosts
 │   │   ├── media01
 │   │   ├── router01
 │   │   ├── storage01
 │   ├── rsa_key.priv
 │   ├── tinc.conf
 │   ├── tinc-down
 │   └── tinc-up
 └── nets.boot
/etc/tinc/nets.boot:
    myvpn
# Enable and start tinc
systemctl enable tinc
systemctl start tinc

# Check the status
systemctl status tinc
Simple VPN network mesh with tinc