06 Aug 2021 - tsp
Last update 06 Aug 2021
TL;DR: See table.
|Virtual device type
|2 - Ethernet
|Arbitrary Ethernet segments
|3 - IP
|Different IP segments, list in local hosts file as
This is something that I’m asked often - what’s the difference between the
router mode when using the tinc VPN client.
The same goes about the question if these modes are interchangeable or compatible
with each other (short answer: no).
The shortest answer would be that the difference is the same as between a router and a switch - at least when it comes to the idea of the two modes. In contrast to one being able to connect a router to a switch and vice versa - this is not possible when building the VPN mesh though.
In switch mode the VPN is built at layer 2 of the OSI model - at the Ethernet
layer. One can pass arbitrary Ethernet packets and all nodes learn the MAC addresses
used by the other nodes just like an ordinary network switch. In case they don’t
know the route for a packet they just broadcast to all nodes - also like a typical
switch - and slowly learn the MAC table that way. Switch mode is best when one really
wants to bridge two Ethernet segments - they may even share the same IP address
ranges - or wants to connect routers that learn their own IP address ranges
for multiple attached networks in a dynamic fashion (for example using
bgp). This is the mode that I personally usually use when interconnecting
different complex sites that run themselves multiple network segments and get
extended dynamically. Switch mode is realized via
Router mode on the other hand is something like a layer 3 IP router embedded in
the VPN client. All nodes announce the IP addresses that they’re responsible for
and other nodes learn that way who is responsible for which net. The only drawback is
that tinc nodes source the networks they announce from their hosts files
declarations. This means it’s not easily possible to extend these routing tables
dynamically via a protocol such as OLSR or BGP like it’s for the routing
functionality when using full blown router implementations or hardware routers.
At least one doesn’t have to change the host files on all nodes anyways but then
there is the problem that one still has to configure routes on the host level for
the virtual network interface anyways. Router mode is realized via
switch mode is usually more flexible when building VPNs this is
what I’m personally using most of the time (running a standard router configuration
on the host machine and usually either
bgpd to announce routes)- unfortunately
there are some clients like the Android implementation that use Androids VPN
interface that only support
tun interfaces so sometimes one has to
I’ve already described this in another blog post
including configuration of
olsrd to learn new routes. This is the mode of operation
that I personally prefer, especially when bridging whole network segments and
not only backhauling single computers into some network.
The basic ideas are similar to using switch mode - I’ll only outline the differences
here. The main difference are some minor changes in
tinc.conf - basically just
router mode and supply a
tun interface instead of a
Name = anyexamplenodenamea
Mode = router
DecrementTTL = no
Device = /dev/tun1
DeviceType = tun
Forwarding = internal
# Followed by some ConnectTo = statements if possible
tinc-down scripts have to be modified too to create
tap devices. Since one configures the routes statically one can
also add the static network configuration inside the
# First create the interface
ifconfig tun1 create
ifconfig tun1 inet 126.96.36.199/24
# Then add static routes
route add -net 188.8.131.52/24 184.108.40.206
route add -net 220.127.116.11/24 18.104.22.168
route add -net 22.214.171.124/24 126.96.36.199
route add -net 188.8.131.52/24 184.108.40.206
# Remove static routes
route del -net 220.127.116.11/24 18.104.22.168
route del -net 22.214.171.124/24 126.96.36.199
route del -net 188.8.131.52/24 184.108.40.206
route del -net 220.127.116.11/24 18.104.22.168
# Then destroy interface
ifconfig tun1 destroy
After that the procedure is the same for host key creation:
tincd -n NETNAME -K
The next modification is that one has to add a
Subnet declaration for
each subnet that is reachable via this node to the hostfile (for example
Address = 22.214.171.124
Subnet = 126.96.36.199/32
Subnet = 188.8.131.52/24
Subnet = 184.108.40.206/24
Compression = 9
Port = 656
-----BEGIN RSA PUBLIC KEY-----
-----END RSA PUBLIC KEY-----
In this case
Address still is the publicly reachable external address that
the host is reachable by. If a host uses a dynamic IP one cannot supply an
Subnet declarations specify which subnets the node should announce - they
are only read by the node itself, not by the nodes that the hosts file is distributed
The same has to be done for all other nodes. This basically is the main difference in configuration to layer 2 mode.
A word of caution: Many mobile network operators run carrier grade NAT for their devices and assign private IP ranges from the RFC1918 space to the devices, there might be collisions with own VPN meshes in case one uses these ranges too. So in case nothing appears to work check the IP address of your device on the mobile network side.
Unfortunately Android currently only supports
tun devices in VPN mode.
A nice app that wraps tinc and provides some simple way of configuration
is tincapp. This application is available
either as source, via F-Droid
or Google Play.
It provides no configuration GUI though - one has to enable the internal FTP server
while being in a local network and upload configuration files that way after one
has created a VPN network inside the app and generated the host keys. Unfortunately
it currently does not support automatic launching on boot though.
Basically the configuration works the same way as for other machines - one uploads
tinc.conf, the set of host keys (including the modified host
key for the device one creates) and an additional
tinc.conf works the same as on any other system:
Name = anyexamplenodenameb
Mode = router
ConnectTo = anyexamplenodenamea
network.conf is something specific for this platform though. It substitutes
local interface configuration and route configuration since this has to be
done through Androids VPN API. Basically it contains:
Route statements that lists all networks that should be
reached via the VPN
The Address is simply specified using
Address = 220.127.116.11/32
Route statements really only list all subnets that are supported by
any of the remote nodes. This is also a shortfall of this solution since there
seems to be no way to dynamically update this route information using OLSR or BGP.
Route = 18.104.22.168/24
Route = 22.214.171.124/24
Route = 126.96.36.199/24
Route = 188.8.131.52/24
Route = 184.108.40.206/24
In case one wants to route all traffic via the VPN one can set the usual default route with prefix length 0.
Route = 0.0.0.0/0
Whenever one wants to use an own internal DNS or DNS suffix the settings can also be set:
DNSServer = 220.127.116.11
DNSServer = 18.104.22.168
SearchDomain = example.com
At the end bypass and reconnection settings finalize the configuration:
AllowBypass = true
ReconnectOnNetworkChange = true
After one has created the host keys via the UI one can download the generated
host file using FTP - in this example the mobile device is reachable via
FTP access has been enabled in tincapp settings:
$ ftp email@example.com 65521
Connected to 22.214.171.124.
220 Service ready for new user.
331 User name okay, need password for tincapp.
230 User logged in, proceed.
Remote system type is UNIX.
ftp> cd files/networks/NETNAME
250 Directory changed to /files/networks/NETNAME
In case one has to change the local directory (tincd.conf and host files are not
in the current working directory) one simply uses the
ftp> lcd tinchosts
Local directory now: /usr/home/exampleuser/tinchosts
After that one can download the host file for the mobile node:
ftp> get hosts/anyexamplenodenameb
local: hosts/anyexamplenodenameb remote: hosts/anyexamplenodenameb
229 Entering Passive Mode (|||65530|)
150 File status okay; about to open data connection.
100% |***********************************| 554 333.13 KiB/s --:-- ETA
226 Transfer complete.
554 bytes received in 00:00 (12.46 KiB/s)
Via the same mechanism one uploads
network.conf and any
ftp> put hosts/anyexamplenodenamea
ftp> put tincd.conf
ftp> put network.conf
Then one should add the required subnet declaration (if any) to the hosts file. This might look like the following line:
Subnet = 126.96.36.199/32
At the end one just has to distribute the hosts file to all other hosts as usual. Now the mobile device should be able to join the VPN as usual.
This article is tagged:
Dipl.-Ing. Thomas Spielauer, Wien (firstname.lastname@example.org)
This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/