User Tools

Site Tools



Tinc is a self-routing, mesh networking protocol, used for compressed, encrypted, virtual private networks. This howto is intended as a guide to document some of the Tinc on OpenWrt specifics the author stumbled on and struggled with in hopes it saves others time and effort.

UCI Configuration

Tinc normally makes use of a series of files and directories under /etc/tinc/ for it's configuration. On OpenWrt much of configuration has been moved into the UCI system into the file located at /etc/config/tinc. The OpenWrt Tinc init script will use the contents of the tinc uci config along with files in the /etc/tinc directories to generate a full Tinc configuration located under /tmp/tinc

The Tinc uci config file contains two types of sections: tinc-net and tinc-host.

The tinc-net sections start with "config tinc-net NETNAME" followed by options that match the options described in tinc.conf.5 / tinc with the exceptions of an "enabled" option and a few for command line options. The NETNAME will be mapped to /etc/tinc/NETNAME and the values in that section will be used to generate the equivalent of the /etc/tinc/NETNAME/tinc.conf file. While use of UCI this way can configure Tinc, you'll find it much less painful in the long run to make minimal use of the UCI methods to configure Tinc.

The tinc-host sections start with "config tinc-host NODENAME" followed by options that will be used to generate the Tinc host files normally located at /etc/tinc/NETNAME/hosts/NODENAME . UCI doesn't seem to have a place to hold the public keys that go in a host config file so you will still be expected to have files with public keys at /etc/tinc/NETNAME/hosts/NODENAME but the other values from the UCI section will be combined when a host file is generated under /tmp/tinc/NETNAME/hosts/NODENAME . Again, prefer Tinc's node configuration method when you can.

UCI also does not store the helper scripts such as tinc-up or NODENAME-up that are normally found in /etc/tinc/NETNAME/ and /etc/tinc/NETNAME/hosts/ so you will have to create them and store them there. Make sure they are executable.

UCI Network/Firewall Integration

The following helped this author have a more reliable coexistence between Tinc and the OpenWrt web interface managed Network/Firewall settings. The info below is based on my experience setting up Tinc to let me route between private lans.

Because the network management of UCI may tear down and build up the network or firewall settings I found it advantageous to use the Networking/Firewall UCI settings as applied to the Tinc created interfaces as much as possible to prevent unexpected Tinc VPN failures. That said, it still isn't 100% reliable for me yet when making significant network changes. Reboot and verify changes come back online as expected.

I've evolved my tinc scripts into the four mostly generic scripts below. You can get away with less but for routing between networks, these work with minimal thought.

/etc/tinc/[NETNAME]/tinc-up contains:

#!/bin/sh ip=`uci get network.lan.ipaddr` ifconfig $INTERFACE $ip

unlike some some Tinc howtos for other distributions I did not have any iptables rules in the tinc-up script. The `uci get network.lan.ipaddr` will extract the IP address of your LAN interface. If you've renamed this interface or want something else, change here.

/etc/tinc/[NETNAME]/tinc-down contains:

#!/bin/sh ifconfig $INTERFACE down

/etc/tinc/[NETNAME]/subnet-up contains:

#!/bin/sh [ $NODE = `uci get tinc.$NETNAME.Name` ] && exit case $SUBNET in */32) targetType=-host ;; *) targetType=-net ;; esac route add $targetType $SUBNET dev $INTERFACE

The `uci get tinc.$NETNAME.Name` extracts this host's name from the tinc config. You need to know this so the subnet-up script doesn't run to add a subnet for itself because that already exists. Versions of tinc newer than 1.0.19 have a better way around this but I don't recall at the moment.

NOTE: I (user mbello, not the author of this guide) followed this entire guide and it worked brilliantly except for this `uci get tinc.$NETNAME.Name` command, I had to replace it with "netname".

/etc/tinc/[NETNAME]/subnet-down contains:

#!/bin/sh [ $NODE = `uci get tinc.$NETNAME.Name` ] && exit case $SUBNET in */32) targetType=-host ;; *) targetType=-net ;; esac route del $targetType $SUBNET dev $INTERFACE

Instead I went into the OpenWrt LuCI web interface and under Network > Interfaces I Added a new interface… which I named NETNAME that was of Protocol unmanaged and covered the NETNAME interface. This makes UCI aware of the Tinc network interface but it shouldn't try to manage it.

Then, under Network > Interfaces > NETNAME > Firewall Settings I created or assigned the zone of vpn .

Next, under Network > Firewall > General Settings > Zones you can edit the vpn zone to enable Inter-Zone Forwarding to/from your lan zone.

Finally, under Network > Firewall > Traffic Rules you'l need to open the port Tinc is using, 655 by default. The summary table for me reads: "Tinc-[NETNAME] | Any TCP, UDP From any host in wan To any router IP at port 655 on this device | Accept input"

NOTE: I (user mnlipp, neither the author of this guide) had problems (using Chaos Calmer) with the coexistence of the unmanaged interface NETNAME (really nice to have in LuCI) and tinc managing that same interface. An unmanaged interface isn't completely unmanaged – it is created. There seems to be a conflict (or race condition) between netifd trying to create the interface and tincd attempting to do the same. Although the interface had been configured properly by tinc-up (I logged he results), I always found my $INTERFACE to have no address at the end of the boot.

I think that tincd is faster than netifd and the latter overwrites the settings of the former by re-creating the interface. I could solve the problem by adding

ubus -t 15 wait_for network.interface.$INTERFACE

at the beginning of my tinc-up script.

doc/howto/vpn.tinc.txt · Last modified: 2016/02/23 19:35 by mnlipp