06 Aug 2021 - tsp
Last update 06 Aug 2021
10 mins
TL;DR: See table.
Mode | OSI layer | Virtual device type | Connects |
---|---|---|---|
Switch | 2 - Ethernet | tap |
Arbitrary Ethernet segments |
Router | 3 - IP | tun |
Different IP segments, list in local hosts file as Subnet |
This is something that I’m asked often - what’s the difference between the switch
and 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 olsr
or 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 tap
interfaces.
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 Subnet
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 tun
interfaces.
Since 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 olsrd
or 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
use router
mode.
switch
modeI’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.
router
modeThe 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
specify the router
mode and supply a tun
interface instead of a tap
one:
Name = anyexamplenodenamea
Mode = router
DecrementTTL = no
Device = /dev/tun1
DeviceType = tun
Forwarding = internal
# Followed by some ConnectTo = statements if possible
The tinc-up
and tinc-down
scripts have to be modified too to create tun
instead of tap
devices. Since one configures the routes statically one can
also add the static network configuration inside the tinc-up
and tinc-down
scripts:
#!/bin/sh
# tinc-up
# First create the interface
ifconfig tun1 create
ifconfig tun1 inet 128.66.1.1/24
# Then add static routes
route add -net 128.66.12.0/24 128.66.1.2
route add -net 128.66.13.0/24 128.66.1.2
route add -net 128.66.14.0/24 128.66.1.3
route add -net 128.66.15.0/24 128.66.1.3
#!/bin/sh
# tinc-down
# Remove static routes
route del -net 128.66.12.0/24 128.66.1.2
route del -net 128.66.13.0/24 128.66.1.2
route del -net 128.66.14.0/24 128.66.1.3
route del -net 128.66.15.0/24 128.66.1.3
# 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 hosts/anyexamplenodenamea
):
Address = 128.66.0.1
Subnet = 128.66.1.1/32
Subnet = 128.66.10.0/24
Subnet = 128.66.11.0/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 Address
.
The 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
to.
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
the required tinc.conf
, the set of host keys (including the modified host
key for the device one creates) and an additional network.conf
.
The tinc.conf
works the same as on any other system:
Name = anyexamplenodenameb
Mode = router
ConnectTo = anyexamplenodenamea
The 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 VPNThe Address is simply specified using Address
:
Address = 128.66.1.2/32
The 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 = 128.66.10.0/24
Route = 128.66.11.0/24
Route = 128.66.12.0/24
Route = 128.66.13.0/24
Route = 128.66.14.0/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 = 128.66.1.100
DNSServer = 128.66.1.101
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 128.66.0.1
on port 65521
after FTP access
has been enabled in tincapp settings:
$ ftp tincapp@128.66.0.1 65521
Connected to 128.66.0.1.
220 Service ready for new user.
331 User name okay, need password for tincapp.
Password:
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 lcd
command:
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 tinc.conf
, network.conf
and any
other hostfiles:
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 = 128.66.1.2/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 (webcomplains389t48957@tspi.at)
This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/