3001 lines
112 KiB
Text
3001 lines
112 KiB
Text
\input texinfo @c -*-texinfo-*-
|
|
@c %**start of header
|
|
@setfilename tinc.info
|
|
@settitle tinc Manual
|
|
@setchapternewpage odd
|
|
@c %**end of header
|
|
|
|
@include tincinclude.texi
|
|
|
|
@ifinfo
|
|
@dircategory Networking tools
|
|
@direntry
|
|
* tinc: (tinc). The tinc Manual.
|
|
@end direntry
|
|
|
|
This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon.
|
|
|
|
Copyright @copyright{} 1998-2013 Ivo Timmermans,
|
|
Guus Sliepen <guus@@tinc-vpn.org> and
|
|
Wessel Dankers <wsl@@tinc-vpn.org>.
|
|
|
|
Permission is granted to make and distribute verbatim copies of this
|
|
manual provided the copyright notice and this permission notice are
|
|
preserved on all copies.
|
|
|
|
Permission is granted to copy and distribute modified versions of this
|
|
manual under the conditions for verbatim copying, provided that the
|
|
entire resulting derived work is distributed under the terms of a
|
|
permission notice identical to this one.
|
|
|
|
@end ifinfo
|
|
|
|
@titlepage
|
|
@title tinc Manual
|
|
@subtitle Setting up a Virtual Private Network with tinc
|
|
@author Ivo Timmermans and Guus Sliepen
|
|
|
|
@page
|
|
@vskip 0pt plus 1filll
|
|
This is the info manual for @value{PACKAGE} version @value{VERSION}, a Virtual Private Network daemon.
|
|
|
|
Copyright @copyright{} 1998-2013 Ivo Timmermans,
|
|
Guus Sliepen <guus@@tinc-vpn.org> and
|
|
Wessel Dankers <wsl@@tinc-vpn.org>.
|
|
|
|
Permission is granted to make and distribute verbatim copies of this
|
|
manual provided the copyright notice and this permission notice are
|
|
preserved on all copies.
|
|
|
|
Permission is granted to copy and distribute modified versions of this
|
|
manual under the conditions for verbatim copying, provided that the
|
|
entire resulting derived work is distributed under the terms of a
|
|
permission notice identical to this one.
|
|
|
|
@end titlepage
|
|
|
|
@ifnottex
|
|
@c ==================================================================
|
|
@node Top
|
|
@top Top
|
|
|
|
@menu
|
|
* Introduction::
|
|
* Preparations::
|
|
* Installation::
|
|
* Configuration::
|
|
* Running tinc::
|
|
* Controlling tinc::
|
|
* Technical information::
|
|
* Platform specific information::
|
|
* About us::
|
|
* Concept Index:: All used terms explained
|
|
@end menu
|
|
@end ifnottex
|
|
|
|
@c ==================================================================
|
|
@node Introduction
|
|
@chapter Introduction
|
|
|
|
@cindex tinc
|
|
Tinc is a Virtual Private Network (VPN) daemon that uses tunneling and
|
|
encryption to create a secure private network between hosts on the
|
|
Internet.
|
|
|
|
Because the tunnel appears to the IP level network code as a normal
|
|
network device, there is no need to adapt any existing software.
|
|
The encrypted tunnels allows VPN sites to share information with each other
|
|
over the Internet without exposing any information to others.
|
|
|
|
This document is the manual for tinc. Included are chapters on how to
|
|
configure your computer to use tinc, as well as the configuration
|
|
process of tinc itself.
|
|
|
|
@menu
|
|
* Virtual Private Networks::
|
|
* tinc:: About tinc
|
|
* Supported platforms::
|
|
@end menu
|
|
|
|
@c ==================================================================
|
|
@node Virtual Private Networks
|
|
@section Virtual Private Networks
|
|
|
|
@cindex VPN
|
|
A Virtual Private Network or VPN is a network that can only be accessed
|
|
by a few elected computers that participate. This goal is achievable in
|
|
more than just one way.
|
|
|
|
@cindex private
|
|
Private networks can consist of a single stand-alone Ethernet LAN. Or
|
|
even two computers hooked up using a null-modem cable. In these cases,
|
|
it is
|
|
obvious that the network is @emph{private}, no one can access it from the
|
|
outside. But if your computers are linked to the Internet, the network
|
|
is not private anymore, unless one uses firewalls to block all private
|
|
traffic. But then, there is no way to send private data to trusted
|
|
computers on the other end of the Internet.
|
|
|
|
@cindex virtual
|
|
This problem can be solved by using @emph{virtual} networks. Virtual
|
|
networks can live on top of other networks, but they use encapsulation to
|
|
keep using their private address space so they do not interfere with
|
|
the Internet. Mostly, virtual networks appear like a single LAN, even though
|
|
they can span the entire world. But virtual networks can't be secured
|
|
by using firewalls, because the traffic that flows through it has to go
|
|
through the Internet, where other people can look at it.
|
|
|
|
As is the case with either type of VPN, anybody could eavesdrop. Or
|
|
worse, alter data. Hence it's probably advisable to encrypt the data
|
|
that flows over the network.
|
|
|
|
When one introduces encryption, we can form a true VPN. Other people may
|
|
see encrypted traffic, but if they don't know how to decipher it (they
|
|
need to know the key for that), they cannot read the information that flows
|
|
through the VPN. This is what tinc was made for.
|
|
|
|
|
|
@c ==================================================================
|
|
@node tinc
|
|
@section tinc
|
|
|
|
@cindex vpnd
|
|
I really don't quite remember what got us started, but it must have been
|
|
Guus' idea. He wrote a simple implementation (about 50 lines of C) that
|
|
used the ethertap device that Linux knows of since somewhere
|
|
about kernel 2.1.60. It didn't work immediately and he improved it a
|
|
bit. At this stage, the project was still simply called "vpnd".
|
|
|
|
Since then, a lot has changed---to say the least.
|
|
|
|
@cindex tincd
|
|
Tinc now supports encryption, it consists of a single daemon (tincd) for
|
|
both the receiving and sending end, it has become largely
|
|
runtime-configurable---in short, it has become a full-fledged
|
|
professional package.
|
|
|
|
@cindex traditional VPNs
|
|
@cindex scalability
|
|
Tinc also allows more than two sites to connect to eachother and form a single VPN.
|
|
Traditionally VPNs are created by making tunnels, which only have two endpoints.
|
|
Larger VPNs with more sites are created by adding more tunnels.
|
|
Tinc takes another approach: only endpoints are specified,
|
|
the software itself will take care of creating the tunnels.
|
|
This allows for easier configuration and improved scalability.
|
|
|
|
A lot can---and will be---changed. We have a number of things that we would like to
|
|
see in the future releases of tinc. Not everything will be available in
|
|
the near future. Our first objective is to make tinc work perfectly as
|
|
it stands, and then add more advanced features.
|
|
|
|
Meanwhile, we're always open-minded towards new ideas. And we're
|
|
available too.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Supported platforms
|
|
@section Supported platforms
|
|
|
|
@cindex platforms
|
|
Tinc has been verified to work under Linux, FreeBSD, OpenBSD, NetBSD, MacOS/X (Darwin), Solaris, and Windows (both natively and in a Cygwin environment),
|
|
with various hardware architectures. These are some of the platforms
|
|
that are supported by the universal tun/tap device driver or other virtual network device drivers.
|
|
Without such a driver, tinc will most
|
|
likely compile and run, but it will not be able to send or receive data
|
|
packets.
|
|
|
|
@cindex release
|
|
For an up to date list of supported platforms, please check the list on
|
|
our website:
|
|
@uref{http://www.tinc-vpn.org/platforms/}.
|
|
|
|
@c
|
|
@c
|
|
@c
|
|
@c
|
|
@c
|
|
@c
|
|
@c Preparing your system
|
|
@c
|
|
@c
|
|
@c
|
|
@c
|
|
@c
|
|
|
|
@c ==================================================================
|
|
@node Preparations
|
|
@chapter Preparations
|
|
|
|
This chapter contains information on how to prepare your system to
|
|
support tinc.
|
|
|
|
@menu
|
|
* Configuring the kernel::
|
|
* Libraries::
|
|
@end menu
|
|
|
|
|
|
@c ==================================================================
|
|
@node Configuring the kernel
|
|
@section Configuring the kernel
|
|
|
|
@menu
|
|
* Configuration of Linux kernels::
|
|
* Configuration of FreeBSD kernels::
|
|
* Configuration of OpenBSD kernels::
|
|
* Configuration of NetBSD kernels::
|
|
* Configuration of Solaris kernels::
|
|
* Configuration of Darwin (MacOS/X) kernels::
|
|
* Configuration of Windows::
|
|
@end menu
|
|
|
|
|
|
@c ==================================================================
|
|
@node Configuration of Linux kernels
|
|
@subsection Configuration of Linux kernels
|
|
|
|
@cindex Universal tun/tap
|
|
For tinc to work, you need a kernel that supports the Universal tun/tap device.
|
|
Most distributions come with kernels that already support this.
|
|
Here are the options you have to turn on when configuring a new kernel:
|
|
|
|
@example
|
|
Code maturity level options
|
|
[*] Prompt for development and/or incomplete code/drivers
|
|
Network device support
|
|
<M> Universal tun/tap device driver support
|
|
@end example
|
|
|
|
It's not necessary to compile this driver as a module, even if you are going to
|
|
run more than one instance of tinc.
|
|
|
|
If you decide to build the tun/tap driver as a kernel module, add these lines
|
|
to @file{/etc/modules.conf}:
|
|
|
|
@example
|
|
alias char-major-10-200 tun
|
|
@end example
|
|
|
|
|
|
@c ==================================================================
|
|
@node Configuration of FreeBSD kernels
|
|
@subsection Configuration of FreeBSD kernels
|
|
|
|
For FreeBSD version 4.1 and higher, tun and tap drivers are included in the default kernel configuration.
|
|
The tap driver can be loaded with @code{kldload if_tap}, or by adding @code{if_tap_load="YES"} to @file{/boot/loader.conf}.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Configuration of OpenBSD kernels
|
|
@subsection Configuration of OpenBSD kernels
|
|
|
|
For OpenBSD version 2.9 and higher,
|
|
the tun driver is included in the default kernel configuration.
|
|
There is also a kernel patch from @uref{http://diehard.n-r-g.com/stuff/openbsd/}
|
|
which adds a tap device to OpenBSD which should work with tinc,
|
|
but with recent versions of OpenBSD,
|
|
a tun device can act as a tap device by setting the link0 option with ifconfig.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Configuration of NetBSD kernels
|
|
@subsection Configuration of NetBSD kernels
|
|
|
|
For NetBSD version 1.5.2 and higher,
|
|
the tun driver is included in the default kernel configuration.
|
|
|
|
Tunneling IPv6 may not work on NetBSD's tun device.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Configuration of Solaris kernels
|
|
@subsection Configuration of Solaris kernels
|
|
|
|
For Solaris 8 (SunOS 5.8) and higher,
|
|
the tun driver may or may not be included in the default kernel configuration.
|
|
If it isn't, the source can be downloaded from @uref{http://vtun.sourceforge.net/tun/}.
|
|
For x86 and sparc64 architectures, precompiled versions can be found at @uref{http://www.monkey.org/~dugsong/fragroute/}.
|
|
If the @file{net/if_tun.h} header file is missing, install it from the source package.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Configuration of Darwin (MacOS/X) kernels
|
|
@subsection Configuration of Darwin (MacOS/X) kernels
|
|
|
|
Tinc on Darwin relies on a tunnel driver for its data acquisition from the kernel.
|
|
Tinc supports either the driver from @uref{http://tuntaposx.sourceforge.net/},
|
|
which supports both tun and tap style devices,
|
|
and also the driver from from @uref{http://chrisp.de/en/projects/tunnel.html}.
|
|
The former driver is recommended.
|
|
The tunnel driver must be loaded before starting tinc with the following command:
|
|
|
|
@example
|
|
kmodload tunnel
|
|
@end example
|
|
|
|
|
|
@c ==================================================================
|
|
@node Configuration of Windows
|
|
@subsection Configuration of Windows
|
|
|
|
You will need to install the latest TAP-Win32 driver from OpenVPN.
|
|
You can download it from @uref{http://openvpn.sourceforge.net}.
|
|
Using the Network Connections control panel,
|
|
configure the TAP-Win32 network interface in the same way as you would do from the tinc-up script,
|
|
as explained in the rest of the documentation.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Libraries
|
|
@section Libraries
|
|
|
|
@cindex requirements
|
|
@cindex libraries
|
|
Before you can configure or build tinc, you need to have the OpenSSL,
|
|
zlib and lzo libraries installed on your system. If you try to configure tinc without
|
|
having them installed, configure will give you an error message, and stop.
|
|
|
|
@menu
|
|
* OpenSSL::
|
|
* zlib::
|
|
* lzo::
|
|
* libcurses::
|
|
* libreadline::
|
|
@end menu
|
|
|
|
|
|
@c ==================================================================
|
|
@node OpenSSL
|
|
@subsection OpenSSL
|
|
|
|
@cindex OpenSSL
|
|
For all cryptography-related functions, tinc uses the functions provided
|
|
by the OpenSSL library.
|
|
|
|
If this library is not installed, you wil get an error when configuring
|
|
tinc for build. Support for running tinc with other cryptographic libraries
|
|
installed @emph{may} be added in the future.
|
|
|
|
You can use your operating system's package manager to install this if
|
|
available. Make sure you install the development AND runtime versions
|
|
of this package.
|
|
|
|
If you have to install OpenSSL manually, you can get the source code
|
|
from @url{http://www.openssl.org/}. Instructions on how to configure,
|
|
build and install this package are included within the package. Please
|
|
make sure you build development and runtime libraries (which is the
|
|
default).
|
|
|
|
If you installed the OpenSSL libraries from source, it may be necessary
|
|
to let configure know where they are, by passing configure one of the
|
|
--with-openssl-* parameters.
|
|
|
|
@example
|
|
--with-openssl=DIR OpenSSL library and headers prefix
|
|
--with-openssl-include=DIR OpenSSL headers directory
|
|
(Default is OPENSSL_DIR/include)
|
|
--with-openssl-lib=DIR OpenSSL library directory
|
|
(Default is OPENSSL_DIR/lib)
|
|
@end example
|
|
|
|
|
|
@subsubheading License
|
|
|
|
@cindex license
|
|
The complete source code of tinc is covered by the GNU GPL version 2.
|
|
Since the license under which OpenSSL is distributed is not directly
|
|
compatible with the terms of the GNU GPL
|
|
@uref{http://www.openssl.org/support/faq.html#LEGAL2}, we
|
|
include an exemption to the GPL (see also the file COPYING.README) to allow
|
|
everyone to create a statically or dynamically linked executable:
|
|
|
|
@quotation
|
|
This program is released under the GPL with the additional exemption
|
|
that compiling, linking, and/or using OpenSSL is allowed. You may
|
|
provide binary packages linked to the OpenSSL libraries, provided that
|
|
all other requirements of the GPL are met.
|
|
@end quotation
|
|
|
|
Since the LZO library used by tinc is also covered by the GPL,
|
|
we also present the following exemption:
|
|
|
|
@quotation
|
|
Hereby I grant a special exception to the tinc VPN project
|
|
(http://www.tinc-vpn.org/) to link the LZO library with the OpenSSL library
|
|
(http://www.openssl.org).
|
|
|
|
Markus F.X.J. Oberhumer
|
|
@end quotation
|
|
|
|
|
|
@c ==================================================================
|
|
@node zlib
|
|
@subsection zlib
|
|
|
|
@cindex zlib
|
|
For the optional compression of UDP packets, tinc uses the functions provided
|
|
by the zlib library.
|
|
|
|
If this library is not installed, you wil get an error when running the
|
|
configure script. You can either install the zlib library, or disable support
|
|
for zlib compression by using the "--disable-zlib" option when running the
|
|
configure script. Note that if you disable support for zlib, the resulting
|
|
binary will not work correctly on VPNs where zlib compression is used.
|
|
|
|
You can use your operating system's package manager to install this if
|
|
available. Make sure you install the development AND runtime versions
|
|
of this package.
|
|
|
|
If you have to install zlib manually, you can get the source code
|
|
from @url{http://www.gzip.org/zlib/}. Instructions on how to configure,
|
|
build and install this package are included within the package. Please
|
|
make sure you build development and runtime libraries (which is the
|
|
default).
|
|
|
|
|
|
@c ==================================================================
|
|
@node lzo
|
|
@subsection lzo
|
|
|
|
@cindex lzo
|
|
Another form of compression is offered using the LZO library.
|
|
|
|
If this library is not installed, you wil get an error when running the
|
|
configure script. You can either install the LZO library, or disable support
|
|
for LZO compression by using the "--disable-lzo" option when running the
|
|
configure script. Note that if you disable support for LZO, the resulting
|
|
binary will not work correctly on VPNs where LZO compression is used.
|
|
|
|
You can use your operating system's package manager to install this if
|
|
available. Make sure you install the development AND runtime versions
|
|
of this package.
|
|
|
|
If you have to install lzo manually, you can get the source code
|
|
from @url{http://www.oberhumer.com/opensource/lzo/}. Instructions on how to configure,
|
|
build and install this package are included within the package. Please
|
|
make sure you build development and runtime libraries (which is the
|
|
default).
|
|
|
|
|
|
@c ==================================================================
|
|
@node libcurses
|
|
@subsection libcurses
|
|
|
|
@cindex libcurses
|
|
For the "tincctl top" command, tinc requires a curses library.
|
|
|
|
If this library is not installed, you wil get an error when running the
|
|
configure script. You can either install a suitable curses library, or disable
|
|
all functionality that depends on a curses library by using the
|
|
"--disable-curses" option when running the configure script.
|
|
|
|
There are several curses libraries. It is recommended that you install
|
|
"ncurses" (@url{http://invisible-island.net/ncurses/}),
|
|
however other curses libraries should also work.
|
|
In particular, "PDCurses" (@url{http://pdcurses.sourceforge.net/})
|
|
is recommended if you want to compile tinc for Windows.
|
|
|
|
You can use your operating system's package manager to install this if
|
|
available. Make sure you install the development AND runtime versions
|
|
of this package.
|
|
|
|
|
|
@c ==================================================================
|
|
@node libreadline
|
|
@subsection libreadline
|
|
|
|
@cindex libreadline
|
|
For the "tincctl" command's shell functionality, tinc uses the readline library.
|
|
|
|
If this library is not installed, you wil get an error when running the
|
|
configure script. You can either install a suitable readline library, or
|
|
disable all functionality that depends on a readline library by using the
|
|
"--disable-readline" option when running the configure script.
|
|
|
|
You can use your operating system's package manager to install this if
|
|
available. Make sure you install the development AND runtime versions
|
|
of this package.
|
|
|
|
If you have to install libreadline manually, you can get the source code from
|
|
@url{http://www.gnu.org/software/readline/}. Instructions on how to configure,
|
|
build and install this package are included within the package. Please make
|
|
sure you build development and runtime libraries (which is the default).
|
|
|
|
|
|
@c
|
|
@c
|
|
@c
|
|
@c Installing tinc
|
|
@c
|
|
@c
|
|
@c
|
|
@c
|
|
|
|
@c ==================================================================
|
|
@node Installation
|
|
@chapter Installation
|
|
|
|
If you use Debian, you may want to install one of the
|
|
precompiled packages for your system. These packages are equipped with
|
|
system startup scripts and sample configurations.
|
|
|
|
If you cannot use one of the precompiled packages, or you want to compile tinc
|
|
for yourself, you can use the source. The source is distributed under
|
|
the GNU General Public License (GPL). Download the source from the
|
|
@uref{http://www.tinc-vpn.org/download/, download page}, which has
|
|
the checksums of these files listed; you may wish to check these with
|
|
md5sum before continuing.
|
|
|
|
Tinc comes in a convenient autoconf/automake package, which you can just
|
|
treat the same as any other package. Which is just untar it, type
|
|
`./configure' and then `make'.
|
|
More detailed instructions are in the file @file{INSTALL}, which is
|
|
included in the source distribution.
|
|
|
|
@menu
|
|
* Building and installing tinc::
|
|
* System files::
|
|
@end menu
|
|
|
|
|
|
@c ==================================================================
|
|
@node Building and installing tinc
|
|
@section Building and installing tinc
|
|
|
|
Detailed instructions on configuring the source, building tinc and installing tinc
|
|
can be found in the file called @file{INSTALL}.
|
|
|
|
@cindex binary package
|
|
If you happen to have a binary package for tinc for your distribution,
|
|
you can use the package management tools of that distribution to install tinc.
|
|
The documentation that comes along with your distribution will tell you how to do that.
|
|
|
|
@menu
|
|
* Darwin (MacOS/X) build environment::
|
|
* Cygwin (Windows) build environment::
|
|
* MinGW (Windows) build environment::
|
|
@end menu
|
|
|
|
|
|
@c ==================================================================
|
|
@node Darwin (MacOS/X) build environment
|
|
@subsection Darwin (MacOS/X) build environment
|
|
|
|
In order to build tinc on Darwin, you need to install the MacOS/X Developer Tools
|
|
from @uref{http://developer.apple.com/tools/macosxtools.html} and
|
|
a recent version of Fink from @uref{http://www.finkproject.org/}.
|
|
|
|
After installation use fink to download and install the following packages:
|
|
autoconf25, automake, dlcompat, m4, openssl, zlib and lzo.
|
|
|
|
@c ==================================================================
|
|
@node Cygwin (Windows) build environment
|
|
@subsection Cygwin (Windows) build environment
|
|
|
|
If Cygwin hasn't already been installed, install it directly from
|
|
@uref{http://www.cygwin.com/}.
|
|
|
|
When tinc is compiled in a Cygwin environment, it can only be run in this environment,
|
|
but all programs, including those started outside the Cygwin environment, will be able to use the VPN.
|
|
It will also support all features.
|
|
|
|
@c ==================================================================
|
|
@node MinGW (Windows) build environment
|
|
@subsection MinGW (Windows) build environment
|
|
|
|
You will need to install the MinGW environment from @uref{http://www.mingw.org}.
|
|
|
|
When tinc is compiled using MinGW it runs natively under Windows,
|
|
it is not necessary to keep MinGW installed.
|
|
|
|
When detaching, tinc will install itself as a service,
|
|
which will be restarted automatically after reboots.
|
|
|
|
|
|
@c ==================================================================
|
|
@node System files
|
|
@section System files
|
|
|
|
Before you can run tinc, you must make sure you have all the needed
|
|
files on your system.
|
|
|
|
@menu
|
|
* Device files::
|
|
* Other files::
|
|
@end menu
|
|
|
|
|
|
@c ==================================================================
|
|
@node Device files
|
|
@subsection Device files
|
|
|
|
@cindex device files
|
|
Most operating systems nowadays come with the necessary device files by default,
|
|
or they have a mechanism to create them on demand.
|
|
|
|
If you use Linux and do not have udev installed,
|
|
you may need to create the following device file if it does not exist:
|
|
|
|
@example
|
|
mknod -m 600 /dev/net/tun c 10 200
|
|
@end example
|
|
|
|
|
|
@c ==================================================================
|
|
@node Other files
|
|
@subsection Other files
|
|
|
|
@subsubheading @file{/etc/networks}
|
|
|
|
You may add a line to @file{/etc/networks} so that your VPN will get a
|
|
symbolic name. For example:
|
|
|
|
@example
|
|
myvpn 10.0.0.0
|
|
@end example
|
|
|
|
@subsubheading @file{/etc/services}
|
|
|
|
@cindex port numbers
|
|
You may add this line to @file{/etc/services}. The effect is that you
|
|
may supply a @samp{tinc} as a valid port number to some programs. The
|
|
number 655 is registered with the IANA.
|
|
|
|
@example
|
|
tinc 655/tcp TINC
|
|
tinc 655/udp TINC
|
|
# Ivo Timmermans <ivo@@tinc-vpn.org>
|
|
@end example
|
|
|
|
|
|
@c
|
|
@c
|
|
@c
|
|
@c
|
|
@c Configuring tinc
|
|
@c
|
|
@c
|
|
@c
|
|
@c
|
|
|
|
|
|
@c ==================================================================
|
|
@node Configuration
|
|
@chapter Configuration
|
|
|
|
@menu
|
|
* Configuration introduction::
|
|
* Multiple networks::
|
|
* How connections work::
|
|
* Configuration files::
|
|
* Network interfaces::
|
|
* Example configuration::
|
|
@end menu
|
|
|
|
@c ==================================================================
|
|
@node Configuration introduction
|
|
@section Configuration introduction
|
|
|
|
Before actually starting to configure tinc and editing files,
|
|
make sure you have read this entire section so you know what to expect.
|
|
Then, make it clear to yourself how you want to organize your VPN:
|
|
What are the nodes (computers running tinc)?
|
|
What IP addresses/subnets do they have?
|
|
What is the network mask of the entire VPN?
|
|
Do you need special firewall rules?
|
|
Do you have to set up masquerading or forwarding rules?
|
|
Do you want to run tinc in router mode or switch mode?
|
|
These questions can only be answered by yourself,
|
|
you will not find the answers in this documentation.
|
|
Make sure you have an adequate understanding of networks in general.
|
|
@cindex Network Administrators Guide
|
|
A good resource on networking is the
|
|
@uref{http://www.tldp.org/LDP/nag2/, Linux Network Administrators Guide}.
|
|
|
|
If you have everything clearly pictured in your mind,
|
|
proceed in the following order:
|
|
First, create the initial configuration files and public/private keypairs using the following command:
|
|
@example
|
|
tincctl -n @var{NETNAME} init @var{NAME}
|
|
@end example
|
|
Second, use @samp{tincctl -n @var{NETNAME} config ...} to further configure tinc.
|
|
Finally, export your host configuration file using @samp{tincctl -n @var{NETNAME} export} and send it to those
|
|
people or computers you want tinc to connect to.
|
|
They should send you their host configuration file back, which you can import using @samp{tincctl -n @var{NETNAME} import}.
|
|
|
|
These steps are described in the subsections below.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Multiple networks
|
|
@section Multiple networks
|
|
|
|
@cindex multiple networks
|
|
@cindex netname
|
|
|
|
In order to allow you to run more than one tinc daemon on one computer,
|
|
for instance if your computer is part of more than one VPN,
|
|
you can assign a @var{netname} to your VPN.
|
|
It is not required if you only run one tinc daemon,
|
|
it doesn't even have to be the same on all the nodes of your VPN,
|
|
but it is recommended that you choose one anyway.
|
|
|
|
We will asume you use a netname throughout this document.
|
|
This means that you call tincctl with the -n argument,
|
|
which will specify the netname.
|
|
|
|
The effect of this option is that tinc will set its configuration
|
|
root to @file{@value{sysconfdir}/tinc/@var{netname}/}, where @var{netname} is your argument to the -n option.
|
|
You will also notice that log messages it appears in syslog as coming from @file{tinc.@var{netname}},
|
|
and on Linux, unless specified otherwise, the name of the virtual network interface will be the same as the network name.
|
|
|
|
However, it is not strictly necessary that you call tinc with the -n
|
|
option. If you don not use it, the network name will just be empty, and
|
|
tinc will look for files in @file{@value{sysconfdir}/tinc/} instead of
|
|
@file{@value{sysconfdir}/tinc/@var{netname}/};
|
|
the configuration file will then be @file{@value{sysconfdir}/tinc/tinc.conf},
|
|
and the host configuration files are expected to be in @file{@value{sysconfdir}/tinc/hosts/}.
|
|
|
|
|
|
@c ==================================================================
|
|
@node How connections work
|
|
@section How connections work
|
|
|
|
When tinc starts up, it parses the command-line options and then
|
|
reads in the configuration file tinc.conf.
|
|
If it sees one or more `ConnectTo' values pointing to other tinc daemons in that file,
|
|
it will try to connect to those other daemons.
|
|
Whether this succeeds or not and whether `ConnectTo' is specified or not,
|
|
tinc will listen for incoming connection from other deamons.
|
|
If you did specify a `ConnectTo' value and the other side is not responding,
|
|
tinc will keep retrying.
|
|
This means that once started, tinc will stay running until you tell it to stop,
|
|
and failures to connect to other tinc daemons will not stop your tinc daemon
|
|
for trying again later.
|
|
This means you don't have to intervene if there are temporary network problems.
|
|
|
|
@cindex client
|
|
@cindex server
|
|
There is no real distinction between a server and a client in tinc.
|
|
If you wish, you can view a tinc daemon without a `ConnectTo' value as a server,
|
|
and one which does specify such a value as a client.
|
|
It does not matter if two tinc daemons have a `ConnectTo' value pointing to each other however.
|
|
|
|
Connections specified using `ConnectTo' are so-called meta-connections.
|
|
Tinc daemons exchange information about all other daemon they know about via these meta-connections.
|
|
After learning about all the daemons in the VPN,
|
|
tinc will create other connections as necessary in order to communicate with them.
|
|
For example, if there are three daemons named A, B and C, and A has @samp{ConnectTo = B} in its tinc.conf file,
|
|
and C has @samp{ConnectTo = B} in its tinc.conf file, then A will learn about C from B,
|
|
and will be able to exchange VPN packets with C without the need to have @samp{ConnectTo = C} in its tinc.conf file.
|
|
|
|
It could be that some daemons are located behind a Network Address Translation (NAT) device, or behind a firewall.
|
|
In the above scenario with three daemons, if A and C are behind a NAT,
|
|
B will automatically help A and C punch holes through their NAT,
|
|
in a way similar to the STUN protocol, so that A and C can still communicate with each other directly.
|
|
It is not always possible to do this however, and firewalls might also prevent direct communication.
|
|
In that case, VPN packets between A and C will be forwarded by B.
|
|
|
|
In effect, all nodes in the VPN will be able to talk to each other, as long as
|
|
their is a path of meta-connections between them, and whenever possible, two
|
|
nodes will communicate with each other directly.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Configuration files
|
|
@section Configuration files
|
|
|
|
The actual configuration of the daemon is done in the file
|
|
@file{@value{sysconfdir}/tinc/@var{netname}/tinc.conf} and at least one other file in the directory
|
|
@file{@value{sysconfdir}/tinc/@var{netname}/hosts/}.
|
|
|
|
These file consists of comments (lines started with a #) or assignments
|
|
in the form of
|
|
|
|
@example
|
|
Variable = Value.
|
|
@end example
|
|
|
|
The variable names are case insensitive, and any spaces, tabs, newlines
|
|
and carriage returns are ignored. Note: it is not required that you put
|
|
in the `=' sign, but doing so improves readability. If you leave it
|
|
out, remember to replace it with at least one space character.
|
|
|
|
The server configuration is complemented with host specific configuration (see
|
|
the next section). Although all host configuration options for the local node
|
|
listed in this document can also be put in
|
|
@file{@value{sysconfdir}/tinc/@var{netname}/tinc.conf}, it is recommended to
|
|
put host specific configuration options in the host configuration file, as this
|
|
makes it easy to exchange with other nodes.
|
|
|
|
You can edit the config file manually, but it is recommended that you use
|
|
tincctl to change configuration variables for you.
|
|
|
|
In the following two subsections all valid variables are listed in alphabetical order.
|
|
The default value is given between parentheses,
|
|
other comments are between square brackets.
|
|
|
|
@menu
|
|
* Main configuration variables::
|
|
* Host configuration variables::
|
|
* Scripts::
|
|
* How to configure::
|
|
@end menu
|
|
|
|
|
|
@c ==================================================================
|
|
@node Main configuration variables
|
|
@subsection Main configuration variables
|
|
|
|
@table @asis
|
|
@cindex AddressFamily
|
|
@item AddressFamily = <ipv4|ipv6|any> (any)
|
|
This option affects the address family of listening and outgoing sockets.
|
|
If any is selected, then depending on the operating system
|
|
both IPv4 and IPv6 or just IPv6 listening sockets will be created.
|
|
|
|
@cindex AutoConnect
|
|
@item AutoConnect = <count> (0) [experimental]
|
|
If set to a non-zero value,
|
|
tinc will try to only have count meta connections to other nodes,
|
|
by automatically making or breaking connections to known nodes.
|
|
Higher values increase redundancy but also increase meta data overhead.
|
|
When using this option, a good value is 3.
|
|
|
|
@cindex BindToAddress
|
|
@item BindToAddress = <@var{address}> [<@var{port}>]
|
|
If your computer has more than one IPv4 or IPv6 address, tinc
|
|
will by default listen on all of them for incoming connections.
|
|
Multiple BindToAddress variables may be specified,
|
|
in which case listening sockets for each specified address are made.
|
|
|
|
If no @var{port} is specified, the socket will be bound to the port specified by the Port option,
|
|
or to port 655 if neither is given.
|
|
To only bind to a specific port but not to a specific address, use "*" for the @var{address}.
|
|
|
|
@cindex BindToInterface
|
|
@item BindToInterface = <@var{interface}> [experimental]
|
|
If you have more than one network interface in your computer, tinc will
|
|
by default listen on all of them for incoming connections. It is
|
|
possible to bind tinc to a single interface like eth0 or ppp0 with this
|
|
variable.
|
|
|
|
This option may not work on all platforms.
|
|
Also, on some platforms it will not actually bind to an interface,
|
|
but rather to the address that the interface has at the moment a socket is created.
|
|
|
|
@cindex Broadcast
|
|
@item Broadcast = <no | mst | direct> (mst) [experimental]
|
|
This option selects the way broadcast packets are sent to other daemons.
|
|
@emph{NOTE: all nodes in a VPN must use the same Broadcast mode, otherwise routing loops can form.}
|
|
|
|
@table @asis
|
|
@item no
|
|
Broadcast packets are never sent to other nodes.
|
|
|
|
@item mst
|
|
Broadcast packets are sent and forwarded via the VPN's Minimum Spanning Tree.
|
|
This ensures broadcast packets reach all nodes.
|
|
|
|
@item direct
|
|
Broadcast packets are sent directly to all nodes that can be reached directly.
|
|
Broadcast packets received from other nodes are never forwarded.
|
|
If the IndirectData option is also set, broadcast packets will only be sent to nodes which we have a meta connection to.
|
|
@end table
|
|
|
|
@cindex ConnectTo
|
|
@item ConnectTo = <@var{name}>
|
|
Specifies which other tinc daemon to connect to on startup.
|
|
Multiple ConnectTo variables may be specified,
|
|
in which case outgoing connections to each specified tinc daemon are made.
|
|
The names should be known to this tinc daemon
|
|
(i.e., there should be a host configuration file for the name on the ConnectTo line).
|
|
|
|
If you don't specify a host with ConnectTo,
|
|
tinc won't try to connect to other daemons at all,
|
|
and will instead just listen for incoming connections.
|
|
|
|
@cindex DecrementTTL
|
|
@item DecrementTTL = <yes | no> (no) [experimental]
|
|
When enabled, tinc will decrement the Time To Live field in IPv4 packets, or the Hop Limit field in IPv6 packets,
|
|
before forwarding a received packet to the virtual network device or to another node,
|
|
and will drop packets that have a TTL value of zero,
|
|
in which case it will send an ICMP Time Exceeded packet back.
|
|
|
|
Do not use this option if you use switch mode and want to use IPv6.
|
|
|
|
@cindex Device
|
|
@item Device = <@var{device}> (@file{/dev/tap0}, @file{/dev/net/tun} or other depending on platform)
|
|
The virtual network device to use.
|
|
Tinc will automatically detect what kind of device it is.
|
|
Note that you can only use one device per daemon.
|
|
Under Windows, use @var{Interface} instead of @var{Device}.
|
|
Note that you can only use one device per daemon.
|
|
See also @ref{Device files}.
|
|
|
|
@cindex DeviceType
|
|
@item DeviceType = <@var{type}> (platform dependent)
|
|
The type of the virtual network device.
|
|
Tinc will normally automatically select the right type of tun/tap interface, and this option should not be used.
|
|
However, this option can be used to select one of the special interface types, if support for them is compiled in.
|
|
|
|
@table @asis
|
|
@cindex dummy
|
|
@item dummy
|
|
Use a dummy interface.
|
|
No packets are ever read or written to a virtual network device.
|
|
Useful for testing, or when setting up a node that only forwards packets for other nodes.
|
|
|
|
@cindex raw_socket
|
|
@item raw_socket
|
|
Open a raw socket, and bind it to a pre-existing
|
|
@var{Interface} (eth0 by default).
|
|
All packets are read from this interface.
|
|
Packets received for the local node are written to the raw socket.
|
|
However, at least on Linux, the operating system does not process IP packets destined for the local host.
|
|
|
|
@cindex multicast
|
|
@item multicast
|
|
Open a multicast UDP socket and bind it to the address and port (separated by spaces) and optionally a TTL value specified using @var{Device}.
|
|
Packets are read from and written to this multicast socket.
|
|
This can be used to connect to UML, QEMU or KVM instances listening on the same multicast address.
|
|
Do NOT connect multiple tinc daemons to the same multicast address, this will very likely cause routing loops.
|
|
Also note that this can cause decrypted VPN packets to be sent out on a real network if misconfigured.
|
|
|
|
@cindex UML
|
|
@item uml (not compiled in by default)
|
|
Create a UNIX socket with the filename specified by
|
|
@var{Device}, or @file{@value{localstatedir}/run/@var{netname}.umlsocket}
|
|
if not specified.
|
|
Tinc will wait for a User Mode Linux instance to connect to this socket.
|
|
|
|
@cindex VDE
|
|
@item vde (not compiled in by default)
|
|
Uses the libvdeplug library to connect to a Virtual Distributed Ethernet switch,
|
|
using the UNIX socket specified by
|
|
@var{Device}, or @file{@value{localstatedir}/run/vde.ctl}
|
|
if not specified.
|
|
@end table
|
|
|
|
Also, in case tinc does not seem to correctly interpret packets received from the virtual network device,
|
|
it can be used to change the way packets are interpreted:
|
|
|
|
@table @asis
|
|
@item tun (BSD and Linux)
|
|
Set type to tun.
|
|
Depending on the platform, this can either be with or without an address family header (see below).
|
|
|
|
@cindex tunnohead
|
|
@item tunnohead (BSD)
|
|
Set type to tun without an address family header.
|
|
Tinc will expect packets read from the virtual network device to start with an IP header.
|
|
On some platforms IPv6 packets cannot be read from or written to the device in this mode.
|
|
|
|
@cindex tunifhead
|
|
@item tunifhead (BSD)
|
|
Set type to tun with an address family header.
|
|
Tinc will expect packets read from the virtual network device
|
|
to start with a four byte header containing the address family,
|
|
followed by an IP header.
|
|
This mode should support both IPv4 and IPv6 packets.
|
|
|
|
@item tap (BSD and Linux)
|
|
Set type to tap.
|
|
Tinc will expect packets read from the virtual network device
|
|
to start with an Ethernet header.
|
|
@end table
|
|
|
|
@cindex DirectOnly
|
|
@item DirectOnly = <yes|no> (no) [experimental]
|
|
When this option is enabled, packets that cannot be sent directly to the destination node,
|
|
but which would have to be forwarded by an intermediate node, are dropped instead.
|
|
When combined with the IndirectData option,
|
|
packets for nodes for which we do not have a meta connection with are also dropped.
|
|
|
|
@cindex ECDSAPrivateKeyFile
|
|
@item ECDSAPrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/ecdsa_key.priv})
|
|
The file in which the private ECDSA key of this tinc daemon resides.
|
|
This is only used if ExperimentalProtocol is enabled.
|
|
|
|
@cindex ExperimentalProtocol
|
|
@item ExperimentalProtocol = <yes|no> (no) [experimental]
|
|
When this option is enabled, experimental protocol enhancements will be used.
|
|
Ephemeral ECDH will be used for key exchanges,
|
|
and ECDSA will be used instead of RSA for authentication.
|
|
When enabled, an ECDSA key must have been generated before with
|
|
@samp{tincctl generate-ecdsa-keys}.
|
|
The experimental protocol may change at any time,
|
|
and there is no guarantee that tinc will run stable when it is used.
|
|
|
|
@cindex Forwarding
|
|
@item Forwarding = <off|internal|kernel> (internal) [experimental]
|
|
This option selects the way indirect packets are forwarded.
|
|
|
|
@table @asis
|
|
@item off
|
|
Incoming packets that are not meant for the local node,
|
|
but which should be forwarded to another node, are dropped.
|
|
|
|
@item internal
|
|
Incoming packets that are meant for another node are forwarded by tinc internally.
|
|
|
|
This is the default mode, and unless you really know you need another forwarding mode, don't change it.
|
|
|
|
@item kernel
|
|
Incoming packets are always sent to the TUN/TAP device, even if the packets are not for the local node.
|
|
This is less efficient, but allows the kernel to apply its routing and firewall rules on them,
|
|
and can also help debugging.
|
|
@end table
|
|
|
|
@cindex Hostnames
|
|
@item Hostnames = <yes|no> (no)
|
|
This option selects whether IP addresses (both real and on the VPN)
|
|
should be resolved. Since DNS lookups are blocking, it might affect
|
|
tinc's efficiency, even stopping the daemon for a few seconds everytime
|
|
it does a lookup if your DNS server is not responding.
|
|
|
|
This does not affect resolving hostnames to IP addresses from the
|
|
configuration file, but whether hostnames should be resolved while logging.
|
|
|
|
@cindex Interface
|
|
@item Interface = <@var{interface}>
|
|
Defines the name of the interface corresponding to the virtual network device.
|
|
Depending on the operating system and the type of device this may or may not actually set the name of the interface.
|
|
Under Windows, this variable is used to select which network interface will be used.
|
|
If you specified a Device, this variable is almost always already correctly set.
|
|
|
|
@cindex LocalDiscovery
|
|
@item LocalDiscovery = <yes | no> (no)
|
|
When enabled, tinc will try to detect peers that are on the same local network.
|
|
This will allow direct communication using LAN addresses, even if both peers are behind a NAT
|
|
and they only ConnectTo a third node outside the NAT,
|
|
which normally would prevent the peers from learning each other's LAN address.
|
|
|
|
Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery.
|
|
This feature may not work in all possible situations.
|
|
|
|
@cindex Mode
|
|
@item Mode = <router|switch|hub> (router)
|
|
This option selects the way packets are routed to other daemons.
|
|
|
|
@table @asis
|
|
@cindex router
|
|
@item router
|
|
In this mode Subnet
|
|
variables in the host configuration files will be used to form a routing table.
|
|
Only packets of routable protocols (IPv4 and IPv6) are supported in this mode.
|
|
|
|
This is the default mode, and unless you really know you need another mode, don't change it.
|
|
|
|
@cindex switch
|
|
@item switch
|
|
In this mode the MAC addresses of the packets on the VPN will be used to
|
|
dynamically create a routing table just like an Ethernet switch does.
|
|
Unicast, multicast and broadcast packets of every protocol that runs over Ethernet are supported in this mode
|
|
at the cost of frequent broadcast ARP requests and routing table updates.
|
|
|
|
This mode is primarily useful if you want to bridge Ethernet segments.
|
|
|
|
@cindex hub
|
|
@item hub
|
|
This mode is almost the same as the switch mode, but instead
|
|
every packet will be broadcast to the other daemons
|
|
while no routing table is managed.
|
|
@end table
|
|
|
|
@cindex KeyExpire
|
|
@item KeyExpire = <@var{seconds}> (3600)
|
|
This option controls the time the encryption keys used to encrypt the data
|
|
are valid. It is common practice to change keys at regular intervals to
|
|
make it even harder for crackers, even though it is thought to be nearly
|
|
impossible to crack a single key.
|
|
|
|
@cindex MACExpire
|
|
@item MACExpire = <@var{seconds}> (600)
|
|
This option controls the amount of time MAC addresses are kept before they are removed.
|
|
This only has effect when Mode is set to "switch".
|
|
|
|
@cindex Name
|
|
@item Name = <@var{name}> [required]
|
|
This is a symbolic name for this connection.
|
|
The name should consist only of alfanumeric and underscore characters (a-z, A-Z, 0-9 and _), and is case sensitive.
|
|
|
|
If Name starts with a $, then the contents of the environment variable that follows will be used.
|
|
In that case, invalid characters will be converted to underscores.
|
|
If Name is $HOST, but no such environment variable exist,
|
|
the hostname will be read using the gethostname() system call.
|
|
|
|
@cindex PingInterval
|
|
@item PingInterval = <@var{seconds}> (60)
|
|
The number of seconds of inactivity that tinc will wait before sending a
|
|
probe to the other end.
|
|
|
|
@cindex PingTimeout
|
|
@item PingTimeout = <@var{seconds}> (5)
|
|
The number of seconds to wait for a response to pings or to allow meta
|
|
connections to block. If the other end doesn't respond within this time,
|
|
the connection is terminated, and the others will be notified of this.
|
|
|
|
@cindex PriorityInheritance
|
|
@item PriorityInheritance = <yes|no> (no) [experimental]
|
|
When this option is enabled the value of the TOS field of tunneled IPv4 packets
|
|
will be inherited by the UDP packets that are sent out.
|
|
|
|
@cindex PrivateKey
|
|
@item PrivateKey = <@var{key}> [obsolete]
|
|
This is the RSA private key for tinc. However, for safety reasons it is
|
|
advised to store private keys of any kind in separate files. This prevents
|
|
accidental eavesdropping if you are editting the configuration file.
|
|
|
|
@cindex PrivateKeyFile
|
|
@item PrivateKeyFile = <@var{path}> (@file{@value{sysconfdir}/tinc/@var{netname}/rsa_key.priv})
|
|
This is the full path name of the RSA private key file that was
|
|
generated by @samp{tincctl generate-keys}. It must be a full path, not a
|
|
relative directory.
|
|
|
|
@cindex ProcessPriority
|
|
@item ProcessPriority = <low|normal|high>
|
|
When this option is used the priority of the tincd process will be adjusted.
|
|
Increasing the priority may help to reduce latency and packet loss on the VPN.
|
|
|
|
@cindex Proxy
|
|
@item Proxy = socks4 | socks4 | http | exec @var{...} [experimental]
|
|
Use a proxy when making outgoing connections.
|
|
The following proxy types are currently supported:
|
|
|
|
@table @asis
|
|
@cindex socks4
|
|
@item socks4 <@var{address}> <@var{port}> [<@var{username}>]
|
|
Connects to the proxy using the SOCKS version 4 protocol.
|
|
Optionally, a @var{username} can be supplied which will be passed on to the proxy server.
|
|
|
|
@cindex socks5
|
|
@item socks4 <@var{address}> <@var{port}> [<@var{username}> <@var{password}>]
|
|
Connect to the proxy using the SOCKS version 5 protocol.
|
|
If a @var{username} and @var{password} are given, basic username/password authentication will be used,
|
|
otherwise no authentication will be used.
|
|
|
|
@cindex http
|
|
@item http <@var{address}> <@var{port}>
|
|
Connects to the proxy and sends a HTTP CONNECT request.
|
|
|
|
@cindex exec
|
|
@item exec <@var{command}>
|
|
Executes the given command which should set up the outgoing connection.
|
|
The environment variables @env{NAME}, @env{NODE}, @env{REMOTEADDRES} and @env{REMOTEPORT} are available.
|
|
@end table
|
|
|
|
@cindex ReplayWindow
|
|
@item ReplayWindow = <bytes> (16)
|
|
This is the size of the replay tracking window for each remote node, in bytes.
|
|
The window is a bitfield which tracks 1 packet per bit, so for example
|
|
the default setting of 16 will track up to 128 packets in the window. In high
|
|
bandwidth scenarios, setting this to a higher value can reduce packet loss from
|
|
the interaction of replay tracking with underlying real packet loss and/or
|
|
reordering. Setting this to zero will disable replay tracking completely and
|
|
pass all traffic, but leaves tinc vulnerable to replay-based attacks on your
|
|
traffic.
|
|
|
|
|
|
@cindex StrictSubnets
|
|
@item StrictSubnets <yes|no> (no) [experimental]
|
|
When this option is enabled tinc will only use Subnet statements which are
|
|
present in the host config files in the local
|
|
@file{@value{sysconfdir}/tinc/@var{netname}/hosts/} directory.
|
|
|
|
@cindex TunnelServer
|
|
@item TunnelServer = <yes|no> (no) [experimental]
|
|
When this option is enabled tinc will no longer forward information between other tinc daemons,
|
|
and will only allow connections with nodes for which host config files are present in the local
|
|
@file{@value{sysconfdir}/tinc/@var{netname}/hosts/} directory.
|
|
Setting this options also implicitly sets StrictSubnets.
|
|
|
|
@cindex UDPRcvBuf
|
|
@item UDPRcvBuf = <bytes> (OS default)
|
|
Sets the socket receive buffer size for the UDP socket, in bytes.
|
|
If unset, the default buffer size will be used by the operating system.
|
|
|
|
@cindex UDPSndBuf
|
|
@item UDPSndBuf = <bytes> Pq OS default
|
|
Sets the socket send buffer size for the UDP socket, in bytes.
|
|
If unset, the default buffer size will be used by the operating system.
|
|
|
|
@end table
|
|
|
|
|
|
@c ==================================================================
|
|
@node Host configuration variables
|
|
@subsection Host configuration variables
|
|
|
|
@table @asis
|
|
@cindex Address
|
|
@item Address = <@var{IP address}|@var{hostname}> [<port>] [recommended]
|
|
This variable is only required if you want to connect to this host. It
|
|
must resolve to the external IP address where the host can be reached,
|
|
not the one that is internal to the VPN.
|
|
If no port is specified, the default Port is used.
|
|
|
|
@cindex Cipher
|
|
@item Cipher = <@var{cipher}> (blowfish)
|
|
The symmetric cipher algorithm used to encrypt UDP packets.
|
|
Any cipher supported by OpenSSL is recognized.
|
|
Furthermore, specifying "none" will turn off packet encryption.
|
|
It is best to use only those ciphers which support CBC mode.
|
|
|
|
@cindex ClampMSS
|
|
@item ClampMSS = <yes|no> (yes)
|
|
This option specifies whether tinc should clamp the maximum segment size (MSS)
|
|
of TCP packets to the path MTU. This helps in situations where ICMP
|
|
Fragmentation Needed or Packet too Big messages are dropped by firewalls.
|
|
|
|
@cindex Compression
|
|
@item Compression = <@var{level}> (0)
|
|
This option sets the level of compression used for UDP packets.
|
|
Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib),
|
|
10 (fast lzo) and 11 (best lzo).
|
|
|
|
@cindex Digest
|
|
@item Digest = <@var{digest}> (sha1)
|
|
The digest algorithm used to authenticate UDP packets.
|
|
Any digest supported by OpenSSL is recognized.
|
|
Furthermore, specifying "none" will turn off packet authentication.
|
|
|
|
@cindex IndirectData
|
|
@item IndirectData = <yes|no> (no)
|
|
When set to yes, other nodes which do not already have a meta connection to you
|
|
will not try to establish direct communication with you.
|
|
It is best to leave this option out or set it to no.
|
|
|
|
@cindex MACLength
|
|
@item MACLength = <@var{bytes}> (4)
|
|
The length of the message authentication code used to authenticate UDP packets.
|
|
Can be anything from 0
|
|
up to the length of the digest produced by the digest algorithm.
|
|
|
|
@cindex PMTU
|
|
@item PMTU = <@var{mtu}> (1514)
|
|
This option controls the initial path MTU to this node.
|
|
|
|
@cindex PMTUDiscovery
|
|
@item PMTUDiscovery = <yes|no> (yes)
|
|
When this option is enabled, tinc will try to discover the path MTU to this node.
|
|
After the path MTU has been discovered, it will be enforced on the VPN.
|
|
|
|
@cindex Port
|
|
@item Port = <@var{port}> (655)
|
|
This is the port this tinc daemon listens on.
|
|
You can use decimal portnumbers or symbolic names (as listed in @file{/etc/services}).
|
|
|
|
@cindex PublicKey
|
|
@item PublicKey = <@var{key}> [obsolete]
|
|
This is the RSA public key for this host.
|
|
|
|
@cindex PublicKeyFile
|
|
@item PublicKeyFile = <@var{path}> [obsolete]
|
|
This is the full path name of the RSA public key file that was generated
|
|
by @samp{tincctl generate-keys}. It must be a full path, not a relative
|
|
directory.
|
|
|
|
@cindex PEM format
|
|
From version 1.0pre4 on tinc will store the public key directly into the
|
|
host configuration file in PEM format, the above two options then are not
|
|
necessary. Either the PEM format is used, or exactly
|
|
@strong{one of the above two options} must be specified
|
|
in each host configuration file, if you want to be able to establish a
|
|
connection with that host.
|
|
|
|
@cindex Subnet
|
|
@item Subnet = <@var{address}[/@var{prefixlength}[#@var{weight}]]>
|
|
The subnet which this tinc daemon will serve.
|
|
Tinc tries to look up which other daemon it should send a packet to by searching the appropiate subnet.
|
|
If the packet matches a subnet,
|
|
it will be sent to the daemon who has this subnet in his host configuration file.
|
|
Multiple subnet lines can be specified for each daemon.
|
|
|
|
Subnets can either be single MAC, IPv4 or IPv6 addresses,
|
|
in which case a subnet consisting of only that single address is assumed,
|
|
or they can be a IPv4 or IPv6 network address with a prefixlength.
|
|
For example, IPv4 subnets must be in a form like 192.168.1.0/24,
|
|
where 192.168.1.0 is the network address and 24 is the number of bits set in the netmask.
|
|
Note that subnets like 192.168.1.1/24 are invalid!
|
|
Read a networking HOWTO/FAQ/guide if you don't understand this.
|
|
IPv6 subnets are notated like fec0:0:0:1::/64.
|
|
MAC addresses are notated like 0:1a:2b:3c:4d:5e.
|
|
|
|
@cindex CIDR notation
|
|
Prefixlength is the number of bits set to 1 in the netmask part; for
|
|
example: netmask 255.255.255.0 would become /24, 255.255.252.0 becomes
|
|
/22. This conforms to standard CIDR notation as described in
|
|
@uref{http://www.ietf.org/rfc/rfc1519.txt, RFC1519}
|
|
|
|
A Subnet can be given a weight to indicate its priority over identical Subnets
|
|
owned by different nodes. The default weight is 10. Lower values indicate
|
|
higher priority. Packets will be sent to the node with the highest priority,
|
|
unless that node is not reachable, in which case the node with the next highest
|
|
priority will be tried, and so on.
|
|
|
|
@cindex TCPonly
|
|
@item TCPonly = <yes|no> (no)
|
|
If this variable is set to yes, then the packets are tunnelled over a
|
|
TCP connection instead of a UDP connection. This is especially useful
|
|
for those who want to run a tinc daemon from behind a masquerading
|
|
firewall, or if UDP packet routing is disabled somehow.
|
|
Setting this options also implicitly sets IndirectData.
|
|
@end table
|
|
|
|
|
|
@c ==================================================================
|
|
@node Scripts
|
|
@subsection Scripts
|
|
|
|
@cindex scripts
|
|
Apart from reading the server and host configuration files,
|
|
tinc can also run scripts at certain moments.
|
|
Under Windows (not Cygwin), the scripts should have the extension .bat.
|
|
|
|
@table @file
|
|
@cindex tinc-up
|
|
@item @value{sysconfdir}/tinc/@var{netname}/tinc-up
|
|
This is the most important script.
|
|
If it is present it will be executed right after the tinc daemon has been
|
|
started and has connected to the virtual network device.
|
|
It should be used to set up the corresponding network interface,
|
|
but can also be used to start other things.
|
|
Under Windows you can use the Network Connections control panel instead of creating this script.
|
|
|
|
@cindex tinc-down
|
|
@item @value{sysconfdir}/tinc/@var{netname}/tinc-down
|
|
This script is started right before the tinc daemon quits.
|
|
|
|
@item @value{sysconfdir}/tinc/@var{netname}/hosts/@var{host}-up
|
|
This script is started when the tinc daemon with name @var{host} becomes reachable.
|
|
|
|
@item @value{sysconfdir}/tinc/@var{netname}/hosts/@var{host}-down
|
|
This script is started when the tinc daemon with name @var{host} becomes unreachable.
|
|
|
|
@item @value{sysconfdir}/tinc/@var{netname}/host-up
|
|
This script is started when any host becomes reachable.
|
|
|
|
@item @value{sysconfdir}/tinc/@var{netname}/host-down
|
|
This script is started when any host becomes unreachable.
|
|
|
|
@item @value{sysconfdir}/tinc/@var{netname}/subnet-up
|
|
This script is started when a Subnet becomes reachable.
|
|
The Subnet and the node it belongs to are passed in environment variables.
|
|
|
|
@item @value{sysconfdir}/tinc/@var{netname}/subnet-down
|
|
This script is started when a Subnet becomes unreachable.
|
|
@end table
|
|
|
|
@cindex environment variables
|
|
The scripts are started without command line arguments,
|
|
but can make use of certain environment variables.
|
|
Under UNIX like operating systems the names of environment variables must be preceded by a $ in scripts.
|
|
Under Windows, in @file{.bat} files, they have to be put between % signs.
|
|
|
|
@table @env
|
|
@cindex NETNAME
|
|
@item NETNAME
|
|
If a netname was specified, this environment variable contains it.
|
|
|
|
@cindex NAME
|
|
@item NAME
|
|
Contains the name of this tinc daemon.
|
|
|
|
@cindex DEVICE
|
|
@item DEVICE
|
|
Contains the name of the virtual network device that tinc uses.
|
|
|
|
@cindex INTERFACE
|
|
@item INTERFACE
|
|
Contains the name of the virtual network interface that tinc uses.
|
|
This should be used for commands like ifconfig.
|
|
|
|
@cindex NODE
|
|
@item NODE
|
|
When a host becomes (un)reachable, this is set to its name.
|
|
If a subnet becomes (un)reachable, this is set to the owner of that subnet.
|
|
|
|
@cindex REMOTEADDRESS
|
|
@item REMOTEADDRESS
|
|
When a host becomes (un)reachable, this is set to its real address.
|
|
|
|
@cindex REMOTEPORT
|
|
@item REMOTEPORT
|
|
When a host becomes (un)reachable,
|
|
this is set to the port number it uses for communication with other tinc daemons.
|
|
|
|
@cindex SUBNET
|
|
@item SUBNET
|
|
When a subnet becomes (un)reachable, this is set to the subnet.
|
|
|
|
@end table
|
|
|
|
|
|
@c ==================================================================
|
|
@node How to configure
|
|
@subsection How to configure
|
|
|
|
@subsubheading Step 1. Creating initial configuration files.
|
|
|
|
The initial directory structure, configuration files and public/private keypairs are created using the following command:
|
|
|
|
@example
|
|
tincctl -n @var{netname} init @var{name}
|
|
@end example
|
|
|
|
(You will need to run this as root, or use "sudo".)
|
|
This will create the configuration directory @file{@value{sysconfdir}/tinc/@var{netname}.},
|
|
and inside it will create another directory named @file{hosts/}.
|
|
In the configuration directory, it will create the file @file{tinc.conf} with the following contents:
|
|
|
|
@example
|
|
Name = @var{name}
|
|
@end example
|
|
|
|
It will also create private RSA and ECDSA keys, which will be stored in the files @file{rsa_key.priv} and @file{ecdsa_key.priv}.
|
|
It will also create a host configuration file @file{hosts/@var{name}},
|
|
which will contain the corresponding public RSA and ECDSA keys.
|
|
|
|
Finally, on UNIX operating systems, it will create an executable script @file{tinc-up},
|
|
which will initially not do anything except warning that you should edit it.
|
|
|
|
@subsubheading Step 2. Modifying the initial configuration.
|
|
|
|
Unless you want to use tinc in switch mode,
|
|
you should now configure which range of addresses you will use on the VPN.
|
|
Let's assume you will be part of a VPN which uses the address range 192.168.0.0/16,
|
|
and you yourself have a smaller portion of that range: 192.168.2.0/24.
|
|
Then you should run the following command:
|
|
|
|
@example
|
|
tincctl -n @var{netname} config add subnet 192.168.2.0/24
|
|
@end example
|
|
|
|
This will add a Subnet statement to your host configuration file.
|
|
Try opening the file @file{@value{sysconfdir}/tinc/@var{netname}/hosts/@var{name}} in an editor.
|
|
You should now see a file containing the public RSA and ECDSA keys (which looks like a bunch of random characters),
|
|
and the following line at the bottom:
|
|
|
|
@example
|
|
Subnet = 192.168.2.0/24
|
|
@end example
|
|
|
|
If you will use more than one address range, you can add more Subnets.
|
|
For example, if you also use the IPv6 subnet fec0:0:0:2::/64, you can add it as well:
|
|
|
|
@example
|
|
tincctl -n @var{netname} config add subnet fec0:0:0:2::/24
|
|
@end example
|
|
|
|
This will add another line to the file @file{hosts/@var{name}}.
|
|
If you make a mistake, you can undo it by simply using @samp{config del} instead of @samp{config add}.
|
|
|
|
If you want other tinc daemons to create meta-connections to your daemon,
|
|
you should add your public IP address or hostname to your host configuration file.
|
|
For example, if your hostname is foo.example.org, run:
|
|
|
|
@example
|
|
tincctl -n @var{netname} config add address foo.example.org
|
|
@end example
|
|
|
|
If you already know to which daemons your daemon should make meta-connections,
|
|
you should configure that now as well.
|
|
Suppose you want to connect to a daemon named "bar", run:
|
|
|
|
@example
|
|
tincctl -n @var{netname} config add connectto bar
|
|
@end example
|
|
|
|
Note that you specify the Name of the other daemon here, not an IP address or hostname!
|
|
When you start tinc, and it tries to make a connection to "bar",
|
|
it will look for a host configuration file named @file{hosts/bar},
|
|
and will read Address statements and public keys from that file.
|
|
|
|
@subsubheading Step 2. Exchanging configuration files.
|
|
|
|
If your daemon has a ConnectTo = bar statement in its @file{tinc.conf} file,
|
|
or if bar has a ConnectTo your daemon, then you both need each other's host configuration files.
|
|
You should send @file{hosts/@var{name}} to bar, and bar should send you his file which you should move to @file{hosts/bar}.
|
|
If you are on a UNIX platform, you can easily send an email containing the necessary information using the following command
|
|
(assuming the owner of bar has the email address bar@@example.org):
|
|
|
|
@example
|
|
tincctl -n @var{netname} export | mail -s "My config file" bar@@example.org
|
|
@end example
|
|
|
|
If the owner of bar does the same to send his host configuration file to you,
|
|
you can probably pipe his email through the following command,
|
|
or you can just start this command in a terminal and copy&paste the email:
|
|
|
|
@example
|
|
tincctl -n @var{netname} import
|
|
@end example
|
|
|
|
If you are the owner of bar yourself, and you have SSH access to that computer,
|
|
you can also swap the host configuration files using the following command:
|
|
|
|
@example
|
|
tincctl -n @var{netname} export \
|
|
| ssh bar.example.org tincctl -n @var{netname} exchange \
|
|
| tincctl -n @var{netname} import
|
|
@end example
|
|
|
|
You should repeat this for all nodes you ConnectTo, or which ConnectTo you.
|
|
However, remember that you do not need to ConnectTo all nodes in the VPN;
|
|
it is only necessary to create one or a few meta-connections,
|
|
after the connections are made tinc will learn about all the other nodes in the VPN,
|
|
and will automatically make other connections as necessary.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Network interfaces
|
|
@section Network interfaces
|
|
|
|
Before tinc can start transmitting data over the tunnel, it must
|
|
set up the virtual network interface.
|
|
|
|
First, decide which IP addresses you want to have associated with these
|
|
devices, and what network mask they must have.
|
|
|
|
Tinc will open a virtual network device (@file{/dev/tun}, @file{/dev/tap0} or similar),
|
|
which will also create a network interface called something like @samp{tun0}, @samp{tap0}.
|
|
If you are using the Linux tun/tap driver, the network interface will by default have the same name as the @var{netname}.
|
|
Under Windows you can change the name of the network interface from the Network Connections control panel.
|
|
|
|
@cindex tinc-up
|
|
You can configure the network interface by putting ordinary ifconfig, route, and other commands
|
|
to a script named @file{@value{sysconfdir}/tinc/@var{netname}/tinc-up}.
|
|
When tinc starts, this script will be executed. When tinc exits, it will execute the script named
|
|
@file{@value{sysconfdir}/tinc/@var{netname}/tinc-down}, but normally you don't need to create that script.
|
|
You can manually open the script in an editor, or use the following command:
|
|
|
|
@example
|
|
tincctl -n @var{netname} edit tinc-up
|
|
@end example
|
|
|
|
An example @file{tinc-up} script, that would be appropriate for the scenario in the previous section, is:
|
|
|
|
@example
|
|
#!/bin/sh
|
|
ifconfig $INTERFACE 192.168.2.1 netmask 255.255.0.0
|
|
ip addr add fec0:0:0:2::/48 dev $INTERFACE
|
|
@end example
|
|
|
|
The first command gives the interface an IPv4 address and a netmask.
|
|
The kernel will also automatically add an IPv4 route to this interface, so normally you don't need
|
|
to add route commands to the @file{tinc-up} script.
|
|
The kernel will also bring the interface up after this command.
|
|
@cindex netmask
|
|
The netmask is the mask of the @emph{entire} VPN network, not just your
|
|
own subnet.
|
|
The second command gives the interface an IPv6 address and netmask,
|
|
which will also automatically add an IPv6 route.
|
|
If you only want to use "ip addr" commands on Linux, don't forget that it doesn't bring the interface up, unlike ifconfig,
|
|
so you need to add @samp{ip link set $INTERFACE up} in that case.
|
|
|
|
The exact syntax of the ifconfig and route commands differs from platform to platform.
|
|
You can look up the commands for setting addresses and adding routes in @ref{Platform specific information},
|
|
but it is best to consult the manpages of those utilities on your platform.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Example configuration
|
|
@section Example configuration
|
|
|
|
|
|
@cindex example
|
|
Imagine the following situation. Branch A of our example `company' wants to connect
|
|
three branch offices in B, C and D using the Internet. All four offices
|
|
have a 24/7 connection to the Internet.
|
|
|
|
A is going to serve as the center of the network. B and C will connect
|
|
to A, and D will connect to C. Each office will be assigned their own IP
|
|
network, 10.x.0.0.
|
|
|
|
@example
|
|
A: net 10.1.0.0 mask 255.255.0.0 gateway 10.1.54.1 internet IP 1.2.3.4
|
|
B: net 10.2.0.0 mask 255.255.0.0 gateway 10.2.1.12 internet IP 2.3.4.5
|
|
C: net 10.3.0.0 mask 255.255.0.0 gateway 10.3.69.254 internet IP 3.4.5.6
|
|
D: net 10.4.0.0 mask 255.255.0.0 gateway 10.4.3.32 internet IP 4.5.6.7
|
|
@end example
|
|
|
|
Here, ``gateway'' is the VPN IP address of the machine that is running the
|
|
tincd, and ``internet IP'' is the IP address of the firewall, which does not
|
|
need to run tincd, but it must do a port forwarding of TCP and UDP on port
|
|
655 (unless otherwise configured).
|
|
|
|
In this example, it is assumed that eth0 is the interface that points to
|
|
the inner (physical) LAN of the office, although this could also be the
|
|
same as the interface that leads to the Internet. The configuration of
|
|
the real interface is also shown as a comment, to give you an idea of
|
|
how these example host is set up. All branches use the netname `company'
|
|
for this particular VPN.
|
|
|
|
Each branch is set up using the @samp{tincctl init} and @samp{tincctl config} commands,
|
|
here we just show the end results:
|
|
|
|
@subsubheading For Branch A
|
|
|
|
@emph{BranchA} would be configured like this:
|
|
|
|
In @file{@value{sysconfdir}/tinc/company/tinc-up}:
|
|
|
|
@example
|
|
#!/bin/sh
|
|
|
|
# Real interface of internal network:
|
|
# ifconfig eth0 10.1.54.1 netmask 255.255.0.0
|
|
|
|
ifconfig $INTERFACE 10.1.54.1 netmask 255.0.0.0
|
|
@end example
|
|
|
|
and in @file{@value{sysconfdir}/tinc/company/tinc.conf}:
|
|
|
|
@example
|
|
Name = BranchA
|
|
@end example
|
|
|
|
On all hosts, @file{@value{sysconfdir}/tinc/company/hosts/BranchA} contains:
|
|
|
|
@example
|
|
Subnet = 10.1.0.0/16
|
|
Address = 1.2.3.4
|
|
|
|
-----BEGIN RSA PUBLIC KEY-----
|
|
...
|
|
-----END RSA PUBLIC KEY-----
|
|
@end example
|
|
|
|
Note that the IP addresses of eth0 and the VPN interface are the same.
|
|
This is quite possible, if you make sure that the netmasks of the interfaces are different.
|
|
It is in fact recommended to give both real internal network interfaces and VPN interfaces the same IP address,
|
|
since that will make things a lot easier to remember and set up.
|
|
|
|
|
|
@subsubheading For Branch B
|
|
|
|
In @file{@value{sysconfdir}/tinc/company/tinc-up}:
|
|
|
|
@example
|
|
#!/bin/sh
|
|
|
|
# Real interface of internal network:
|
|
# ifconfig eth0 10.2.43.8 netmask 255.255.0.0
|
|
|
|
ifconfig $INTERFACE 10.2.1.12 netmask 255.0.0.0
|
|
@end example
|
|
|
|
and in @file{@value{sysconfdir}/tinc/company/tinc.conf}:
|
|
|
|
@example
|
|
Name = BranchB
|
|
ConnectTo = BranchA
|
|
@end example
|
|
|
|
Note here that the internal address (on eth0) doesn't have to be the
|
|
same as on the VPN interface. Also, ConnectTo is given so that this node will
|
|
always try to connect to BranchA.
|
|
|
|
On all hosts, in @file{@value{sysconfdir}/tinc/company/hosts/BranchB}:
|
|
|
|
@example
|
|
Subnet = 10.2.0.0/16
|
|
Address = 2.3.4.5
|
|
|
|
-----BEGIN RSA PUBLIC KEY-----
|
|
...
|
|
-----END RSA PUBLIC KEY-----
|
|
@end example
|
|
|
|
|
|
@subsubheading For Branch C
|
|
|
|
In @file{@value{sysconfdir}/tinc/company/tinc-up}:
|
|
|
|
@example
|
|
#!/bin/sh
|
|
|
|
# Real interface of internal network:
|
|
# ifconfig eth0 10.3.69.254 netmask 255.255.0.0
|
|
|
|
ifconfig $INTERFACE 10.3.69.254 netmask 255.0.0.0
|
|
@end example
|
|
|
|
and in @file{@value{sysconfdir}/tinc/company/tinc.conf}:
|
|
|
|
@example
|
|
Name = BranchC
|
|
ConnectTo = BranchA
|
|
@end example
|
|
|
|
C already has another daemon that runs on port 655, so they have to
|
|
reserve another port for tinc. It knows the portnumber it has to listen on
|
|
from it's own host configuration file.
|
|
|
|
On all hosts, in @file{@value{sysconfdir}/tinc/company/hosts/BranchC}:
|
|
|
|
@example
|
|
Address = 3.4.5.6
|
|
Subnet = 10.3.0.0/16
|
|
Port = 2000
|
|
|
|
-----BEGIN RSA PUBLIC KEY-----
|
|
...
|
|
-----END RSA PUBLIC KEY-----
|
|
@end example
|
|
|
|
|
|
@subsubheading For Branch D
|
|
|
|
In @file{@value{sysconfdir}/tinc/company/tinc-up}:
|
|
|
|
@example
|
|
#!/bin/sh
|
|
|
|
# Real interface of internal network:
|
|
# ifconfig eth0 10.4.3.32 netmask 255.255.0.0
|
|
|
|
ifconfig $INTERFACE 10.4.3.32 netmask 255.0.0.0
|
|
@end example
|
|
|
|
and in @file{@value{sysconfdir}/tinc/company/tinc.conf}:
|
|
|
|
@example
|
|
Name = BranchD
|
|
ConnectTo = BranchC
|
|
@end example
|
|
|
|
D will be connecting to C, which has a tincd running for this network on
|
|
port 2000. It knows the port number from the host configuration file.
|
|
|
|
On all hosts, in @file{@value{sysconfdir}/tinc/company/hosts/BranchD}:
|
|
|
|
@example
|
|
Subnet = 10.4.0.0/16
|
|
Address = 4.5.6.7
|
|
|
|
-----BEGIN RSA PUBLIC KEY-----
|
|
...
|
|
-----END RSA PUBLIC KEY-----
|
|
@end example
|
|
|
|
@subsubheading Key files
|
|
|
|
A, B, C and D all have their own public/private keypairs:
|
|
|
|
The private RSA key is stored in @file{@value{sysconfdir}/tinc/company/rsa_key.priv},
|
|
the private ECDSA key is stored in @file{@value{sysconfdir}/tinc/company/ecdsa_key.priv},
|
|
and the public RSA and ECDSA keys are put into the host configuration file in the @file{@value{sysconfdir}/tinc/company/hosts/} directory.
|
|
|
|
@subsubheading Starting
|
|
|
|
After each branch has finished configuration and they have distributed
|
|
the host configuration files amongst them, they can start their tinc daemons.
|
|
They don't necessarily have to wait for the other branches to have started
|
|
their daemons, tinc will try connecting until they are available.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Running tinc
|
|
@chapter Running tinc
|
|
|
|
If everything else is done, you can start tinc by typing the following command:
|
|
|
|
@example
|
|
tincctl -n @var{netname} start
|
|
@end example
|
|
|
|
@cindex daemon
|
|
Tinc will detach from the terminal and continue to run in the background like a good daemon.
|
|
If there are any problems however you can try to increase the debug level
|
|
and look in the syslog to find out what the problems are.
|
|
|
|
@menu
|
|
* Runtime options::
|
|
* Signals::
|
|
* Debug levels::
|
|
* Solving problems::
|
|
* Error messages::
|
|
* Sending bug reports::
|
|
@end menu
|
|
|
|
|
|
@c ==================================================================
|
|
@node Runtime options
|
|
@section Runtime options
|
|
|
|
Besides the settings in the configuration file, tinc also accepts some
|
|
command line options.
|
|
|
|
@cindex command line
|
|
@cindex runtime options
|
|
@cindex options
|
|
@c from the manpage
|
|
@table @option
|
|
@item -c, --config=@var{path}
|
|
Read configuration options from the directory @var{path}. The default is
|
|
@file{@value{sysconfdir}/tinc/@var{netname}/}.
|
|
|
|
@item -D, --no-detach
|
|
Don't fork and detach.
|
|
This will also disable the automatic restart mechanism for fatal errors.
|
|
|
|
@cindex debug level
|
|
@item -d, --debug=@var{level}
|
|
Set debug level to @var{level}. The higher the debug level, the more gets
|
|
logged. Everything goes via syslog.
|
|
|
|
@item -n, --net=@var{netname}
|
|
Use configuration for net @var{netname}.
|
|
This will let tinc read all configuration files from
|
|
@file{@value{sysconfdir}/tinc/@var{netname}/}.
|
|
Specifying . for @var{netname} is the same as not specifying any @var{netname}.
|
|
@xref{Multiple networks}.
|
|
|
|
@item --pidfile=@var{filename}
|
|
Store a cookie in @var{filename} which allows tincctl to authenticate.
|
|
If unspecified, the default is
|
|
@file{@value{localstatedir}/run/tinc.@var{netname}.pid}.
|
|
|
|
@item -o, --option=[@var{HOST}.]@var{KEY}=@var{VALUE}
|
|
Without specifying a @var{HOST}, this will set server configuration variable @var{KEY} to @var{VALUE}.
|
|
If specified as @var{HOST}.@var{KEY}=@var{VALUE},
|
|
this will set the host configuration variable @var{KEY} of the host named @var{HOST} to @var{VALUE}.
|
|
This option can be used more than once to specify multiple configuration variables.
|
|
|
|
@item -L, --mlock
|
|
Lock tinc into main memory.
|
|
This will prevent sensitive data like shared private keys to be written to the system swap files/partitions.
|
|
|
|
This option is not supported on all platforms.
|
|
|
|
@item --logfile[=@var{file}]
|
|
Write log entries to a file instead of to the system logging facility.
|
|
If @var{file} is omitted, the default is @file{@value{localstatedir}/log/tinc.@var{netname}.log}.
|
|
|
|
@item --bypass-security
|
|
Disables encryption and authentication.
|
|
Only useful for debugging.
|
|
|
|
@item -R, --chroot
|
|
Change process root directory to the directory where the config file is
|
|
located (@file{@value{sysconfdir}/tinc/@var{netname}/} as determined by
|
|
-n/--net option or as given by -c/--config option), for added security.
|
|
The chroot is performed after all the initialization is done, after
|
|
writing pid files and opening network sockets.
|
|
|
|
Note that this option alone does not do any good without -U/--user, below.
|
|
|
|
Note also that tinc can't run scripts anymore (such as tinc-down or host-up),
|
|
unless it's setup to be runnable inside chroot environment.
|
|
|
|
This option is not supported on all platforms.
|
|
@item -U, --user=@var{user}
|
|
Switch to the given @var{user} after initialization, at the same time as
|
|
chroot is performed (see --chroot above). With this option tinc drops
|
|
privileges, for added security.
|
|
|
|
This option is not supported on all platforms.
|
|
|
|
@item --help
|
|
Display a short reminder of these runtime options and terminate.
|
|
|
|
@item --version
|
|
Output version information and exit.
|
|
|
|
@end table
|
|
|
|
@c ==================================================================
|
|
@node Signals
|
|
@section Signals
|
|
|
|
@cindex signals
|
|
You can also send the following signals to a running tincd process:
|
|
|
|
@c from the manpage
|
|
@table @samp
|
|
|
|
@item ALRM
|
|
Forces tinc to try to connect to all uplinks immediately.
|
|
Usually tinc attempts to do this itself,
|
|
but increases the time it waits between the attempts each time it failed,
|
|
and if tinc didn't succeed to connect to an uplink the first time after it started,
|
|
it defaults to the maximum time of 15 minutes.
|
|
|
|
@item HUP
|
|
Partially rereads configuration files.
|
|
Connections to hosts whose host config file are removed are closed.
|
|
New outgoing connections specified in @file{tinc.conf} will be made.
|
|
If the --logfile option is used, this will also close and reopen the log file,
|
|
useful when log rotation is used.
|
|
|
|
@end table
|
|
|
|
@c ==================================================================
|
|
@node Debug levels
|
|
@section Debug levels
|
|
|
|
@cindex debug levels
|
|
The tinc daemon can send a lot of messages to the syslog.
|
|
The higher the debug level, the more messages it will log.
|
|
Each level inherits all messages of the previous level:
|
|
|
|
@c from the manpage
|
|
@table @samp
|
|
|
|
@item 0
|
|
This will log a message indicating tinc has started along with a version number.
|
|
It will also log any serious error.
|
|
|
|
@item 1
|
|
This will log all connections that are made with other tinc daemons.
|
|
|
|
@item 2
|
|
This will log status and error messages from scripts and other tinc daemons.
|
|
|
|
@item 3
|
|
This will log all requests that are exchanged with other tinc daemons. These include
|
|
authentication, key exchange and connection list updates.
|
|
|
|
@item 4
|
|
This will log a copy of everything received on the meta socket.
|
|
|
|
@item 5
|
|
This will log all network traffic over the virtual private network.
|
|
|
|
@end table
|
|
|
|
@c ==================================================================
|
|
@node Solving problems
|
|
@section Solving problems
|
|
|
|
If tinc starts without problems, but if the VPN doesn't work, you will have to find the cause of the problem.
|
|
The first thing to do is to start tinc with a high debug level in the foreground,
|
|
so you can directly see everything tinc logs:
|
|
|
|
@example
|
|
tincd -n @var{netname} -d5 -D
|
|
@end example
|
|
|
|
If tinc does not log any error messages, then you might want to check the following things:
|
|
|
|
@itemize
|
|
@item @file{tinc-up} script
|
|
Does this script contain the right commands?
|
|
Normally you must give the interface the address of this host on the VPN, and the netmask must be big enough so that the entire VPN is covered.
|
|
|
|
@item Subnet
|
|
Does the Subnet (or Subnets) in the host configuration file of this host match the portion of the VPN that belongs to this host?
|
|
|
|
@item Firewalls and NATs
|
|
Do you have a firewall or a NAT device (a masquerading firewall or perhaps an ADSL router that performs masquerading)?
|
|
If so, check that it allows TCP and UDP traffic on port 655.
|
|
If it masquerades and the host running tinc is behind it, make sure that it forwards TCP and UDP traffic to port 655 to the host running tinc.
|
|
You can add @samp{TCPOnly = yes} to your host config file to force tinc to only use a single TCP connection,
|
|
this works through most firewalls and NATs.
|
|
|
|
@end itemize
|
|
|
|
|
|
@c ==================================================================
|
|
@node Error messages
|
|
@section Error messages
|
|
|
|
What follows is a list of the most common error messages you might find in the logs.
|
|
Some of them will only be visible if the debug level is high enough.
|
|
|
|
@table @samp
|
|
@item Could not open /dev/tap0: No such device
|
|
|
|
@itemize
|
|
@item You forgot to `modprobe netlink_dev' or `modprobe ethertap'.
|
|
@item You forgot to compile `Netlink device emulation' in the kernel.
|
|
@end itemize
|
|
|
|
@item Can't write to /dev/net/tun: No such device
|
|
|
|
@itemize
|
|
@item You forgot to `modprobe tun'.
|
|
@item You forgot to compile `Universal TUN/TAP driver' in the kernel.
|
|
@item The tun device is located somewhere else in @file{/dev/}.
|
|
@end itemize
|
|
|
|
@item Network address and prefix length do not match!
|
|
|
|
@itemize
|
|
@item The Subnet field must contain a @emph{network} address, trailing bits should be 0.
|
|
@item If you only want to use one IP address, set the netmask to /32.
|
|
@end itemize
|
|
|
|
@item Error reading RSA key file `rsa_key.priv': No such file or directory
|
|
|
|
@itemize
|
|
@item You forgot to create a public/private keypair.
|
|
@item Specify the complete pathname to the private key file with the @samp{PrivateKeyFile} option.
|
|
@end itemize
|
|
|
|
@item Warning: insecure file permissions for RSA private key file `rsa_key.priv'!
|
|
|
|
@itemize
|
|
@item The private key file is readable by users other than root.
|
|
Use chmod to correct the file permissions.
|
|
@end itemize
|
|
|
|
@item Creating metasocket failed: Address family not supported
|
|
|
|
@itemize
|
|
@item By default tinc tries to create both IPv4 and IPv6 sockets.
|
|
On some platforms this might not be implemented.
|
|
If the logs show @samp{Ready} later on, then at least one metasocket was created,
|
|
and you can ignore this message.
|
|
You can add @samp{AddressFamily = ipv4} to @file{tinc.conf} to prevent this from happening.
|
|
@end itemize
|
|
|
|
@item Cannot route packet: unknown IPv4 destination 1.2.3.4
|
|
|
|
@itemize
|
|
@item You try to send traffic to a host on the VPN for which no Subnet is known.
|
|
@item If it is a broadcast address (ending in .255), it probably is a samba server or a Windows host sending broadcast packets.
|
|
You can ignore it.
|
|
@end itemize
|
|
|
|
@item Cannot route packet: ARP request for unknown address 1.2.3.4
|
|
|
|
@itemize
|
|
@item You try to send traffic to a host on the VPN for which no Subnet is known.
|
|
@end itemize
|
|
|
|
@item Packet with destination 1.2.3.4 is looping back to us!
|
|
|
|
@itemize
|
|
@item Something is not configured right. Packets are being sent out to the
|
|
virtual network device, but according to the Subnet directives in your host configuration
|
|
file, those packets should go to your own host. Most common mistake is that
|
|
you have a Subnet line in your host configuration file with a prefix length which is
|
|
just as large as the prefix of the virtual network interface. The latter should in almost all
|
|
cases be larger. Rethink your configuration.
|
|
Note that you will only see this message if you specified a debug
|
|
level of 5 or higher!
|
|
@item Chances are that a @samp{Subnet = ...} line in the host configuration file of this tinc daemon is wrong.
|
|
Change it to a subnet that is accepted locally by another interface,
|
|
or if that is not the case, try changing the prefix length into /32.
|
|
@end itemize
|
|
|
|
@item Node foo (1.2.3.4) is not reachable
|
|
|
|
@itemize
|
|
@item Node foo does not have a connection anymore, its tinc daemon is not running or its connection to the Internet is broken.
|
|
@end itemize
|
|
|
|
@item Received UDP packet from unknown source 1.2.3.4 (port 12345)
|
|
|
|
@itemize
|
|
@item If you see this only sporadically, it is harmless and caused by a node sending packets using an old key.
|
|
@item If you see this often and another node is not reachable anymore, then a NAT (masquerading firewall) is changing the source address of UDP packets.
|
|
You can add @samp{TCPOnly = yes} to host configuration files to force all VPN traffic to go over a TCP connection.
|
|
@end itemize
|
|
|
|
@item Got bad/bogus/unauthorized REQUEST from foo (1.2.3.4 port 12345)
|
|
|
|
@itemize
|
|
@item Node foo does not have the right public/private keypair.
|
|
Generate new keypairs and distribute them again.
|
|
@item An attacker tries to gain access to your VPN.
|
|
@item A network error caused corruption of metadata sent from foo.
|
|
@end itemize
|
|
|
|
@end table
|
|
|
|
@c ==================================================================
|
|
@node Sending bug reports
|
|
@section Sending bug reports
|
|
|
|
If you really can't find the cause of a problem, or if you suspect tinc is not working right,
|
|
you can send us a bugreport, see @ref{Contact information}.
|
|
Be sure to include the following information in your bugreport:
|
|
|
|
@itemize
|
|
@item A clear description of what you are trying to achieve and what the problem is.
|
|
@item What platform (operating system, version, hardware architecture) and which version of tinc you use.
|
|
@item If compiling tinc fails, a copy of @file{config.log} and the error messages you get.
|
|
@item Otherwise, a copy of @file{tinc.conf}, @file{tinc-up} and all files in the @file{hosts/} directory.
|
|
@item The output of the commands @samp{ifconfig -a} and @samp{route -n} (or @samp{netstat -rn} if that doesn't work).
|
|
@item The output of any command that fails to work as it should (like ping or traceroute).
|
|
@end itemize
|
|
|
|
@c ==================================================================
|
|
@node Controlling tinc
|
|
@chapter Controlling tinc
|
|
|
|
You can control and inspect a running tincd through the tincctl
|
|
command. A quick example:
|
|
|
|
@example
|
|
tincctl -n @var{netname} reload
|
|
@end example
|
|
|
|
@menu
|
|
* tincctl runtime options::
|
|
* tincctl environment variables::
|
|
* tincctl commands::
|
|
* tincctl examples::
|
|
* tincctl top::
|
|
@end menu
|
|
|
|
|
|
@c ==================================================================
|
|
@node tincctl runtime options
|
|
@section tincctl runtime options
|
|
|
|
@c from the manpage
|
|
@table @option
|
|
@item -c, --config=@var{path}
|
|
Read configuration options from the directory @var{path}. The default is
|
|
@file{@value{sysconfdir}/tinc/@var{netname}/}.
|
|
|
|
@item -n, --net=@var{netname}
|
|
Use configuration for net @var{netname}. @xref{Multiple networks}.
|
|
|
|
@item --pidfile=@var{filename}
|
|
Use the cookie from @var{filename} to authenticate with a running tinc daemon.
|
|
If unspecified, the default is
|
|
@file{@value{localstatedir}/run/tinc.@var{netname}.pid}.
|
|
|
|
@item --help
|
|
Display a short reminder of runtime options and commands, then terminate.
|
|
|
|
@item --version
|
|
Output version information and exit.
|
|
|
|
@end table
|
|
|
|
@c ==================================================================
|
|
@node tincctl environment variables
|
|
@section tincctl environment variables
|
|
|
|
@table @env
|
|
@cindex NETNAME
|
|
@item NETNAME
|
|
If no netname is specified on the command line with the @option{-n} option,
|
|
the value of this environment variable is used.
|
|
@end table
|
|
|
|
@c ==================================================================
|
|
@node tincctl commands
|
|
@section tincctl commands
|
|
|
|
@c from the manpage
|
|
@table @code
|
|
|
|
@item init [@var{name}]
|
|
Create initial configuration files and RSA and ECDSA keypairs with default length.
|
|
If no @var{name} for this node is given, it will be asked for.
|
|
|
|
@item config [get] @var{variable}
|
|
Print the current value of configuration variable @var{variable}.
|
|
If more than one variable with the same name exists,
|
|
the value of each of them will be printed on a separate line.
|
|
|
|
@item config [set] @var{variable} @var{value}
|
|
Set configuration variable @var{variable} to the given @var{value}.
|
|
All previously existing configuration variables with the same name are removed.
|
|
To set a variable for a specific host, use the notation @var{host}.@var{variable}.
|
|
|
|
@item config add @var{variable} @var{value}
|
|
As above, but without removing any previously existing configuration variables.
|
|
|
|
@item config del @var{variable} [@var{value}]
|
|
Remove configuration variables with the same name and @var{value}.
|
|
If no @var{value} is given, all configuration variables with the same name will be removed.
|
|
|
|
@item edit @var{filename}
|
|
Start an editor for the given configuration file.
|
|
You do not need to specify the full path to the file.
|
|
|
|
@item export
|
|
Export the host configuration file of the local node to standard output.
|
|
|
|
@item export-all
|
|
Export all host configuration files to standard output.
|
|
|
|
@item import [--force]
|
|
Import host configuration file(s) generated by the tincctl export command from standard input.
|
|
Already existing host configuration files are not overwritten unless the option --force is used.
|
|
|
|
@item exchange [--force]
|
|
The same as export followed by import.
|
|
|
|
@item exchange-all [--force]
|
|
The same as export-all followed by import.
|
|
|
|
@item start [tincd options]
|
|
Start @samp{tincd}, optionally with the given extra options.
|
|
|
|
@item stop
|
|
Stop @samp{tincd}.
|
|
|
|
@item restart
|
|
Restart @samp{tincd}.
|
|
|
|
@item reload
|
|
Partially rereads configuration files. Connections to hosts whose host
|
|
config files are removed are closed. New outgoing connections specified
|
|
in @file{tinc.conf} will be made.
|
|
|
|
@item pid
|
|
Shows the PID of the currently running @samp{tincd}.
|
|
|
|
@item generate-keys [@var{bits}]
|
|
Generate public/private keypair of @var{bits} length. If @var{bits} is not specified,
|
|
1024 is the default. tinc will ask where you want to store the files,
|
|
but will default to the configuration directory (you can use the -c or -n
|
|
option).
|
|
|
|
@item dump [reachable] nodes
|
|
Dump a list of all known nodes in the VPN.
|
|
If the reachable keyword is used, only lists reachable nodes.
|
|
|
|
@item dump edges
|
|
Dump a list of all known connections in the VPN.
|
|
|
|
@item dump subnets
|
|
Dump a list of all known subnets in the VPN.
|
|
|
|
@item dump connections
|
|
Dump a list of all meta connections with ourself.
|
|
|
|
@item dump graph | digraph
|
|
Dump a graph of the VPN in dotty format.
|
|
Nodes are colored according to their reachability:
|
|
red nodes are unreachable, orange nodes are indirectly reachable, green nodes are directly reachable.
|
|
Black nodes are either directly or indirectly reachable, but direct reachability has not been tried yet.
|
|
|
|
@item info @var{node} | @var{subnet} | @var{address}
|
|
Show information about a particular @var{node}, @var{subnet} or @var{address}.
|
|
If an @var{address} is given, any matching subnet will be shown.
|
|
|
|
@item purge
|
|
Purges all information remembered about unreachable nodes.
|
|
|
|
@item debug @var{level}
|
|
Sets debug level to @var{level}.
|
|
|
|
@item log [@var{level}]
|
|
Capture log messages from a running tinc daemon.
|
|
An optional debug level can be given that will be applied only for log messages sent to tincctl.
|
|
|
|
@item retry
|
|
Forces tinc to try to connect to all uplinks immediately.
|
|
Usually tinc attempts to do this itself,
|
|
but increases the time it waits between the attempts each time it failed,
|
|
and if tinc didn't succeed to connect to an uplink the first time after it started,
|
|
it defaults to the maximum time of 15 minutes.
|
|
|
|
@item disconnect @var{node}
|
|
Closes the meta connection with the given @var{node}.
|
|
|
|
@item top
|
|
If tincctl is compiled with libcurses support, this will display live traffic statistics for all the known nodes,
|
|
similar to the UNIX top command.
|
|
See below for more information.
|
|
|
|
@item pcap
|
|
Dump VPN traffic going through the local tinc node in pcap-savefile format to standard output,
|
|
from where it can be redirected to a file or piped through a program that can parse it directly,
|
|
such as tcpdump.
|
|
|
|
@end table
|
|
|
|
@c ==================================================================
|
|
@node tincctl examples
|
|
@section tincctl examples
|
|
|
|
Examples of some commands:
|
|
|
|
@example
|
|
tincctl -n vpn dump graph | circo -Txlib
|
|
tincctl -n vpn pcap | tcpdump -r -
|
|
tincctl -n vpn top
|
|
@end example
|
|
|
|
Example of configuring tinc using tincctl:
|
|
|
|
@example
|
|
tincctl -n vpn init foo
|
|
tincctl -n vpn config Subnet 192.168.1.0/24
|
|
tincctl -n vpn config bar.Address bar.example.com
|
|
tincctl -n vpn config ConnectTo bar
|
|
tincctl -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@@example.com
|
|
@end example
|
|
|
|
@c ==================================================================
|
|
@node tincctl top
|
|
@section tincctl top
|
|
|
|
The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters.
|
|
It displays a list of all the known nodes in the left-most column,
|
|
and the amount of bytes and packets read from and sent to each node in the other columns.
|
|
By default, the information is updated every second.
|
|
The behaviour of the top command can be changed using the following keys:
|
|
|
|
@table @key
|
|
|
|
@item s
|
|
Change the interval between updates.
|
|
After pressing the @key{s} key, enter the desired interval in seconds, followed by enter.
|
|
Fractional seconds are honored.
|
|
Intervals lower than 0.1 seconds are not allowed.
|
|
|
|
@item c
|
|
Toggle between displaying current traffic rates (in packets and bytes per second)
|
|
and cummulative traffic (total packets and bytes since the tinc daemon started).
|
|
|
|
@item n
|
|
Sort the list of nodes by name.
|
|
|
|
@item i
|
|
Sort the list of nodes by incoming amount of bytes.
|
|
|
|
@item I
|
|
Sort the list of nodes by incoming amount of packets.
|
|
|
|
@item o
|
|
Sort the list of nodes by outgoing amount of bytes.
|
|
|
|
@item O
|
|
Sort the list of nodes by outgoing amount of packets.
|
|
|
|
@item t
|
|
Sort the list of nodes by sum of incoming and outgoing amount of bytes.
|
|
|
|
@item T
|
|
Sort the list of nodes by sum of incoming and outgoing amount of packets.
|
|
|
|
@item b
|
|
Show amount of traffic in bytes.
|
|
|
|
@item k
|
|
Show amount of traffic in kilobytes.
|
|
|
|
@item M
|
|
Show amount of traffic in megabytes.
|
|
|
|
@item G
|
|
Show amount of traffic in gigabytes.
|
|
|
|
@item q
|
|
Quit.
|
|
|
|
@end table
|
|
|
|
|
|
@c ==================================================================
|
|
@node Technical information
|
|
@chapter Technical information
|
|
|
|
|
|
@menu
|
|
* The connection::
|
|
* The meta-protocol::
|
|
* Security::
|
|
@end menu
|
|
|
|
|
|
@c ==================================================================
|
|
@node The connection
|
|
@section The connection
|
|
|
|
@cindex connection
|
|
Tinc is a daemon that takes VPN data and transmit that to another host
|
|
computer over the existing Internet infrastructure.
|
|
|
|
@menu
|
|
* The UDP tunnel::
|
|
* The meta-connection::
|
|
@end menu
|
|
|
|
|
|
@c ==================================================================
|
|
@node The UDP tunnel
|
|
@subsection The UDP tunnel
|
|
|
|
@cindex virtual network device
|
|
@cindex frame type
|
|
The data itself is read from a character device file, the so-called
|
|
@emph{virtual network device}. This device is associated with a network
|
|
interface. Any data sent to this interface can be read from the device,
|
|
and any data written to the device gets sent from the interface.
|
|
There are two possible types of virtual network devices:
|
|
`tun' style, which are point-to-point devices which can only handle IPv4 and/or IPv6 packets,
|
|
and `tap' style, which are Ethernet devices and handle complete Ethernet frames.
|
|
|
|
So when tinc reads an Ethernet frame from the device, it determines its
|
|
type. When tinc is in it's default routing mode, it can handle IPv4 and IPv6
|
|
packets. Depending on the Subnet lines, it will send the packets off to their destination IP address.
|
|
In the `switch' and `hub' mode, tinc will use broadcasts and MAC address discovery
|
|
to deduce the destination of the packets.
|
|
Since the latter modes only depend on the link layer information,
|
|
any protocol that runs over Ethernet is supported (for instance IPX and Appletalk).
|
|
However, only `tap' style devices provide this information.
|
|
|
|
After the destination has been determined,
|
|
the packet will be compressed (optionally),
|
|
a sequence number will be added to the packet,
|
|
the packet will then be encrypted
|
|
and a message authentication code will be appended.
|
|
|
|
@cindex encapsulating
|
|
@cindex UDP
|
|
When that is done, time has come to actually transport the
|
|
packet to the destination computer. We do this by sending the packet
|
|
over an UDP connection to the destination host. This is called
|
|
@emph{encapsulating}, the VPN packet (though now encrypted) is
|
|
encapsulated in another IP datagram.
|
|
|
|
When the destination receives this packet, the same thing happens, only
|
|
in reverse. So it checks the message authentication code, decrypts the contents of the UDP datagram,
|
|
checks the sequence number
|
|
and writes the decrypted information to its own virtual network device.
|
|
|
|
If the virtual network device is a `tun' device (a point-to-point tunnel),
|
|
there is no problem for the kernel to accept a packet.
|
|
However, if it is a `tap' device (this is the only available type on FreeBSD),
|
|
the destination MAC address must match that of the virtual network interface.
|
|
If tinc is in it's default routing mode, ARP does not work, so the correct destination MAC
|
|
can not be known by the sending host.
|
|
Tinc solves this by letting the receiving end detect the MAC address of its own virtual network interface
|
|
and overwriting the destination MAC address of the received packet.
|
|
|
|
In switch or hub modes ARP does work so the sender already knows the correct destination MAC address.
|
|
In those modes every interface should have a unique MAC address, so make sure they are not the same.
|
|
Because switch and hub modes rely on MAC addresses to function correctly,
|
|
these modes cannot be used on the following operating systems which don't have a `tap' style virtual network device:
|
|
OpenBSD, NetBSD, Darwin and Solaris.
|
|
|
|
|
|
@c ==================================================================
|
|
@node The meta-connection
|
|
@subsection The meta-connection
|
|
|
|
Having only a UDP connection available is not enough. Though suitable
|
|
for transmitting data, we want to be able to reliably send other
|
|
information, such as routing and session key information to somebody.
|
|
|
|
@cindex TCP
|
|
TCP is a better alternative, because it already contains protection
|
|
against information being lost, unlike UDP.
|
|
|
|
So we establish two connections. One for the encrypted VPN data, and one
|
|
for other information, the meta-data. Hence, we call the second
|
|
connection the meta-connection. We can now be sure that the
|
|
meta-information doesn't get lost on the way to another computer.
|
|
|
|
@cindex data-protocol
|
|
@cindex meta-protocol
|
|
Like with any communication, we must have a protocol, so that everybody
|
|
knows what everything stands for, and how she should react. Because we
|
|
have two connections, we also have two protocols. The protocol used for
|
|
the UDP data is the ``data-protocol,'' the other one is the
|
|
``meta-protocol.''
|
|
|
|
The reason we don't use TCP for both protocols is that UDP is much
|
|
better for encapsulation, even while it is less reliable. The real
|
|
problem is that when TCP would be used to encapsulate a TCP stream
|
|
that's on the private network, for every packet sent there would be
|
|
three ACKs sent instead of just one. Furthermore, if there would be
|
|
a timeout, both TCP streams would sense the timeout, and both would
|
|
start re-sending packets.
|
|
|
|
|
|
@c ==================================================================
|
|
@node The meta-protocol
|
|
@section The meta-protocol
|
|
|
|
The meta protocol is used to tie all tinc daemons together, and
|
|
exchange information about which tinc daemon serves which virtual
|
|
subnet.
|
|
|
|
The meta protocol consists of requests that can be sent to the other
|
|
side. Each request has a unique number and several parameters. All
|
|
requests are represented in the standard ASCII character set. It is
|
|
possible to use tools such as telnet or netcat to connect to a tinc
|
|
daemon started with the --bypass-security option
|
|
and to read and write requests by hand, provided that one
|
|
understands the numeric codes sent.
|
|
|
|
The authentication scheme is described in @ref{Authentication protocol}. After a
|
|
successful authentication, the server and the client will exchange all the
|
|
information about other tinc daemons and subnets they know of, so that both
|
|
sides (and all the other tinc daemons behind them) have their information
|
|
synchronised.
|
|
|
|
@cindex ADD_EDGE
|
|
@cindex ADD_SUBNET
|
|
@example
|
|
message
|
|
------------------------------------------------------------------
|
|
ADD_EDGE node1 node2 21.32.43.54 655 222 0
|
|
| | | | | +-> options
|
|
| | | | +----> weight
|
|
| | | +--------> UDP port of node2
|
|
| | +----------------> real address of node2
|
|
| +-------------------------> name of destination node
|
|
+-------------------------------> name of source node
|
|
|
|
ADD_SUBNET node 192.168.1.0/24
|
|
| | +--> prefixlength
|
|
| +--------> network address
|
|
+------------------> owner of this subnet
|
|
------------------------------------------------------------------
|
|
@end example
|
|
|
|
The ADD_EDGE messages are to inform other tinc daemons that a connection between
|
|
two nodes exist. The address of the destination node is available so that
|
|
VPN packets can be sent directly to that node.
|
|
|
|
The ADD_SUBNET messages inform other tinc daemons that certain subnets belong
|
|
to certain nodes. tinc will use it to determine to which node a VPN packet has
|
|
to be sent.
|
|
|
|
@cindex DEL_EDGE
|
|
@cindex DEL_SUBNET
|
|
@example
|
|
message
|
|
------------------------------------------------------------------
|
|
DEL_EDGE node1 node2
|
|
| +----> name of destination node
|
|
+----------> name of source node
|
|
|
|
DEL_SUBNET node 192.168.1.0/24
|
|
| | +--> prefixlength
|
|
| +--------> network address
|
|
+------------------> owner of this subnet
|
|
------------------------------------------------------------------
|
|
@end example
|
|
|
|
In case a connection between two daemons is closed or broken, DEL_EDGE messages
|
|
are sent to inform the other daemons of that fact. Each daemon will calculate a
|
|
new route to the the daemons, or mark them unreachable if there isn't any.
|
|
|
|
@cindex REQ_KEY
|
|
@cindex ANS_KEY
|
|
@cindex KEY_CHANGED
|
|
@example
|
|
message
|
|
------------------------------------------------------------------
|
|
REQ_KEY origin destination
|
|
| +--> name of the tinc daemon it wants the key from
|
|
+----------> name of the daemon that wants the key
|
|
|
|
ANS_KEY origin destination 4ae0b0a82d6e0078 91 64 4
|
|
| | \______________/ | | +--> MAC length
|
|
| | | | +-----> digest algorithm
|
|
| | | +--------> cipher algorithm
|
|
| | +--> 128 bits key
|
|
| +--> name of the daemon that wants the key
|
|
+----------> name of the daemon that uses this key
|
|
|
|
KEY_CHANGED origin
|
|
+--> daemon that has changed it's packet key
|
|
------------------------------------------------------------------
|
|
@end example
|
|
|
|
The keys used to encrypt VPN packets are not sent out directly. This is
|
|
because it would generate a lot of traffic on VPNs with many daemons, and
|
|
chances are that not every tinc daemon will ever send a packet to every
|
|
other daemon. Instead, if a daemon needs a key it sends a request for it
|
|
via the meta connection of the nearest hop in the direction of the
|
|
destination.
|
|
|
|
@cindex PING
|
|
@cindex PONG
|
|
@example
|
|
daemon message
|
|
------------------------------------------------------------------
|
|
origin PING
|
|
dest. PONG
|
|
------------------------------------------------------------------
|
|
@end example
|
|
|
|
There is also a mechanism to check if hosts are still alive. Since network
|
|
failures or a crash can cause a daemon to be killed without properly
|
|
shutting down the TCP connection, this is necessary to keep an up to date
|
|
connection list. PINGs are sent at regular intervals, except when there
|
|
is also some other traffic. A little bit of salt (random data) is added
|
|
with each PING and PONG message, to make sure that long sequences of PING/PONG
|
|
messages without any other traffic won't result in known plaintext.
|
|
|
|
This basically covers what is sent over the meta connection by tinc.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Security
|
|
@section Security
|
|
|
|
@cindex TINC
|
|
@cindex Cabal
|
|
Tinc got its name from ``TINC,'' short for @emph{There Is No Cabal}; the
|
|
alleged Cabal was/is an organisation that was said to keep an eye on the
|
|
entire Internet. As this is exactly what you @emph{don't} want, we named
|
|
the tinc project after TINC.
|
|
|
|
@cindex SVPN
|
|
But in order to be ``immune'' to eavesdropping, you'll have to encrypt
|
|
your data. Because tinc is a @emph{Secure} VPN (SVPN) daemon, it does
|
|
exactly that: encrypt.
|
|
Tinc by default uses blowfish encryption with 128 bit keys in CBC mode, 32 bit
|
|
sequence numbers and 4 byte long message authentication codes to make sure
|
|
eavesdroppers cannot get and cannot change any information at all from the
|
|
packets they can intercept. The encryption algorithm and message authentication
|
|
algorithm can be changed in the configuration. The length of the message
|
|
authentication codes is also adjustable. The length of the key for the
|
|
encryption algorithm is always the default length used by OpenSSL.
|
|
|
|
@menu
|
|
* Authentication protocol::
|
|
* Encryption of network packets::
|
|
* Security issues::
|
|
@end menu
|
|
|
|
|
|
@c ==================================================================
|
|
@node Authentication protocol
|
|
@subsection Authentication protocol
|
|
|
|
@cindex authentication
|
|
A new scheme for authentication in tinc has been devised, which offers some
|
|
improvements over the protocol used in 1.0pre2 and 1.0pre3. Explanation is
|
|
below.
|
|
|
|
@cindex ID
|
|
@cindex META_KEY
|
|
@cindex CHALLENGE
|
|
@cindex CHAL_REPLY
|
|
@cindex ACK
|
|
@example
|
|
daemon message
|
|
--------------------------------------------------------------------------
|
|
client <attempts connection>
|
|
|
|
server <accepts connection>
|
|
|
|
client ID client 12
|
|
| +---> version
|
|
+-------> name of tinc daemon
|
|
|
|
server ID server 12
|
|
| +---> version
|
|
+-------> name of tinc daemon
|
|
|
|
client META_KEY 5f0823a93e35b69e...7086ec7866ce582b
|
|
\_________________________________/
|
|
+-> RSAKEYLEN bits totally random string S1,
|
|
encrypted with server's public RSA key
|
|
|
|
server META_KEY 6ab9c1640388f8f0...45d1a07f8a672630
|
|
\_________________________________/
|
|
+-> RSAKEYLEN bits totally random string S2,
|
|
encrypted with client's public RSA key
|
|
|
|
From now on:
|
|
- the client will symmetrically encrypt outgoing traffic using S1
|
|
- the server will symmetrically encrypt outgoing traffic using S2
|
|
|
|
client CHALLENGE da02add1817c1920989ba6ae2a49cecbda0
|
|
\_________________________________/
|
|
+-> CHALLEN bits totally random string H1
|
|
|
|
server CHALLENGE 57fb4b2ccd70d6bb35a64c142f47e61d57f
|
|
\_________________________________/
|
|
+-> CHALLEN bits totally random string H2
|
|
|
|
client CHAL_REPLY 816a86
|
|
+-> 160 bits SHA1 of H2
|
|
|
|
server CHAL_REPLY 928ffe
|
|
+-> 160 bits SHA1 of H1
|
|
|
|
After the correct challenge replies are received, both ends have proved
|
|
their identity. Further information is exchanged.
|
|
|
|
client ACK 655 123 0
|
|
| | +-> options
|
|
| +----> estimated weight
|
|
+--------> listening port of client
|
|
|
|
server ACK 655 321 0
|
|
| | +-> options
|
|
| +----> estimated weight
|
|
+--------> listening port of server
|
|
--------------------------------------------------------------------------
|
|
@end example
|
|
|
|
This new scheme has several improvements, both in efficiency and security.
|
|
|
|
First of all, the server sends exactly the same kind of messages over the wire
|
|
as the client. The previous versions of tinc first authenticated the client,
|
|
and then the server. This scheme even allows both sides to send their messages
|
|
simultaneously, there is no need to wait for the other to send something first.
|
|
This means that any calculations that need to be done upon sending or receiving
|
|
a message can also be done in parallel. This is especially important when doing
|
|
RSA encryption/decryption. Given that these calculations are the main part of
|
|
the CPU time spent for the authentication, speed is improved by a factor 2.
|
|
|
|
Second, only one RSA encrypted message is sent instead of two. This reduces the
|
|
amount of information attackers can see (and thus use for a cryptographic
|
|
attack). It also improves speed by a factor two, making the total speedup a
|
|
factor 4.
|
|
|
|
Third, and most important:
|
|
The symmetric cipher keys are exchanged first, the challenge is done
|
|
afterwards. In the previous authentication scheme, because a man-in-the-middle
|
|
could pass the challenge/chal_reply phase (by just copying the messages between
|
|
the two real tinc daemons), but no information was exchanged that was really
|
|
needed to read the rest of the messages, the challenge/chal_reply phase was of
|
|
no real use. The man-in-the-middle was only stopped by the fact that only after
|
|
the ACK messages were encrypted with the symmetric cipher. Potentially, it
|
|
could even send it's own symmetric key to the server (if it knew the server's
|
|
public key) and read some of the metadata the server would send it (it was
|
|
impossible for the mitm to read actual network packets though). The new scheme
|
|
however prevents this.
|
|
|
|
This new scheme makes sure that first of all, symmetric keys are exchanged. The
|
|
rest of the messages are then encrypted with the symmetric cipher. Then, each
|
|
side can only read received messages if they have their private key. The
|
|
challenge is there to let the other side know that the private key is really
|
|
known, because a challenge reply can only be sent back if the challenge is
|
|
decrypted correctly, and that can only be done with knowledge of the private
|
|
key.
|
|
|
|
Fourth: the first thing that is sent via the symmetric cipher encrypted
|
|
connection is a totally random string, so that there is no known plaintext (for
|
|
an attacker) in the beginning of the encrypted stream.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Encryption of network packets
|
|
@subsection Encryption of network packets
|
|
@cindex encryption
|
|
|
|
A data packet can only be sent if the encryption key is known to both
|
|
parties, and the connection is activated. If the encryption key is not
|
|
known, a request is sent to the destination using the meta connection
|
|
to retrieve it. The packet is stored in a queue while waiting for the
|
|
key to arrive.
|
|
|
|
@cindex UDP
|
|
The UDP packet containing the network packet from the VPN has the following layout:
|
|
|
|
@example
|
|
... | IP header | UDP header | seqno | VPN packet | MAC | UDP trailer
|
|
\___________________/\_____/
|
|
| |
|
|
V +---> digest algorithm
|
|
Encrypted with symmetric cipher
|
|
@end example
|
|
|
|
So, the entire VPN packet is encrypted using a symmetric cipher, including a 32 bits
|
|
sequence number that is added in front of the actual VPN packet, to act as a unique
|
|
IV for each packet and to prevent replay attacks. A message authentication code
|
|
is added to the UDP packet to prevent alteration of packets. By default the
|
|
first 4 bytes of the digest are used for this, but this can be changed using
|
|
the MACLength configuration variable.
|
|
|
|
@c ==================================================================
|
|
@node Security issues
|
|
@subsection Security issues
|
|
|
|
In August 2000, we discovered the existence of a security hole in all versions
|
|
of tinc up to and including 1.0pre2. This had to do with the way we exchanged
|
|
keys. Since then, we have been working on a new authentication scheme to make
|
|
tinc as secure as possible. The current version uses the OpenSSL library and
|
|
uses strong authentication with RSA keys.
|
|
|
|
On the 29th of December 2001, Jerome Etienne posted a security analysis of tinc
|
|
1.0pre4. Due to a lack of sequence numbers and a message authentication code
|
|
for each packet, an attacker could possibly disrupt certain network services or
|
|
launch a denial of service attack by replaying intercepted packets. The current
|
|
version adds sequence numbers and message authentication codes to prevent such
|
|
attacks.
|
|
|
|
On the 15th of September 2003, Peter Gutmann posted a security analysis of tinc
|
|
1.0.1. He argues that the 32 bit sequence number used by tinc is not a good IV,
|
|
that tinc's default length of 4 bytes for the MAC is too short, and he doesn't
|
|
like tinc's use of RSA during authentication. We do not know of a security hole
|
|
in this version of tinc, but tinc's security is not as strong as TLS or IPsec.
|
|
We will address these issues in tinc 2.0.
|
|
|
|
Cryptography is a hard thing to get right. We cannot make any
|
|
guarantees. Time, review and feedback are the only things that can
|
|
prove the security of any cryptographic product. If you wish to review
|
|
tinc or give us feedback, you are stronly encouraged to do so.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Platform specific information
|
|
@chapter Platform specific information
|
|
|
|
@menu
|
|
* Interface configuration::
|
|
* Routes::
|
|
@end menu
|
|
|
|
@c ==================================================================
|
|
@node Interface configuration
|
|
@section Interface configuration
|
|
|
|
When configuring an interface, one normally assigns it an address and a
|
|
netmask. The address uniquely identifies the host on the network attached to
|
|
the interface. The netmask, combined with the address, forms a subnet. It is
|
|
used to add a route to the routing table instructing the kernel to send all
|
|
packets which fall into that subnet to that interface. Because all packets for
|
|
the entire VPN should go to the virtual network interface used by tinc, the
|
|
netmask should be such that it encompasses the entire VPN.
|
|
|
|
For IPv4 addresses:
|
|
|
|
@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
|
|
@item Linux
|
|
@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
|
|
@item Linux iproute2
|
|
@tab @code{ip addr add} @var{address}@code{/}@var{prefixlength} @code{dev} @var{interface}
|
|
@item FreeBSD
|
|
@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
|
|
@item OpenBSD
|
|
@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
|
|
@item NetBSD
|
|
@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
|
|
@item Solaris
|
|
@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
|
|
@item Darwin (MacOS/X)
|
|
@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
|
|
@item Windows
|
|
@tab @code{netsh interface ip set address} @var{interface} @code{static} @var{address} @var{netmask}
|
|
@end multitable
|
|
|
|
For IPv6 addresses:
|
|
|
|
@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
|
|
@item Linux
|
|
@tab @code{ifconfig} @var{interface} @code{add} @var{address}@code{/}@var{prefixlength}
|
|
@item FreeBSD
|
|
@tab @code{ifconfig} @var{interface} @code{inet6} @var{address} @code{prefixlen} @var{prefixlength}
|
|
@item OpenBSD
|
|
@tab @code{ifconfig} @var{interface} @code{inet6} @var{address} @code{prefixlen} @var{prefixlength}
|
|
@item NetBSD
|
|
@tab @code{ifconfig} @var{interface} @code{inet6} @var{address} @code{prefixlen} @var{prefixlength}
|
|
@item Solaris
|
|
@tab @code{ifconfig} @var{interface} @code{inet6 plumb up}
|
|
@item
|
|
@tab @code{ifconfig} @var{interface} @code{inet6 addif} @var{address} @var{address}
|
|
@item Darwin (MacOS/X)
|
|
@tab @code{ifconfig} @var{interface} @code{inet6} @var{address} @code{prefixlen} @var{prefixlength}
|
|
@item Windows
|
|
@tab @code{netsh interface ipv6 add address} @var{interface} @code{static} @var{address}/@var{prefixlength}
|
|
@end multitable
|
|
|
|
On some platforms, when running tinc in switch mode, the VPN interface must be set to tap mode with an ifconfig command:
|
|
|
|
@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
|
|
@item OpenBSD
|
|
@tab @code{ifconfig} @var{interface} @code{link0}
|
|
@end multitable
|
|
|
|
On Linux, it is possible to create a persistent tun/tap interface which will
|
|
continue to exist even if tinc quit, although this is normally not required.
|
|
It can be useful to set up a tun/tap interface owned by a non-root user, so
|
|
tinc can be started without needing any root privileges at all.
|
|
|
|
@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
|
|
@item Linux
|
|
@tab @code{ip tuntap add dev} @var{interface} @code{mode} @var{tun|tap} @code{user} @var{username}
|
|
@end multitable
|
|
|
|
@c ==================================================================
|
|
@node Routes
|
|
@section Routes
|
|
|
|
In some cases it might be necessary to add more routes to the virtual network
|
|
interface. There are two ways to indicate which interface a packet should go
|
|
to, one is to use the name of the interface itself, another way is to specify
|
|
the (local) address that is assigned to that interface (@var{local_address}). The
|
|
former way is unambiguous and therefore preferable, but not all platforms
|
|
support this.
|
|
|
|
Adding routes to IPv4 subnets:
|
|
|
|
@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
|
|
@item Linux
|
|
@tab @code{route add -net} @var{network_address} @code{netmask} @var{netmask} @var{interface}
|
|
@item Linux iproute2
|
|
@tab @code{ip route add} @var{network_address}@code{/}@var{prefixlength} @code{dev} @var{interface}
|
|
@item FreeBSD
|
|
@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address}
|
|
@item OpenBSD
|
|
@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address}
|
|
@item NetBSD
|
|
@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address}
|
|
@item Solaris
|
|
@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address} @code{-interface}
|
|
@item Darwin (MacOS/X)
|
|
@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address}
|
|
@item Windows
|
|
@tab @code{netsh routing ip add persistentroute} @var{network_address} @var{netmask} @var{interface} @var{local_address}
|
|
@end multitable
|
|
|
|
Adding routes to IPv6 subnets:
|
|
|
|
@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
|
|
@item Linux
|
|
@tab @code{route add -A inet6} @var{network_address}@code{/}@var{prefixlength} @var{interface}
|
|
@item Linux iproute2
|
|
@tab @code{ip route add} @var{network_address}@code{/}@var{prefixlength} @code{dev} @var{interface}
|
|
@item FreeBSD
|
|
@tab @code{route add -inet6} @var{network_address}@code{/}@var{prefixlength} @var{local_address}
|
|
@item OpenBSD
|
|
@tab @code{route add -inet6} @var{network_address} @var{local_address} @code{-prefixlen} @var{prefixlength}
|
|
@item NetBSD
|
|
@tab @code{route add -inet6} @var{network_address} @var{local_address} @code{-prefixlen} @var{prefixlength}
|
|
@item Solaris
|
|
@tab @code{route add -inet6} @var{network_address}@code{/}@var{prefixlength} @var{local_address} @code{-interface}
|
|
@item Darwin (MacOS/X)
|
|
@tab ?
|
|
@item Windows
|
|
@tab @code{netsh interface ipv6 add route} @var{network address}/@var{prefixlength} @var{interface}
|
|
@end multitable
|
|
|
|
|
|
@c ==================================================================
|
|
@node About us
|
|
@chapter About us
|
|
|
|
|
|
@menu
|
|
* Contact information::
|
|
* Authors::
|
|
@end menu
|
|
|
|
|
|
@c ==================================================================
|
|
@node Contact information
|
|
@section Contact information
|
|
|
|
@cindex website
|
|
Tinc's website is at @url{http://www.tinc-vpn.org/},
|
|
this server is located in the Netherlands.
|
|
|
|
@cindex IRC
|
|
We have an IRC channel on the FreeNode and OFTC IRC networks. Connect to
|
|
@uref{http://www.freenode.net/, irc.freenode.net}
|
|
or
|
|
@uref{http://www.oftc.net/, irc.oftc.net}
|
|
and join channel #tinc.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Authors
|
|
@section Authors
|
|
|
|
@table @asis
|
|
@item Ivo Timmermans (zarq)
|
|
@item Guus Sliepen (guus) (@email{guus@@tinc-vpn.org})
|
|
@end table
|
|
|
|
We have received a lot of valuable input from users. With their help,
|
|
tinc has become the flexible and robust tool that it is today. We have
|
|
composed a list of contributions, in the file called @file{THANKS} in
|
|
the source distribution.
|
|
|
|
|
|
@c ==================================================================
|
|
@node Concept Index
|
|
@unnumbered Concept Index
|
|
|
|
@c ==================================================================
|
|
@printindex cp
|
|
|
|
|
|
@c ==================================================================
|
|
@contents
|
|
@bye
|