diff --git a/COPYING b/COPYING index 85c729f..f4dd065 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 1998-2012 Ivo Timmermans, Guus Sliepen and others. +Copyright (C) 1998-2013 Ivo Timmermans, Guus Sliepen and others. See the AUTHORS file for a complete list. This program is free software; you can redistribute it and/or modify it under diff --git a/ChangeLog b/ChangeLog index 2d8d985..01a1494 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +Version 1.1pre7 April 22 2013 +------------------------------------------------------------------------ + +Guus Sliepen (12): + Use UDP when using sptps_test in datagram mode. + Flush output buffers in the tap reader thread on Windows. + Better default output file for generated public keys. + Allow changing configuration with tincctl without the "config" keyword. + Avoid calling time(NULL). + Include README.android in the tarballs. + Rename tincctl to tinc. + Remove references to the config keyword. + Describe the SPTPS protocol in the manual. + Fix completion of add/del/get/set commands. + Drop packets forwarded via TCP if they are too big (CVE-2013-1428). + Releasing 1.1pre7. + Version 1.1pre6 February 20 2013 ------------------------------------------------------------------------ diff --git a/Makefile.am b/Makefile.am index e37864d..130cd6e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6,7 +6,7 @@ SUBDIRS = m4 src doc gui ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = have.h system.h COPYING.README +EXTRA_DIST = have.h system.h COPYING.README README.android ChangeLog: git log > ChangeLog diff --git a/Makefile.in b/Makefile.in index 657ca58..5ae644b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -236,7 +236,7 @@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = gnu SUBDIRS = m4 src doc gui ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = have.h system.h COPYING.README +EXTRA_DIST = have.h system.h COPYING.README README.android all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive diff --git a/NEWS b/NEWS index a6e13d8..960b85c 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,17 @@ +Version 1.1pre7 April 22 2013 + + * Fixed large latencies on Windows. + + * Renamed the tincctl tool to tinc. + + * Simplified changing the configuration using the tinc tool. + + * Added a full description of the ExperimentalProtocol to the manual. + + * Drop packets forwarded via TCP if they are too big (CVE-2013-1428). + +Thanks to Martin Schobert for auditing tinc and reporting the vulnerability. + Version 1.1pre6 February 20 2013 * Fixed tincd exitting immediately on Windows. diff --git a/README b/README index 0709fb8..3267829 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -This is the README file for tinc version 1.1pre6. Installation +This is the README file for tinc version 1.1pre7. Installation instructions may be found in the INSTALL file. tinc is Copyright (C) 1998-2013 by: @@ -22,7 +22,7 @@ Please note that this is NOT a stable release. Until version 1.1.0 is released, please use one of the 1.0.x versions if you need a stable version of tinc. Although tinc 1.1 will be protocol compatible with tinc 1.0.x, the -functionality of the tincctl program may still change, and the control socket +functionality of the tinc program may still change, and the control socket protocol is not fixed yet. @@ -36,11 +36,11 @@ at your own risk. Compatibility ------------- -Version 1.1pre6 is compatible with 1.0pre8, 1.0 and later, but not with older +Version 1.1pre7 is compatible with 1.0pre8, 1.0 and later, but not with older versions of tinc. When the ExperimentalProtocol option is used, tinc is still compatible with -1.0.X and 1.1pre6 itself, but not with any other 1.1preX version. +1.0.X and 1.1pre7 itself, but not with any other 1.1preX version. Requirements @@ -88,6 +88,6 @@ Windows environment this means tinc will intall itself as a service, which will restart after reboots. To prevent tinc from detaching or running as a service, use the -D option. -The status of the VPN can be queried using the "tincctl" tool, which connects +The status of the VPN can be queried using the "tinc" command, which connects to a running tinc daemon via a control connection. The same tool also makes it easy to start and stop tinc, and to change its configuration. diff --git a/README.android b/README.android new file mode 100644 index 0000000..6fffe41 --- /dev/null +++ b/README.android @@ -0,0 +1,20 @@ +Quick how-o cross compile tinc for android (done from $HOME/android/): + +- Download android NDK and setup local ARM toolchain: +wget http://dl.google.com/android/ndk/android-ndk-r8b-linux-x86.tar.bz2 +tar xfj android-ndk-r8b-linux-x86.tar.bz2 +./android-ndk-r8b/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain + +- Download and cross-compile openSSL for ARM: +wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz +tar xfz openssl-1.0.1c.tar.gz +cd openssl-1.0.1c +./Configure dist +make CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc AR="/tmp/my-android-toolchain/bin/arm-linux-androideabi-ar r" RANLIB=/tmp/my-android-toolchain/bin/arm-linux-androideabi-ranlib + +- Clone and cross-compile tinc: +git clone git://tinc-vpn.org/tinc +cd tinc +autoreconf -fsi +CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc ./configure --host=arm-linux --disable-lzo --with-openssl-lib=$HOME/android/openssl-1.0.1c --with-openssl-include=$HOME/android/openssl-1.0.1c/include/ +make -j5 diff --git a/THANKS b/THANKS index 1f2f73c..040f33d 100644 --- a/THANKS +++ b/THANKS @@ -30,6 +30,7 @@ We would like to thank the following people for their contributions to tinc: * Mark Glines * Markus Goetz * Martin Kihlgren +* Martin Schobert * Martin Schürrer * Matias Carrasco * Max Rijevski diff --git a/configure b/configure index 86d7e70..8c3051f 100755 --- a/configure +++ b/configure @@ -4095,7 +4095,7 @@ fi # Define the identity of the package. PACKAGE=tinc - VERSION=1.1pre6 + VERSION=1.1pre7 cat >>confdefs.h <<_ACEOF diff --git a/configure.in b/configure.in index f2ec3bd..a59482a 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ AC_PREREQ(2.61) AC_INIT AC_CONFIG_SRCDIR([src/tincd.c]) AC_GNU_SOURCE -AM_INIT_AUTOMAKE(tinc, 1.1pre6) +AM_INIT_AUTOMAKE(tinc, 1.1pre7) AC_CONFIG_HEADERS([config.h]) AM_MAINTAINER_MODE diff --git a/doc/Makefile.am b/doc/Makefile.am index 2ada5d7..9540b49 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -2,11 +2,11 @@ info_TEXINFOS = tinc.texi -man_MANS = tincd.8 tincctl.8 tinc.conf.5 tinc-gui.8 +man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 -EXTRA_DIST = tincinclude.texi.in tincd.8.in tincctl.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz +EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz -CLEANFILES = *.html tinc.info tincd.8 tincctl.8 tinc.conf.5 tinc-gui.8 tincinclude.texi +CLEANFILES = *.html tinc.info tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi # Use `ginstall' in the definition of man_MANS to avoid # confusion with the `install' target. The install rule transforms `ginstall' @@ -25,7 +25,7 @@ texi2html: tinc.texi tincd.8.html: tincd.8 w3mman2html $? > $@ -tincctl.8.html: tincctl.8 +tinc.8.html: tinc.8 w3mman2html $? > $@ tinc-gui.8.html: tinc-gui.8 @@ -43,7 +43,7 @@ substitute = sed \ tincd.8: tincd.8.in $(substitute) $? > $@ -tincctl.8: tincctl.8.in +tinc.8: tinc.8.in $(substitute) $? > $@ tinc-gui.8: tinc-gui.8.in diff --git a/doc/Makefile.in b/doc/Makefile.in index 3212126..b95f19c 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -224,9 +224,9 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ info_TEXINFOS = tinc.texi -man_MANS = tincd.8 tincctl.8 tinc.conf.5 tinc-gui.8 -EXTRA_DIST = tincinclude.texi.in tincd.8.in tincctl.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz -CLEANFILES = *.html tinc.info tincd.8 tincctl.8 tinc.conf.5 tinc-gui.8 tincinclude.texi +man_MANS = tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 +EXTRA_DIST = tincinclude.texi.in tincd.8.in tinc.8.in tinc.conf.5.in tinc-gui.8.in sample-config.tar.gz +CLEANFILES = *.html tinc.info tincd.8 tinc.8 tinc.conf.5 tinc-gui.8 tincinclude.texi substitute = sed \ -e s,'@PACKAGE\@',"$(PACKAGE)",g \ -e s,'@VERSION\@',"$(VERSION)",g \ @@ -772,7 +772,7 @@ texi2html: tinc.texi tincd.8.html: tincd.8 w3mman2html $? > $@ -tincctl.8.html: tincctl.8 +tinc.8.html: tinc.8 w3mman2html $? > $@ tinc-gui.8.html: tinc-gui.8 @@ -784,7 +784,7 @@ tinc.conf.5.html: tinc.conf.5 tincd.8: tincd.8.in $(substitute) $? > $@ -tincctl.8: tincctl.8.in +tinc.8: tinc.8.in $(substitute) $? > $@ tinc-gui.8: tinc-gui.8.in diff --git a/doc/tincctl.8.in b/doc/tinc.8.in similarity index 93% rename from doc/tincctl.8.in rename to doc/tinc.8.in index e530116..fba373e 100644 --- a/doc/tincctl.8.in +++ b/doc/tinc.8.in @@ -3,7 +3,7 @@ .\" Manual page created by: .\" Scott Lamb .Sh NAME -.Nm tincctl +.Nm tinc .Nd tinc VPN control .Sh SYNOPSIS .Nm @@ -51,12 +51,12 @@ Create initial configuration files and RSA and ECDSA keypairs with default lengt If no .Ar name for this node is given, it will be asked for. -.It config Oo get Oc Ar variable +.It get Ar variable Print the current value of configuration variable .Ar variable . If more than one variable with the same name exists, the value of each of them will be printed on a separate line. -.It config Oo set Oc Ar variable Ar value +.It set Ar variable Ar value Set configuration variable .Ar variable to the given @@ -64,9 +64,9 @@ to the given All previously existing configuration variables with the same name are removed. To set a variable for a specific host, use the notation .Ar host Ns Li . Ns Ar variable . -.It config add Ar variable Ar value +.It add Ar variable Ar value As above, but without removing any previously existing configuration variables. -.It config del Ar variable Op Ar value +.It del Ar variable Op Ar value Remove configuration variables with the same name and .Ar value . If no @@ -147,7 +147,7 @@ Sets debug level to .It log Op Ar N 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 -.Nm tincctl . +.Nm tinc . .It retry Forces .Xr tincd 8 @@ -182,19 +182,19 @@ such as .Sh EXAMPLES Examples of some commands: .Bd -literal -offset indent -tincctl -n vpn dump graph | circo -Txlib -tincctl -n vpn pcap | tcpdump -r - -tincctl -n vpn top +tinc -n vpn dump graph | circo -Txlib +tinc -n vpn pcap | tcpdump -r - +tinc -n vpn top .Pp .Ed Example of configuring tinc using .Nm : .Bd -literal -offset indent -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 +tinc -n vpn init foo +tinc -n vpn add Subnet 192.168.1.0/24 +tinc -n vpn add bar.Address bar.example.com +tinc -n vpn add ConnectTo bar +tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com .Ed .Sh TOP The top command connects to a running tinc daemon and repeatedly queries its per-node traffic counters. diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 38a4c11..1cca366 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -55,15 +55,15 @@ However, you are only allowed to use alphanumerical characters (a-z, A-Z, and 0- .Sh INITIAL CONFIGURATION If you have not configured tinc yet, you can easily create a basic configuration using the following command: .Bd -literal -offset indent -.Nm tincctl Fl n Ar NETNAME Li init Ar NAME +.Nm tinc Fl n Ar NETNAME Li init Ar NAME .Ed .Pp You can further change the configuration as needed either by manually editing the configuration files, or by using -.Xr tincctl 8 . +.Xr tinc 8 . .Sh PUBLIC/PRIVATE KEYS The -.Nm tincctl Li init +.Nm tinc Li init command will have generated both RSA and ECDSA public/private keypairs. The private keys should be stored in files named .Pa rsa_key.priv @@ -77,7 +77,7 @@ The RSA keys are used for backwards compatibility with tinc version 1.0. If you are upgrading from version 1.0 to 1.1, you can keep the old configuration files, but you will need to create ECDSA keys using the following command: .Bd -literal -offset indent -.Nm tincctl Fl n Ar NETNAME Li generate-ecdsa-keys +.Nm tinc Fl n Ar NETNAME Li generate-ecdsa-keys .Ed .Sh SERVER CONFIGURATION The server configuration of the daemon is done in the file @@ -102,7 +102,7 @@ it is recommended to put host specific configuration options in the host configu as this makes it easy to exchange with other nodes. .Pp You can edit the config file manually, but it is recommended that you use -.Xr tincctl 8 +.Xr tinc 8 to change configuration variables for you. .Pp Here are all valid variables, listed in alphabetical order. @@ -279,7 +279,7 @@ 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 -.Nm tincctl generate-ecdsa-keys . +.Nm tinc 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. .It Va Forwarding Li = off | internal | kernel Po internal Pc Bq experimental @@ -482,6 +482,8 @@ Furthermore, specifying .Qq none will turn off packet encryption. It is best to use only those ciphers which support CBC mode. +This option has no effect for connections between nodes using +.Va ExperimentalProtocol . .It Va ClampMSS Li = yes | no Pq 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 @@ -496,6 +498,8 @@ Any digest supported by OpenSSL is recognised. Furthermore, specifying .Qq none will turn off packet authentication. +This option has no effect for connections between nodes using +.Va ExperimentalProtocol . .It Va IndirectData Li = yes | no Pq 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. @@ -505,6 +509,8 @@ The length of the message authentication code used to authenticate UDP packets. Can be anything from .Qq 0 up to the length of the digest produced by the digest algorithm. +This option has no effect for connections between nodes using +.Va ExperimentalProtocol . .It Va PMTU Li = Ar mtu Po 1514 Pc This option controls the initial path MTU to this node. .It Va PMTUDiscovery Li = yes | no Po yes Pc @@ -653,7 +659,7 @@ its connection to the virtual network device. .El .Sh SEE ALSO .Xr tincd 8 , -.Xr tincctl 8 , +.Xr tinc 8 , .Pa http://www.tinc-vpn.org/ , .Pa http://www.tldp.org/LDP/nag2/ . .Pp diff --git a/doc/tinc.info b/doc/tinc.info index 690527a..f46a430 100644 --- a/doc/tinc.info +++ b/doc/tinc.info @@ -5,7 +5,7 @@ START-INFO-DIR-ENTRY * tinc: (tinc). The tinc Manual. END-INFO-DIR-ENTRY - This is the info manual for tinc version 1.1pre5, a Virtual Private + This is the info manual for tinc version 1.1pre7, a Virtual Private Network daemon. Copyright (C) 1998-2013 Ivo Timmermans, Guus Sliepen @@ -49,13 +49,13 @@ 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 +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 +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: @@ -74,15 +74,15 @@ 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. - 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 _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 +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 _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. - This problem can be solved by using _virtual_ networks. Virtual +This problem can be solved by using _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 @@ -90,14 +90,14 @@ 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 +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. +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.  File: tinc.info, Node: tinc, Next: Supported platforms, Prev: Virtual Private Networks, Up: Introduction @@ -111,26 +111,26 @@ 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. +Since then, a lot has changed--to say the least. - Tinc now supports encryption, it consists of a single daemon (tincd) -for both the receiving and sending end, it has become largely +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. - 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. +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 +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 +Meanwhile, we're always open-minded towards new ideas. And we're available too.  @@ -147,8 +147,8 @@ 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. - For an up to date list of supported platforms, please check the list -on our website: `http://www.tinc-vpn.org/platforms/'. +For an up to date list of supported platforms, please check the list on +our website: `http://www.tinc-vpn.org/platforms/'.  File: tinc.info, Node: Preparations, Next: Installation, Prev: Introduction, Up: Top @@ -195,11 +195,11 @@ Here are the options you have to turn on when configuring a new kernel: Network device support Universal tun/tap device driver support - It's not necessary to compile this driver as a module, even if you -are going to run more than one instance of tinc. +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 `/etc/modules.conf': +If you decide to build the tun/tap driver as a kernel module, add these +lines to `/etc/modules.conf': alias char-major-10-200 tun @@ -236,7 +236,7 @@ File: tinc.info, Node: Configuration of NetBSD kernels, Next: Configuration of 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. +Tunneling IPv6 may not work on NetBSD's tun device.  File: tinc.info, Node: Configuration of Solaris kernels, Next: Configuration of Darwin (MacOS/X) kernels, Prev: Configuration of NetBSD kernels, Up: Configuring the kernel @@ -307,23 +307,23 @@ File: tinc.info, Node: OpenSSL, Next: zlib, Up: Libraries 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 _may_ be added in the future. +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 _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. +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 +If you have to install OpenSSL manually, you can get the source code from `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. +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. --with-openssl=DIR OpenSSL library and headers prefix --with-openssl-include=DIR OpenSSL headers directory @@ -346,8 +346,8 @@ everyone to create a statically or dynamically linked executable: allowed. You may provide binary packages linked to the OpenSSL libraries, provided that all other requirements of the GPL are met. - Since the LZO library used by tinc is also covered by the GPL, we -also present the following exemption: +Since the LZO library used by tinc is also covered by the GPL, we also +present the following exemption: Hereby I grant a special exception to the tinc VPN project (http://www.tinc-vpn.org/) to link the LZO library with the @@ -364,22 +364,21 @@ File: tinc.info, Node: zlib, Next: lzo, Prev: OpenSSL, Up: Libraries 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. +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. +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 `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). +If you have to install zlib manually, you can get the source code from +`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).  File: tinc.info, Node: lzo, Next: libcurses, Prev: zlib, Up: Libraries @@ -389,20 +388,20 @@ File: tinc.info, Node: lzo, Next: libcurses, Prev: zlib, Up: Libraries 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 +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. +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 `http://www.oberhumer.com/opensource/lzo/'. Instructions on how -to configure, build and install this package are included within the +If you have to install lzo manually, you can get the source code from +`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). @@ -412,21 +411,21 @@ File: tinc.info, Node: libcurses, Next: libreadline, Prev: lzo, Up: Librarie 2.2.4 libcurses --------------- -For the "tincctl top" command, tinc requires a curses library. +For the "tinc 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. +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" (`http://invisible-island.net/ncurses/'), however -other curses libraries should also work. In particular, "PDCurses" +There are several curses libraries. It is recommended that you install +"ncurses" (`http://invisible-island.net/ncurses/'), however other +curses libraries should also work. In particular, "PDCurses" (`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 +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.  @@ -435,20 +434,19 @@ File: tinc.info, Node: libreadline, Prev: libcurses, Up: Libraries 2.2.5 libreadline ----------------- -For the "tincctl" command's shell functionality, tinc uses the readline +For the "tinc" 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. +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. +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 +If you have to install libreadline manually, you can get the source code from `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 @@ -464,15 +462,15 @@ 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 +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 download page (http://www.tinc-vpn.org/download/), 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 +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 `INSTALL', which is included in the source distribution. @@ -490,10 +488,10 @@ File: tinc.info, Node: Building and installing tinc, Next: System files, Up: Detailed instructions on configuring the source, building tinc and installing tinc can be found in the file called `INSTALL'. - 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. +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: @@ -512,7 +510,7 @@ Developer Tools from `http://developer.apple.com/tools/macosxtools.html' and a recent version of Fink from `http://www.finkproject.org/'. - After installation use fink to download and install the following +After installation use fink to download and install the following packages: autoconf25, automake, dlcompat, m4, openssl, zlib and lzo.  @@ -524,7 +522,7 @@ File: tinc.info, Node: Cygwin (Windows) build environment, Next: MinGW (Window If Cygwin hasn't already been installed, install it directly from `http://www.cygwin.com/'. - When tinc is compiled in a Cygwin environment, it can only be run in +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. @@ -538,10 +536,10 @@ File: tinc.info, Node: MinGW (Windows) build environment, Prev: Cygwin (Window You will need to install the MinGW environment from `http://www.mingw.org'. - When tinc is compiled using MinGW it runs natively under Windows, it -is not necessary to keep MinGW installed. +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 +When detaching, tinc will install itself as a service, which will be restarted automatically after reboots.  @@ -567,8 +565,8 @@ File: tinc.info, Node: Device files, Next: Other files, Up: System 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: +If you use Linux and do not have udev installed, you may need to create +the following device file if it does not exist: mknod -m 600 /dev/net/tun c 10 200 @@ -630,17 +628,17 @@ documentation. Make sure you have an adequate understanding of networks in general. A good resource on networking is the Linux Network Administrators Guide (http://www.tldp.org/LDP/nag2/). - If you have everything clearly pictured in your mind, proceed in the +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: - tincctl -n NETNAME init NAME - Second, use `tincctl -n NETNAME config ...' to further configure -tinc. Finally, export your host configuration file using `tincctl -n -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 `tincctl -n NETNAME import'. + tinc -n NETNAME init NAME +Second, use `tinc -n NETNAME add ...' to further configure tinc. +Finally, export your host configuration file using `tinc -n 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 `tinc -n NETNAME import'. - These steps are described in the subsections below. +These steps are described in the subsections below.  File: tinc.info, Node: Multiple networks, Next: How connections work, Prev: Configuration introduction, Up: Configuration @@ -654,18 +652,17 @@ assign a 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. +We will asume you use a netname throughout this document. This means +that you call tinc with the -n argument, which will specify the netname. - The effect of this option is that tinc will set its configuration -root to `/etc/tinc/NETNAME/', where NETNAME is your argument to the -n +The effect of this option is that tinc will set its configuration root +to `/etc/tinc/NETNAME/', where NETNAME is your argument to the -n option. You will also notice that log messages it appears in syslog as coming from `tinc.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 +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 `/etc/tinc/' instead of `/etc/tinc/NETNAME/'; the configuration file will then be @@ -690,23 +687,23 @@ 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. - 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 +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 `ConnectTo = B' in its -tinc.conf file, and C has `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 `ConnectTo = C' in its tinc.conf file. +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 `ConnectTo = B' in its tinc.conf file, and C has +`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 `ConnectTo = C' in its tinc.conf file. - It could be that some daemons are located behind a Network Address +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 @@ -715,9 +712,9 @@ 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. +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.  File: tinc.info, Node: Configuration files, Next: Network interfaces, Prev: How connections work, Up: Configuration @@ -729,28 +726,27 @@ The actual configuration of the daemon is done in the file `/etc/tinc/NETNAME/tinc.conf' and at least one other file in the directory `/etc/tinc/NETNAME/hosts/'. - These file consists of comments (lines started with a #) or -assignments in the form of +These file consists of comments (lines started with a #) or assignments +in the form of Variable = Value. - 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 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 +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 `/etc/tinc/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. +You can edit the config file manually, but it is recommended that you +use the tinc command to change configuration variables for you. - In the following two subsections all valid variables are listed in +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. @@ -929,10 +925,10 @@ ExperimentalProtocol = (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 - `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. + enabled, an ECDSA key must have been generated before with `tinc + 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. Forwarding = (internal) [experimental] This option selects the way indirect packets are forwarded. @@ -1056,8 +1052,8 @@ PrivateKey = [obsolete] PrivateKeyFile = (`/etc/tinc/NETNAME/rsa_key.priv') This is the full path name of the RSA private key file that was - generated by `tincctl generate-keys'. It must be a full path, not - a relative directory. + generated by `tinc generate-keys'. It must be a full path, not a + relative directory. ProcessPriority = When this option is used the priority of the tincd process will be @@ -1134,10 +1130,12 @@ Address = [] [recommended] port is specified, the default Port is used. 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. + The symmetric cipher algorithm used to encrypt UDP packets using + the legacy protocol. 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. This option has no effect for connections using the + SPTPS protocol, which always use AES-256-CTR. ClampMSS = (yes) This option specifies whether tinc should clamp the maximum @@ -1151,9 +1149,11 @@ Compression = (0) (best zlib), 10 (fast lzo) and 11 (best lzo). 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. + The digest algorithm used to authenticate UDP packets using the + legacy protocol. Any digest supported by OpenSSL is recognized. + Furthermore, specifying "none" will turn off packet authentication. + This option has no effect for connections using the SPTPS + protocol, which always use HMAC-SHA-256. IndirectData = (no) When set to yes, other nodes which do not already have a meta @@ -1162,8 +1162,10 @@ IndirectData = (no) MACLength = (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. + UDP packets using the legacy protocol. Can be anything from 0 up + to the length of the digest produced by the digest algorithm. + This option has no effect for connections using the SPTPS + protocol, which never truncate MACs. PMTU = (1514) This option controls the initial path MTU to this node. @@ -1182,8 +1184,8 @@ PublicKey = [obsolete] PublicKeyFile = [obsolete] This is the full path name of the RSA public key file that was - generated by `tincctl generate-keys'. It must be a full path, not - a relative directory. + generated by `tinc generate-keys'. It must be a full path, not a + relative directory. From version 1.0pre4 on tinc will store the public key directly into the host configuration file in PEM format, the above two @@ -1272,7 +1274,7 @@ scripts should have the extension .bat. `/etc/tinc/NETNAME/subnet-down' This script is started when a Subnet becomes unreachable. - The scripts are started without command line arguments, but can make +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 `.bat' files, they have to be put between % @@ -1319,24 +1321,24 @@ Step 1. Creating initial configuration files. The initial directory structure, configuration files and public/private keypairs are created using the following command: - tincctl -n NETNAME init NAME + tinc -n NETNAME init NAME - (You will need to run this as root, or use "sudo".) This will -create the configuration directory `/etc/tinc/NETNAME.', and inside it -will create another directory named `hosts/'. In the configuration +(You will need to run this as root, or use "sudo".) This will create +the configuration directory `/etc/tinc/NETNAME.', and inside it will +create another directory named `hosts/'. In the configuration directory, it will create the file `tinc.conf' with the following contents: Name = NAME - It will also create private RSA and ECDSA keys, which will be stored -in the files `rsa_key.priv' and `ecdsa_key.priv'. It will also create -a host configuration file `hosts/NAME', which will contain the +It will also create private RSA and ECDSA keys, which will be stored in +the files `rsa_key.priv' and `ecdsa_key.priv'. It will also create a +host configuration file `hosts/NAME', which will contain the corresponding public RSA and ECDSA keys. - Finally, on UNIX operating systems, it will create an executable -script `tinc-up', which will initially not do anything except warning -that you should edit it. +Finally, on UNIX operating systems, it will create an executable script +`tinc-up', which will initially not do anything except warning that you +should edit it. Step 2. Modifying the initial configuration. ............................................. @@ -1347,40 +1349,39 @@ 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: - tincctl -n NETNAME config add subnet 192.168.2.0/24 + tinc -n NETNAME add subnet 192.168.2.0/24 - This will add a Subnet statement to your host configuration file. -Try opening the file `/etc/tinc/NETNAME/hosts/NAME' in an editor. You +This will add a Subnet statement to your host configuration file. Try +opening the file `/etc/tinc/NETNAME/hosts/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: Subnet = 192.168.2.0/24 - 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: +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: - tincctl -n NETNAME config add subnet fec0:0:0:2::/24 + tinc -n NETNAME add subnet fec0:0:0:2::/24 - This will add another line to the file `hosts/NAME'. If you make a -mistake, you can undo it by simply using `config del' instead of -`config add'. +This will add another line to the file `hosts/NAME'. If you make a +mistake, you can undo it by simply using `del' instead of `add'. - If you want other tinc daemons to create meta-connections to your +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: - tincctl -n NETNAME config add address foo.example.org + tinc -n NETNAME add address foo.example.org - If you already know to which daemons your daemon should make +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: - tincctl -n NETNAME config add connectto bar + tinc -n NETNAME add connectto bar - Note that you specify the Name of the other daemon here, not an IP +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 `hosts/bar', and will read Address statements and public keys from that @@ -1397,29 +1398,29 @@ 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): - tincctl -n NETNAME export | mail -s "My config file" bar@example.org + tinc -n NETNAME export | mail -s "My config file" bar@example.org - 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: +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: - tincctl -n NETNAME import + tinc -n NETNAME import - 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 +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: - tincctl -n NETNAME export \ - | ssh bar.example.org tincctl -n NETNAME exchange \ - | tincctl -n NETNAME import + tinc -n NETNAME export \ + | ssh bar.example.org tinc -n NETNAME exchange \ + | tinc -n NETNAME import - 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. +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.  File: tinc.info, Node: Network interfaces, Next: Example configuration, Prev: Configuration files, Up: Configuration @@ -1430,34 +1431,33 @@ File: tinc.info, Node: Network interfaces, Next: Example configuration, Prev: 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. +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 (`/dev/tun', `/dev/tap0' or +Tinc will open a virtual network device (`/dev/tun', `/dev/tap0' or similar), which will also create a network interface called something like `tun0', `tap0'. If you are using the Linux tun/tap driver, the network interface will by default have the same name as the NETNAME. Under Windows you can change the name of the network interface from the Network Connections control panel. - You can configure the network interface by putting ordinary -ifconfig, route, and other commands to a script named -`/etc/tinc/NETNAME/tinc-up'. When tinc starts, this script will be -executed. When tinc exits, it will execute the script named -`/etc/tinc/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: +You can configure the network interface by putting ordinary ifconfig, +route, and other commands to a script named `/etc/tinc/NETNAME/tinc-up'. +When tinc starts, this script will be executed. When tinc exits, it +will execute the script named `/etc/tinc/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: - tincctl -n NETNAME edit tinc-up + tinc -n NETNAME edit tinc-up - An example `tinc-up' script, that would be appropriate for the -scenario in the previous section, is: +An example `tinc-up' script, that would be appropriate for the scenario +in the previous section, is: #!/bin/sh ifconfig $INTERFACE 192.168.2.1 netmask 255.255.0.0 ip addr add fec0:0:0:2::/48 dev $INTERFACE - The first command gives the interface an IPv4 address and a netmask. +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 `tinc-up' script. The kernel will also bring the interface up after this command. The @@ -1468,7 +1468,7 @@ 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 `ip link set $INTERFACE up' in that case. - The exact syntax of the ifconfig and route commands differs from +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 *note Platform specific information::, but it is best to consult the manpages of those utilities on your @@ -1484,36 +1484,36 @@ 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. +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. 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 - 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). +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. +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 `tincctl init' and `tincctl config' -commands, here we just show the end results: +Each branch is set up using the `tinc init' and `tinc config' commands, +here we just show the end results: For Branch A ............ _BranchA_ would be configured like this: - In `/etc/tinc/company/tinc-up': +In `/etc/tinc/company/tinc-up': #!/bin/sh @@ -1522,11 +1522,11 @@ _BranchA_ would be configured like this: ifconfig $INTERFACE 10.1.54.1 netmask 255.0.0.0 - and in `/etc/tinc/company/tinc.conf': +and in `/etc/tinc/company/tinc.conf': Name = BranchA - On all hosts, `/etc/tinc/company/hosts/BranchA' contains: +On all hosts, `/etc/tinc/company/hosts/BranchA' contains: Subnet = 10.1.0.0/16 Address = 1.2.3.4 @@ -1535,10 +1535,10 @@ _BranchA_ would be configured like this: ... -----END RSA PUBLIC KEY----- - 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, +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. For Branch B @@ -1553,16 +1553,16 @@ In `/etc/tinc/company/tinc-up': ifconfig $INTERFACE 10.2.1.12 netmask 255.0.0.0 - and in `/etc/tinc/company/tinc.conf': +and in `/etc/tinc/company/tinc.conf': Name = BranchB ConnectTo = BranchA - Note here that the internal address (on eth0) doesn't have to be the +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 `/etc/tinc/company/hosts/BranchB': +On all hosts, in `/etc/tinc/company/hosts/BranchB': Subnet = 10.2.0.0/16 Address = 2.3.4.5 @@ -1583,16 +1583,16 @@ In `/etc/tinc/company/tinc-up': ifconfig $INTERFACE 10.3.69.254 netmask 255.0.0.0 - and in `/etc/tinc/company/tinc.conf': +and in `/etc/tinc/company/tinc.conf': Name = BranchC ConnectTo = BranchA - C already has another daemon that runs on port 655, so they have to +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 `/etc/tinc/company/hosts/BranchC': +On all hosts, in `/etc/tinc/company/hosts/BranchC': Address = 3.4.5.6 Subnet = 10.3.0.0/16 @@ -1614,16 +1614,15 @@ In `/etc/tinc/company/tinc-up': ifconfig $INTERFACE 10.4.3.32 netmask 255.0.0.0 - and in `/etc/tinc/company/tinc.conf': +and in `/etc/tinc/company/tinc.conf': Name = BranchD ConnectTo = BranchC - 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. +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 `/etc/tinc/company/hosts/BranchD': +On all hosts, in `/etc/tinc/company/hosts/BranchD': Subnet = 10.4.0.0/16 Address = 4.5.6.7 @@ -1637,10 +1636,10 @@ Key files A, B, C and D all have their own public/private keypairs: - The private RSA key is stored in `/etc/tinc/company/rsa_key.priv', -the private ECDSA key is stored in `/etc/tinc/company/ecdsa_key.priv', -and the public RSA and ECDSA keys are put into the host configuration -file in the `/etc/tinc/company/hosts/' directory. +The private RSA key is stored in `/etc/tinc/company/rsa_key.priv', the +private ECDSA key is stored in `/etc/tinc/company/ecdsa_key.priv', and +the public RSA and ECDSA keys are put into the host configuration file +in the `/etc/tinc/company/hosts/' directory. Starting ........ @@ -1660,9 +1659,9 @@ File: tinc.info, Node: Running tinc, Next: Controlling tinc, Prev: Configurat If everything else is done, you can start tinc by typing the following command: - tincctl -n NETNAME start + tinc -n NETNAME start - Tinc will detach from the terminal and continue to run in the +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. @@ -1704,8 +1703,8 @@ command line options. networks::. `--pidfile=FILENAME' - Store a cookie in FILENAME which allows tincctl to authenticate. - If unspecified, the default is `/var/run/tinc.NETNAME.pid'. + Store a cookie in FILENAME which allows tinc to authenticate. If + unspecified, the default is `/var/run/tinc.NETNAME.pid'. `-o, --option=[HOST.]KEY=VALUE' Without specifying a HOST, this will set server configuration @@ -1829,8 +1828,8 @@ directly see everything tinc logs: tincd -n NETNAME -d5 -D - If tinc does not log any error messages, then you might want to -check the following things: +If tinc does not log any error messages, then you might want to check +the following things: * `tinc-up' script Does this script contain the right commands? Normally you must give the interface the address of this host on @@ -1988,24 +1987,24 @@ File: tinc.info, Node: Controlling tinc, Next: Technical information, Prev: R 6 Controlling tinc ****************** -You can control and inspect a running tincd through the tincctl -command. A quick example: +You can control and inspect a running tincd through the tinc command. A +quick example: - tincctl -n NETNAME reload + tinc -n NETNAME reload * Menu: -* tincctl runtime options:: -* tincctl environment variables:: -* tincctl commands:: -* tincctl examples:: -* tincctl top:: +* tinc runtime options:: +* tinc environment variables:: +* tinc commands:: +* tinc examples:: +* tinc top::  -File: tinc.info, Node: tincctl runtime options, Next: tincctl environment variables, Up: Controlling tinc +File: tinc.info, Node: tinc runtime options, Next: tinc environment variables, Up: Controlling tinc -6.1 tincctl runtime options -=========================== +6.1 tinc runtime options +======================== `-c, --config=PATH' Read configuration options from the directory PATH. The default is @@ -2028,42 +2027,42 @@ File: tinc.info, Node: tincctl runtime options, Next: tincctl environment vari  -File: tinc.info, Node: tincctl environment variables, Next: tincctl commands, Prev: tincctl runtime options, Up: Controlling tinc +File: tinc.info, Node: tinc environment variables, Next: tinc commands, Prev: tinc runtime options, Up: Controlling tinc -6.2 tincctl environment variables -================================= +6.2 tinc environment variables +============================== `NETNAME' If no netname is specified on the command line with the `-n' option, the value of this environment variable is used.  -File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincctl environment variables, Up: Controlling tinc +File: tinc.info, Node: tinc commands, Next: tinc examples, Prev: tinc environment variables, Up: Controlling tinc -6.3 tincctl commands -==================== +6.3 tinc commands +================= `init [NAME]' Create initial configuration files and RSA and ECDSA keypairs with default length. If no NAME for this node is given, it will be asked for. -`config [get] VARIABLE' +`get VARIABLE' Print the current value of configuration variable VARIABLE. If more than one variable with the same name exists, the value of each of them will be printed on a separate line. -`config [set] VARIABLE VALUE' +`set VARIABLE VALUE' Set configuration variable VARIABLE to the given VALUE. All previously existing configuration variables with the same name are removed. To set a variable for a specific host, use the notation HOST.VARIABLE. -`config add VARIABLE VALUE' +`add VARIABLE VALUE' As above, but without removing any previously existing configuration variables. -`config del VARIABLE [VALUE]' +`del VARIABLE [VALUE]' Remove configuration variables with the same name and VALUE. If no VALUE is given, all configuration variables with the same name will be removed. @@ -2080,7 +2079,7 @@ File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincct Export all host configuration files to standard output. `import [--force]' - Import host configuration file(s) generated by the tincctl export + Import host configuration file(s) generated by the tinc export command from standard input. Already existing host configuration files are not overwritten unless the option -force is used. @@ -2146,7 +2145,7 @@ File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincct `log [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. + messages sent to tinc. `retry' Forces tinc to try to connect to all uplinks immediately. Usually @@ -2159,9 +2158,9 @@ File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincct Closes the meta connection with the given NODE. `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. + If tinc 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. `pcap' Dump VPN traffic going through the local tinc node in @@ -2171,30 +2170,30 @@ File: tinc.info, Node: tincctl commands, Next: tincctl examples, Prev: tincct  -File: tinc.info, Node: tincctl examples, Next: tincctl top, Prev: tincctl commands, Up: Controlling tinc +File: tinc.info, Node: tinc examples, Next: tinc top, Prev: tinc commands, Up: Controlling tinc -6.4 tincctl examples -==================== +6.4 tinc examples +================= Examples of some commands: - tincctl -n vpn dump graph | circo -Txlib - tincctl -n vpn pcap | tcpdump -r - - tincctl -n vpn top + tinc -n vpn dump graph | circo -Txlib + tinc -n vpn pcap | tcpdump -r - + tinc -n vpn top - Example of configuring tinc using tincctl: +Example of configuring tinc using the tinc command: - 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 + tinc -n vpn init foo + tinc -n vpn add Subnet 192.168.1.0/24 + tinc -n vpn add bar.Address bar.example.com + tinc -n vpn add ConnectTo bar + tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@example.com  -File: tinc.info, Node: tincctl top, Prev: tincctl examples, Up: Controlling tinc +File: tinc.info, Node: tinc top, Prev: tinc examples, Up: Controlling tinc -6.5 tincctl top -=============== +6.5 tinc 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 @@ -2294,33 +2293,33 @@ 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 +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 +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. - When that is done, time has come to actually transport the packet to +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 _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. +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 +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 @@ -2330,7 +2329,7 @@ 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 +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 @@ -2348,21 +2347,21 @@ 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. - TCP is a better alternative, because it already contains protection +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 +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. - 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." +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 +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 @@ -2380,18 +2379,18 @@ 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 +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 *note 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. +The authentication scheme is described in *note Security::. 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. message ------------------------------------------------------------------ @@ -2409,13 +2408,13 @@ daemons behind them) have their information synchronised. +------------------> owner of this subnet ------------------------------------------------------------------ - The ADD_EDGE messages are to inform other tinc daemons that a +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. +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. message ------------------------------------------------------------------ @@ -2429,10 +2428,10 @@ node a VPN packet has to be sent. +------------------> owner of this subnet ------------------------------------------------------------------ - 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. +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. message ------------------------------------------------------------------ @@ -2452,20 +2451,20 @@ unreachable if there isn't any. +--> daemon that has changed it's packet key ------------------------------------------------------------------ - 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. +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. - daemon message + daemon message ------------------------------------------------------------------ - origin PING - dest. PONG + origin PING + dest. PONG ------------------------------------------------------------------ - There is also a mechanism to check if hosts are still alive. Since +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 @@ -2474,7 +2473,7 @@ 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. +This basically covers what is sent over the meta connection by tinc.  File: tinc.info, Node: Security, Prev: The meta-protocol, Up: Technical information @@ -2487,32 +2486,34 @@ alleged Cabal was/is an organisation that was said to keep an eye on the entire Internet. As this is exactly what you _don't_ want, we named the tinc project after TINC. - But in order to be "immune" to eavesdropping, you'll have to encrypt -your data. Because tinc is a _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. +But in order to be "immune" to eavesdropping, you'll have to encrypt +your data. Because tinc is a _Secure_ VPN (SVPN) daemon, it does +exactly that: encrypt. However, encryption in itself does not prevent +an attacker from modifying the encrypted data. Therefore, tinc also +authenticates the data. Finally, tinc uses sequence numbers (which +themselves are also authenticated) to prevent an attacker from +replaying valid packets. + +Since version 1.1pre3, tinc has two protocols used to protect your +data; the legacy protocol, and the new Simple Peer-to-Peer Security +(SPTPS) protocol. The SPTPS protocol is designed to address some +weaknesses in the legacy protocol. The new authentication protocol is +used when two nodes connect to each other that both have the +ExperimentalProtocol option set to yes, otherwise the legacy protocol +will be used. * Menu: -* Authentication protocol:: +* Legacy authentication protocol:: +* Simple Peer-to-Peer Security:: * Encryption of network packets:: * Security issues::  -File: tinc.info, Node: Authentication protocol, Next: Encryption of network packets, Up: Security +File: tinc.info, Node: Legacy authentication protocol, Next: Simple Peer-to-Peer Security, Up: Security -7.3.1 Authentication protocol ------------------------------ - -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. +7.3.1 Legacy authentication protocol +------------------------------------ daemon message -------------------------------------------------------------------------- @@ -2520,28 +2521,47 @@ Explanation is below. server - client ID client 12 - | +---> version - +-------> name of tinc daemon + client ID client 17.2 + | | +-> minor protocol version + | +----> major protocol version + +--------> name of tinc daemon - server ID server 12 - | +---> version - +-------> name of tinc daemon + server ID server 17.2 + | | +-> minor protocol version + | +----> major protocol version + +--------> name of tinc daemon - client META_KEY 5f0823a93e35b69e...7086ec7866ce582b - \_________________________________/ - +-> RSAKEYLEN bits totally random string S1, - encrypted with server's public RSA key + client META_KEY 94 64 0 0 5f0823a93e35b69e...7086ec7866ce582b + | | | | \_________________________________/ + | | | | +-> RSAKEYLEN bits totally random string S1, + | | | | encrypted with server's public RSA key + | | | +-> compression level + | | +---> MAC length + | +------> digest algorithm NID + +---------> cipher algorithm NID - server META_KEY 6ab9c1640388f8f0...45d1a07f8a672630 - \_________________________________/ - +-> RSAKEYLEN bits totally random string S2, - encrypted with client's public RSA key + server META_KEY 94 64 0 0 6ab9c1640388f8f0...45d1a07f8a672630 + | | | | \_________________________________/ + | | | | +-> RSAKEYLEN bits totally random string S2, + | | | | encrypted with client's public RSA key + | | | +-> compression level + | | +---> MAC length + | +------> digest algorithm NID + +---------> cipher algorithm NID + -------------------------------------------------------------------------- - From now on: - - the client will symmetrically encrypt outgoing traffic using S1 - - the server will symmetrically encrypt outgoing traffic using S2 +The protocol allows each side to specify encryption algorithms and +parameters, but in practice they are always fixed, since older versions +of tinc did not allow them to be different from the default values. The +cipher is always Blowfish in OFB mode, the digest is SHA1, but the MAC +length is zero and no compression is used. +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 @@ -2561,74 +2581,227 @@ Explanation is below. client ACK 655 123 0 | | +-> options - | +----> estimated weight - +--------> listening port of client + | +----> estimated weight + +--------> listening port of client server ACK 655 321 0 | | +-> options - | +----> estimated weight - +--------> listening port of server + | +----> estimated weight + +--------> listening port of server -------------------------------------------------------------------------- - 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. +This legacy authentication protocol has several weaknesses, pointed out +by security export Peter Gutmann. First, data is encrypted with RSA +without padding. Padding schemes are designed to prevent attacks when +the size of the plaintext is not equal to the size of the RSA key. +Tinc always encrypts random nonces that have the same size as the RSA +key, so we do not believe this leads to a break of the security. There +might be timing or other side-channel attacks against RSA encryption +and decryption, tinc does not employ any protection against those. +Furthermore, both sides send identical messages to each other, there is +no distinction between server and client, which could make a MITM +attack easier. However, no exploit is known in which a third party who +is not already trusted by other nodes in the VPN could gain access. +Finally, the RSA keys are used to directly encrypt the session keys, +which means that if the RSA keys are compromised, it is possible to +decrypt all previous VPN traffic. In other words, the legacy protocol +does not provide perfect forward secrecy.  -File: tinc.info, Node: Encryption of network packets, Next: Security issues, Prev: Authentication protocol, Up: Security +File: tinc.info, Node: Simple Peer-to-Peer Security, Next: Encryption of network packets, Prev: Legacy authentication protocol, Up: Security -7.3.2 Encryption of network packets +7.3.2 Simple Peer-to-Peer Security +---------------------------------- + +The SPTPS protocol is designed to address the weaknesses in the legacy +protocol. SPTPS is based on TLS 1.2, but has been simplified: there is +no support for exchanging public keys, and there is no cipher suite +negotiation. Instead, SPTPS always uses a very strong cipher suite: +peers authenticate each other using 521 bits ECC keys, Diffie-Hellman +using ephemeral 521 bits ECC keys is used to provide perfect forward +secrecy (PFS), AES-256-CTR is used for encryption, and HMAC-SHA-256 for +message authentication. + +Similar to TLS, messages are split up in records. A complete logical +record contains the following information: + + * uint32_t seqno (network byte order) + + * uint16_t length (network byte order) + + * uint8_t type + + * opaque data[length] + + * opaque hmac[HMAC_SIZE] (HMAC over all preceding fields) + +Depending on whether SPTPS records are sent via TCP or UDP, either the +seqno or the length field is omitted on the wire (but they are still +included in the calculation of the HMAC); for TCP packets are +guaranteed to arrive in-order so we can infer the seqno, but packets +can be split or merged, so we still need the length field to determine +the boundaries between records; for UDP packets we know that there is +exactly one record per packet, and we know the length of a packet, but +packets can be dropped, duplicated and/or reordered, so we need to +include the seqno. + +The type field is used to distinguish between application records or +handshake records. Types 0 to 127 are application records, type 128 is +a handshake record, and types 129 to 255 are reserved. + +Before the initial handshake, no fields are encrypted, and the HMAC +field is not present. After the authentication handshake, the length +(if present), type and data fields are encrypted, and the HMAC field is +present. For UDP packets, the seqno field is not encrypted, as it is +used to determine the value of the counter used for encryption. + +The authentication consists of an exchange of Key EXchange, SIGnature +and ACKnowledge messages, transmitted using type 128 records. + +Overview: + + Initiator Responder + --------------------- + KEX -> + <- KEX + SIG -> + <- SIG + + ...encrypt and HMAC using session keys from now on... + + App -> + <- App + ... + ... + + ...key renegotiation starts here... + + KEX -> + <- KEX + SIG -> + <- SIG + ACK -> + <- ACK + + ...encrypt and HMAC using new session keys from now on... + + App -> + <- App + ... + ... + --------------------- + +Note that the responder does not need to wait before it receives the +first KEX message, it can immediately send its own once it has accepted +an incoming connection. + +Key EXchange message: + + * uint8_t kex_version (always 0 in this version of SPTPS) + + * opaque nonce[32] (random number) + + * opaque ecdh_key[ECDH_SIZE] + +SIGnature message: + + * opaque ecdsa_signature[ECDSA_SIZE] + +ACKnowledge message: + + * empty (only sent after key renegotiation) + +Remarks: + + * At the start, both peers generate a random nonce and an Elliptic + Curve public key and send it to the other in the KEX message. + + * After receiving the other's KEX message, both KEX messages are + concatenated (see below), and the result is signed using ECDSA. + The result is sent to the other. + + * After receiving the other's SIG message, the signature is verified. + If it is correct, the shared secret is calculated from the public + keys exchanged in the KEX message using the Elliptic Curve + Diffie-Helman algorithm. + + * The shared secret key is expanded using a PRF. Both nonces and + the application specific label are also used as input for the PRF. + + * An ACK message is sent only when doing key renegotiation, and is + sent using the old encryption keys. + + * The expanded key is used to key the encryption and HMAC algorithms. + +The signature is calculated over this string: + + * uint8_t initiator (0 = local peer, 1 = remote peer is initiator) + + * opaque remote_kex_message[1 + 32 + ECDH_SIZE] + + * opaque local_kex_message[1 + 32 + ECDH_SIZE] + + * opaque label[label_length] + +The PRF is calculated as follows: + + * A HMAC using SHA512 is used, the shared secret is used as the key. + + * For each block of 64 bytes, a HMAC is calculated. For block n: + hmac[n] = HMAC_SHA512(hmac[n - 1] + seed) + + * For the first block (n = 1), hmac[0] is given by + HMAC_SHA512(zeroes + seed), where zeroes is a block of 64 zero + bytes. + +The seed is as follows: + + * const char[13] "key expansion" + + * opaque responder_nonce[32] + + * opaque initiator_nonce[32] + + * opaque label[label_length] + +The expanded key is used as follows: + + * opaque responder_cipher_key[CIPHER_KEYSIZE] + + * opaque responder_digest_key[DIGEST_KEYSIZE] + + * opaque initiator_cipher_key[CIPHER_KEYSIZE] + + * opaque initiator_digest_key[DIGEST_KEYSIZE] + +Where initiator_cipher_key is the key used by session initiator to +encrypt messages sent to the responder. + +When using 521 bits EC keys, the AES-256-CTR cipher and HMAC-SHA-256 +digest algorithm, the sizes are as follows: + + ECDH_SIZE: 67 (= ceil(521/8) + 1) + ECDSA_SIZE: 141 (= 2 * ceil(521/8) + 9) + CIPHER_KEYSIZE: 48 (= 256/8 + 128/8) + DIGEST_KEYSIZE: 32 (= 256/8) + +Note that the cipher key also includes the initial value for the +counter. + + +File: tinc.info, Node: Encryption of network packets, Next: Security issues, Prev: Simple Peer-to-Peer Security, Up: Security + +7.3.3 Encryption of network packets ----------------------------------- 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. +to retrieve it. - The UDP packet containing the network packet from the VPN has the -following layout: +The UDP packets can be either encrypted with the legacy protocol or +with SPTPS. In case of the legacy protocol, the UDP packet containing +the network packet from the VPN has the following layout: ... | IP header | UDP header | seqno | VPN packet | MAC | UDP trailer \___________________/\_____/ @@ -2636,18 +2809,38 @@ following layout: V +---> digest algorithm Encrypted with symmetric cipher - So, the entire VPN packet is encrypted using a symmetric cipher, +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. +packet to prevent alteration of packets. Tinc by default encrypts +network packets using Blowfish with 128 bit keys in CBC mode and uses 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. + +The SPTPS protocol is described in *note Simple Peer-to-Peer Security::. +For comparison, this is how SPTPS UDP packets look: + + ... | IP header | UDP header | seqno | type | VPN packet | MAC | UDP trailer + \__________________/\_____/ + | | + V +---> digest algorithm + Encrypted with symmetric cipher + +The difference is that the seqno is not encrypted, since the encryption +cipher is used in CTR mode, and therefore the seqno must be known +before the packet can be decrypted. Furthermore, the MAC is never +truncated. The SPTPS protocol always uses the AES-256-CTR cipher and +HMAC-SHA-256 digest, this cannot be changed.  File: tinc.info, Node: Security issues, Prev: Encryption of network packets, Up: Security -7.3.3 Security issues +7.3.4 Security issues --------------------- In August 2000, we discovered the existence of a security hole in all @@ -2657,22 +2850,25 @@ 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 +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. +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 the legacy protocol of tinc, but +it is not as strong as TLS or IPsec. - Cryptography is a hard thing to get right. We cannot make any +This version of tinc comes with an improved protocol, called Simple +Peer-to-Peer Security, which aims to be as strong as TLS with one of +the strongest cipher suites. + +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. @@ -2703,7 +2899,7 @@ 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: +For IPv4 addresses: Linux `ifconfig' INTERFACE ADDRESS `netmask' NETMASK Linux iproute2 `ip addr add' ADDRESS`/'PREFIXLENGTH `dev' INTERFACE @@ -2714,7 +2910,7 @@ Solaris `ifconfig' INTERFACE ADDRESS `netmask' NETMASK Darwin (MacOS/X) `ifconfig' INTERFACE ADDRESS `netmask' NETMASK Windows `netsh interface ip set address' INTERFACE `static' ADDRESS NETMASK - For IPv6 addresses: +For IPv6 addresses: Linux `ifconfig' INTERFACE `add' ADDRESS`/'PREFIXLENGTH FreeBSD `ifconfig' INTERFACE `inet6' ADDRESS `prefixlen' PREFIXLENGTH @@ -2725,16 +2921,16 @@ Solaris `ifconfig' INTERFACE `inet6 plumb up' Darwin (MacOS/X) `ifconfig' INTERFACE `inet6' ADDRESS `prefixlen' PREFIXLENGTH Windows `netsh interface ipv6 add address' INTERFACE `static' ADDRESS/PREFIXLENGTH - On some platforms, when running tinc in switch mode, the VPN -interface must be set to tap mode with an ifconfig command: +On some platforms, when running tinc in switch mode, the VPN interface +must be set to tap mode with an ifconfig command: OpenBSD `ifconfig' INTERFACE `link0' - 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. +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. Linux `ip tuntap add dev' INTERFACE `mode' TUN|TAP `user' USERNAME @@ -2751,7 +2947,7 @@ another way is to specify the (local) address that is assigned to that interface (LOCAL_ADDRESS). The former way is unambiguous and therefore preferable, but not all platforms support this. - Adding routes to IPv4 subnets: +Adding routes to IPv4 subnets: Linux `route add -net' NETWORK_ADDRESS `netmask' NETMASK INTERFACE Linux iproute2 `ip route add' NETWORK_ADDRESS`/'PREFIXLENGTH `dev' INTERFACE @@ -2763,7 +2959,7 @@ Darwin (MacOS/X) `route add' NETWORK_ADDRESS`/'PREFIXLENGTH LOCAL_ADDRESS Windows `netsh routing ip add persistentroute' NETWORK_ADDRESS NETMASK INTERFACE LOCAL_ADDRESS - Adding routes to IPv6 subnets: +Adding routes to IPv6 subnets: Linux `route add -A inet6' NETWORK_ADDRESS`/'PREFIXLENGTH INTERFACE Linux iproute2 `ip route add' NETWORK_ADDRESS`/'PREFIXLENGTH `dev' INTERFACE @@ -2794,8 +2990,8 @@ File: tinc.info, Node: Contact information, Next: Authors, Up: About us Tinc's website is at `http://www.tinc-vpn.org/', this server is located in the Netherlands. - We have an IRC channel on the FreeNode and OFTC IRC networks. -Connect to irc.freenode.net (http://www.freenode.net/) or irc.oftc.net +We have an IRC channel on the FreeNode and OFTC IRC networks. Connect to +irc.freenode.net (http://www.freenode.net/) or irc.oftc.net (http://www.oftc.net/) and join channel #tinc.  @@ -2808,10 +3004,10 @@ Ivo Timmermans (zarq) Guus Sliepen (guus) () - 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 `THANKS' in -the source distribution. +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 `THANKS' in the +source distribution.  File: tinc.info, Node: Concept Index, Prev: About us, Up: Top @@ -2822,8 +3018,8 @@ Concept Index [index] * Menu: -* ACK: Authentication protocol. - (line 10) +* ACK: Legacy authentication protocol. + (line 6) * ADD_EDGE: The meta-protocol. (line 23) * ADD_SUBNET: The meta-protocol. (line 23) * Address: Host configuration variables. @@ -2831,8 +3027,6 @@ Concept Index * AddressFamily: Main configuration variables. (line 6) * ANS_KEY: The meta-protocol. (line 64) -* authentication: Authentication protocol. - (line 6) * AutoConnect: Main configuration variables. (line 12) * binary package: Building and installing tinc. @@ -2844,21 +3038,21 @@ Concept Index * Broadcast: Main configuration variables. (line 41) * Cabal: Security. (line 6) -* CHAL_REPLY: Authentication protocol. - (line 10) -* CHALLENGE: Authentication protocol. - (line 10) +* CHAL_REPLY: Legacy authentication protocol. + (line 6) +* CHALLENGE: Legacy authentication protocol. + (line 6) * CIDR notation: Host configuration variables. - (line 88) + (line 94) * Cipher: Host configuration variables. (line 12) * ClampMSS: Host configuration variables. - (line 18) + (line 20) * client: How connections work. (line 18) * command line: Runtime options. (line 9) * Compression: Host configuration variables. - (line 24) + (line 26) * connection: The connection. (line 6) * ConnectTo: Main configuration variables. (line 61) @@ -2877,7 +3071,7 @@ Concept Index * DeviceType: Main configuration variables. (line 88) * Digest: Host configuration variables. - (line 29) + (line 31) * DirectOnly: Main configuration variables. (line 153) * dummy: Main configuration variables. @@ -2903,10 +3097,10 @@ Concept Index (line 318) * hub: Main configuration variables. (line 245) -* ID: Authentication protocol. - (line 10) +* ID: Legacy authentication protocol. + (line 6) * IndirectData: Host configuration variables. - (line 34) + (line 38) * INTERFACE: Scripts. (line 58) * Interface: Main configuration variables. (line 204) @@ -2914,6 +3108,8 @@ Concept Index * KEY_CHANGED: The meta-protocol. (line 64) * KeyExpire: Main configuration variables. (line 250) +* legacy authentication protocol: Legacy authentication protocol. + (line 6) * libcurses: libcurses. (line 6) * libraries: Libraries. (line 6) * libreadline: libreadline. (line 6) @@ -2924,10 +3120,10 @@ Concept Index * MACExpire: Main configuration variables. (line 256) * MACLength: Host configuration variables. - (line 39) + (line 43) * meta-protocol: The meta-connection. (line 18) -* META_KEY: Authentication protocol. - (line 10) +* META_KEY: Legacy authentication protocol. + (line 6) * Mode: Main configuration variables. (line 223) * multicast: Main configuration variables. @@ -2936,8 +3132,8 @@ Concept Index * NAME: Scripts. (line 52) * Name: Main configuration variables. (line 261) -* netmask: Network interfaces. (line 39) -* NETNAME <1>: tincctl environment variables. +* netmask: Network interfaces. (line 38) +* NETNAME <1>: tinc environment variables. (line 6) * NETNAME: Scripts. (line 49) * netname: Multiple networks. (line 6) @@ -2947,7 +3143,7 @@ Concept Index * OpenSSL: OpenSSL. (line 6) * options: Runtime options. (line 9) * PEM format: Host configuration variables. - (line 64) + (line 70) * PING: The meta-protocol. (line 89) * PingInterval: Main configuration variables. (line 272) @@ -2955,12 +3151,12 @@ Concept Index (line 276) * platforms: Supported platforms. (line 6) * PMTU: Host configuration variables. - (line 44) + (line 50) * PMTUDiscovery: Host configuration variables. - (line 47) + (line 53) * PONG: The meta-protocol. (line 89) * Port: Host configuration variables. - (line 52) + (line 58) * port numbers: Other files. (line 17) * PriorityInheritance: Main configuration variables. (line 282) @@ -2975,9 +3171,9 @@ Concept Index * Proxy: Main configuration variables. (line 303) * PublicKey: Host configuration variables. - (line 56) + (line 62) * PublicKeyFile: Host configuration variables. - (line 59) + (line 65) * raw_socket: Main configuration variables. (line 100) * release: Supported platforms. (line 14) @@ -2999,17 +3195,19 @@ Concept Index (line 307) * socks5: Main configuration variables. (line 312) +* SPTPS: Simple Peer-to-Peer Security. + (line 6) * StrictSubnets: Main configuration variables. (line 337) * SUBNET: Scripts. (line 74) * Subnet: Host configuration variables. - (line 71) + (line 77) * SVPN: Security. (line 11) * switch: Main configuration variables. (line 234) * TCP: The meta-connection. (line 10) * TCPonly: Host configuration variables. - (line 100) + (line 106) * TINC: Security. (line 6) * tinc: Introduction. (line 6) * tinc-down: Scripts. (line 18) @@ -3024,7 +3222,7 @@ Concept Index * tunnohead: Main configuration variables. (line 136) * UDP <1>: Encryption of network packets. - (line 12) + (line 11) * UDP: The UDP tunnel. (line 30) * UDPRcvBuf: Main configuration variables. (line 349) @@ -3050,71 +3248,72 @@ Concept Index Tag Table: Node: Top811 Node: Introduction1131 -Node: Virtual Private Networks1941 -Node: tinc3667 -Node: Supported platforms5194 -Node: Preparations5893 -Node: Configuring the kernel6149 -Node: Configuration of Linux kernels6558 -Node: Configuration of FreeBSD kernels7413 -Node: Configuration of OpenBSD kernels7878 -Node: Configuration of NetBSD kernels8486 -Node: Configuration of Solaris kernels8891 -Node: Configuration of Darwin (MacOS/X) kernels9552 -Node: Configuration of Windows10241 -Node: Libraries10755 -Node: OpenSSL11173 -Node: zlib13461 -Node: lzo14487 -Node: libcurses15485 -Node: libreadline16405 -Node: Installation17353 -Node: Building and installing tinc18369 -Node: Darwin (MacOS/X) build environment19028 -Node: Cygwin (Windows) build environment19595 -Node: MinGW (Windows) build environment20183 -Node: System files20707 -Node: Device files20972 -Node: Other files21388 -Node: Configuration22001 -Node: Configuration introduction22288 -Node: Multiple networks23835 -Node: How connections work25215 -Node: Configuration files27788 -Node: Main configuration variables29321 -Node: Host configuration variables45735 -Node: Scripts50810 -Node: How to configure53489 -Node: Network interfaces58079 -Node: Example configuration60480 -Node: Running tinc65632 -Node: Runtime options66225 -Node: Signals69088 -Node: Debug levels69938 -Node: Solving problems70874 -Node: Error messages72304 -Node: Sending bug reports76626 -Node: Controlling tinc77578 -Node: tincctl runtime options77975 -Node: tincctl environment variables78674 -Node: tincctl commands79018 -Node: tincctl examples83503 -Node: tincctl top84108 -Node: Technical information85706 -Node: The connection85941 -Node: The UDP tunnel86253 -Node: The meta-connection89314 -Node: The meta-protocol90783 -Node: Security95792 -Node: Authentication protocol96922 -Node: Encryption of network packets101926 -Node: Security issues103299 -Node: Platform specific information104916 -Node: Interface configuration105144 -Node: Routes107597 -Node: About us109513 -Node: Contact information109688 -Node: Authors110092 -Node: Concept Index110497 +Node: Virtual Private Networks1935 +Node: tinc3650 +Node: Supported platforms5161 +Node: Preparations5857 +Node: Configuring the kernel6113 +Node: Configuration of Linux kernels6522 +Node: Configuration of FreeBSD kernels7371 +Node: Configuration of OpenBSD kernels7836 +Node: Configuration of NetBSD kernels8444 +Node: Configuration of Solaris kernels8846 +Node: Configuration of Darwin (MacOS/X) kernels9507 +Node: Configuration of Windows10196 +Node: Libraries10710 +Node: OpenSSL11128 +Node: zlib13401 +Node: lzo14418 +Node: libcurses15407 +Node: libreadline16315 +Node: Installation17251 +Node: Building and installing tinc18261 +Node: Darwin (MacOS/X) build environment18917 +Node: Cygwin (Windows) build environment19481 +Node: MinGW (Windows) build environment20066 +Node: System files20584 +Node: Device files20849 +Node: Other files21262 +Node: Configuration21875 +Node: Configuration introduction22162 +Node: Multiple networks23684 +Node: How connections work25052 +Node: Configuration files27613 +Node: Main configuration variables29140 +Node: Host configuration variables45548 +Node: Scripts51020 +Node: How to configure53696 +Node: Network interfaces58178 +Node: Example configuration60557 +Node: Running tinc65648 +Node: Runtime options66235 +Node: Signals69096 +Node: Debug levels69946 +Node: Solving problems70882 +Node: Error messages72309 +Node: Sending bug reports76631 +Node: Controlling tinc77583 +Node: tinc runtime options77959 +Node: tinc environment variables78646 +Node: tinc commands78975 +Node: tinc examples83404 +Node: tinc top83967 +Node: Technical information85553 +Node: The connection85788 +Node: The UDP tunnel86100 +Node: The meta-connection89143 +Node: The meta-protocol90601 +Node: Security95575 +Node: Legacy authentication protocol96911 +Node: Simple Peer-to-Peer Security101526 +Node: Encryption of network packets107223 +Node: Security issues109850 +Node: Platform specific information111576 +Node: Interface configuration111804 +Node: Routes114245 +Node: About us116155 +Node: Contact information116330 +Node: Authors116731 +Node: Concept Index117134  End Tag Table diff --git a/doc/tinc.texi b/doc/tinc.texi index 8910115..e1af55c 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -30,6 +30,10 @@ permission notice identical to this one. @end ifinfo +@afourpaper +@paragraphindent none +@finalout + @titlepage @title tinc Manual @subtitle Setting up a Virtual Private Network with tinc @@ -262,7 +266,7 @@ alias char-major-10-200 tun @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}. +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 ================================================================== @@ -462,7 +466,7 @@ default). @subsection libcurses @cindex libcurses -For the "tincctl top" command, tinc requires a curses library. +For the "tinc 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 @@ -485,7 +489,7 @@ of this package. @subsection libreadline @cindex libreadline -For the "tincctl" command's shell functionality, tinc uses the readline library. +For the "tinc" 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 @@ -696,12 +700,12 @@ 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} +tinc -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 +Second, use @samp{tinc -n @var{NETNAME} add ...} to further configure tinc. +Finally, export your host configuration file using @samp{tinc -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}. +They should send you their host configuration file back, which you can import using @samp{tinc -n @var{NETNAME} import}. These steps are described in the subsections below. @@ -721,7 +725,7 @@ 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, +This means that you call tinc with the -n argument, which will specify the netname. The effect of this option is that tinc will set its configuration @@ -809,7 +813,7 @@ 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. +the tinc command 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, @@ -1003,7 +1007,7 @@ 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}. +@samp{tinc 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. @@ -1130,7 +1134,7 @@ 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 +generated by @samp{tinc generate-keys}. It must be a full path, not a relative directory. @cindex ProcessPriority @@ -1217,10 +1221,11 @@ 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. +The symmetric cipher algorithm used to encrypt UDP packets using the legacy protocol. 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. +This option has no effect for connections using the SPTPS protocol, which always use AES-256-CTR. @cindex ClampMSS @item ClampMSS = (yes) @@ -1236,9 +1241,10 @@ Possible values are 0 (off), 1 (fast zlib) and any integer up to 9 (best zlib), @cindex Digest @item Digest = <@var{digest}> (sha1) -The digest algorithm used to authenticate UDP packets. +The digest algorithm used to authenticate UDP packets using the legacy protocol. Any digest supported by OpenSSL is recognized. Furthermore, specifying "none" will turn off packet authentication. +This option has no effect for connections using the SPTPS protocol, which always use HMAC-SHA-256. @cindex IndirectData @item IndirectData = (no) @@ -1248,9 +1254,10 @@ 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. +The length of the message authentication code used to authenticate UDP packets using the legacy protocol. Can be anything from 0 up to the length of the digest produced by the digest algorithm. +This option has no effect for connections using the SPTPS protocol, which never truncate MACs. @cindex PMTU @item PMTU = <@var{mtu}> (1514) @@ -1273,7 +1280,7 @@ 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 +by @samp{tinc generate-keys}. It must be a full path, not a relative directory. @cindex PEM format @@ -1421,7 +1428,7 @@ When a subnet becomes (un)reachable, this is set to the subnet. The initial directory structure, configuration files and public/private keypairs are created using the following command: @example -tincctl -n @var{netname} init @var{name} +tinc -n @var{netname} init @var{name} @end example (You will need to run this as root, or use "sudo".) @@ -1449,7 +1456,7 @@ 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 +tinc -n @var{netname} add subnet 192.168.2.0/24 @end example This will add a Subnet statement to your host configuration file. @@ -1465,18 +1472,18 @@ 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 +tinc -n @var{netname} 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 make a mistake, you can undo it by simply using @samp{del} instead of @samp{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 +tinc -n @var{netname} add address foo.example.org @end example If you already know to which daemons your daemon should make meta-connections, @@ -1484,7 +1491,7 @@ 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 +tinc -n @var{netname} add connectto bar @end example Note that you specify the Name of the other daemon here, not an IP address or hostname! @@ -1501,7 +1508,7 @@ If you are on a UNIX platform, you can easily send an email containing the neces (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 +tinc -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, @@ -1509,16 +1516,16 @@ 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 +tinc -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 +tinc -n @var{netname} export \ + | ssh bar.example.org tinc -n @var{netname} exchange \ + | tinc -n @var{netname} import @end example You should repeat this for all nodes you ConnectTo, or which ConnectTo you. @@ -1551,7 +1558,7 @@ When tinc starts, this script will be executed. When tinc exits, it will execute You can manually open the script in an editor, or use the following command: @example -tincctl -n @var{netname} edit tinc-up +tinc -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: @@ -1612,7 +1619,7 @@ 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, +Each branch is set up using the @samp{tinc init} and @samp{tinc config} commands, here we just show the end results: @subsubheading For Branch A @@ -1783,7 +1790,7 @@ their daemons, tinc will try connecting until they are available. If everything else is done, you can start tinc by typing the following command: @example -tincctl -n @var{netname} start +tinc -n @var{netname} start @end example @cindex daemon @@ -1834,7 +1841,7 @@ 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. +Store a cookie in @var{filename} which allows tinc to authenticate. If unspecified, the default is @file{@value{localstatedir}/run/tinc.@var{netname}.pid}. @@ -2059,7 +2066,7 @@ 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. +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 @@ -2108,25 +2115,25 @@ Be sure to include the following information in your bugreport: @node Controlling tinc @chapter Controlling tinc -You can control and inspect a running tincd through the tincctl +You can control and inspect a running tincd through the tinc command. A quick example: @example -tincctl -n @var{netname} reload +tinc -n @var{netname} reload @end example @menu -* tincctl runtime options:: -* tincctl environment variables:: -* tincctl commands:: -* tincctl examples:: -* tincctl top:: +* tinc runtime options:: +* tinc environment variables:: +* tinc commands:: +* tinc examples:: +* tinc top:: @end menu @c ================================================================== -@node tincctl runtime options -@section tincctl runtime options +@node tinc runtime options +@section tinc runtime options @c from the manpage @table @option @@ -2151,8 +2158,8 @@ Output version information and exit. @end table @c ================================================================== -@node tincctl environment variables -@section tincctl environment variables +@node tinc environment variables +@section tinc environment variables @table @env @cindex NETNAME @@ -2162,8 +2169,8 @@ the value of this environment variable is used. @end table @c ================================================================== -@node tincctl commands -@section tincctl commands +@node tinc commands +@section tinc commands @c from the manpage @table @code @@ -2172,20 +2179,20 @@ the value of this environment variable is used. 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} +@item 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} +@item 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} +@item add @var{variable} @var{value} As above, but without removing any previously existing configuration variables. -@item config del @var{variable} [@var{value}] +@item 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. @@ -2200,7 +2207,7 @@ Export the host configuration file of the local node to standard output. 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. +Import host configuration file(s) generated by the tinc export command from standard input. Already existing host configuration files are not overwritten unless the option --force is used. @item exchange [--force] @@ -2263,7 +2270,7 @@ 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. +An optional debug level can be given that will be applied only for log messages sent to tinc. @item retry Forces tinc to try to connect to all uplinks immediately. @@ -2276,7 +2283,7 @@ it defaults to the maximum time of 15 minutes. 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, +If tinc 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. @@ -2288,30 +2295,30 @@ such as tcpdump. @end table @c ================================================================== -@node tincctl examples -@section tincctl examples +@node tinc examples +@section tinc examples Examples of some commands: @example -tincctl -n vpn dump graph | circo -Txlib -tincctl -n vpn pcap | tcpdump -r - -tincctl -n vpn top +tinc -n vpn dump graph | circo -Txlib +tinc -n vpn pcap | tcpdump -r - +tinc -n vpn top @end example -Example of configuring tinc using tincctl: +Example of configuring tinc using the tinc command: @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 +tinc -n vpn init foo +tinc -n vpn add Subnet 192.168.1.0/24 +tinc -n vpn add bar.Address bar.example.com +tinc -n vpn add ConnectTo bar +tinc -n vpn export | gpg --clearsign | mail -s "My config" vpnmaster@@example.com @end example @c ================================================================== -@node tincctl top -@section tincctl top +@node tinc top +@section tinc 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, @@ -2442,7 +2449,7 @@ 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 +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. @@ -2504,7 +2511,7 @@ 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 +The authentication scheme is described in @ref{Security}. 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 @@ -2566,7 +2573,7 @@ message ------------------------------------------------------------------ REQ_KEY origin destination | +--> name of the tinc daemon it wants the key from - +----------> name of the daemon that wants the key + +----------> name of the daemon that wants the key ANS_KEY origin destination 4ae0b0a82d6e0078 91 64 4 | | \______________/ | | +--> MAC length @@ -2591,10 +2598,10 @@ destination. @cindex PING @cindex PONG @example -daemon message +daemon message ------------------------------------------------------------------ -origin PING -dest. PONG +origin PING +dest. PONG ------------------------------------------------------------------ @end example @@ -2622,31 +2629,30 @@ 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 +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. +However, encryption in itself does not prevent an attacker from modifying the encrypted data. +Therefore, tinc also authenticates the data. +Finally, tinc uses sequence numbers (which themselves are also authenticated) to prevent an attacker from replaying valid packets. + +Since version 1.1pre3, tinc has two protocols used to protect your data; the legacy protocol, and the new Simple Peer-to-Peer Security (SPTPS) protocol. +The SPTPS protocol is designed to address some weaknesses in the legacy protocol. +The new authentication protocol is used when two nodes connect to each other that both have the ExperimentalProtocol option set to yes, +otherwise the legacy protocol will be used. @menu -* Authentication protocol:: +* Legacy authentication protocol:: +* Simple Peer-to-Peer Security:: * Encryption of network packets:: * Security issues:: @end menu @c ================================================================== -@node Authentication protocol -@subsection Authentication protocol +@node Legacy authentication protocol +@subsection Legacy 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 legacy authentication protocol @cindex ID @cindex META_KEY @@ -2660,28 +2666,50 @@ client server -client ID client 12 - | +---> version - +-------> name of tinc daemon +client ID client 17.2 + | | +-> minor protocol version + | +----> major protocol version + +--------> name of tinc daemon -server ID server 12 - | +---> version - +-------> name of tinc daemon +server ID server 17.2 + | | +-> minor protocol version + | +----> major protocol version + +--------> name of tinc daemon -client META_KEY 5f0823a93e35b69e...7086ec7866ce582b - \_________________________________/ - +-> RSAKEYLEN bits totally random string S1, - encrypted with server's public RSA key +client META_KEY 94 64 0 0 5f0823a93e35b69e...7086ec7866ce582b + | | | | \_________________________________/ + | | | | +-> RSAKEYLEN bits totally random string S1, + | | | | encrypted with server's public RSA key + | | | +-> compression level + | | +---> MAC length + | +------> digest algorithm NID + +---------> cipher algorithm NID -server META_KEY 6ab9c1640388f8f0...45d1a07f8a672630 - \_________________________________/ - +-> RSAKEYLEN bits totally random string S2, - encrypted with client's public RSA key +server META_KEY 94 64 0 0 6ab9c1640388f8f0...45d1a07f8a672630 + | | | | \_________________________________/ + | | | | +-> RSAKEYLEN bits totally random string S2, + | | | | encrypted with client's public RSA key + | | | +-> compression level + | | +---> MAC length + | +------> digest algorithm NID + +---------> cipher algorithm NID +-------------------------------------------------------------------------- +@end example + +The protocol allows each side to specify encryption algorithms and parameters, +but in practice they are always fixed, since older versions of tinc did not +allow them to be different from the default values. The cipher is always +Blowfish in OFB mode, the digest is SHA1, but the MAC length is zero and no +compression is used. From now on: - - the client will symmetrically encrypt outgoing traffic using S1 - - the server will symmetrically encrypt outgoing traffic using S2 +@itemize +@item the client will symmetrically encrypt outgoing traffic using S1 +@item the server will symmetrically encrypt outgoing traffic using S2 +@end itemize +@example +-------------------------------------------------------------------------- client CHALLENGE da02add1817c1920989ba6ae2a49cecbda0 \_________________________________/ +-> CHALLEN bits totally random string H1 @@ -2701,57 +2729,188 @@ their identity. Further information is exchanged. client ACK 655 123 0 | | +-> options - | +----> estimated weight - +--------> listening port of client + | +----> estimated weight + +--------> listening port of client server ACK 655 321 0 | | +-> options - | +----> estimated weight - +--------> listening port of server + | +----> estimated weight + +--------> listening port of server -------------------------------------------------------------------------- @end example -This new scheme has several improvements, both in efficiency and security. +This legacy authentication protocol has several weaknesses, pointed out by security export Peter Gutmann. +First, data is encrypted with RSA without padding. +Padding schemes are designed to prevent attacks when the size of the plaintext is not equal to the size of the RSA key. +Tinc always encrypts random nonces that have the same size as the RSA key, so we do not believe this leads to a break of the security. +There might be timing or other side-channel attacks against RSA encryption and decryption, tinc does not employ any protection against those. +Furthermore, both sides send identical messages to each other, there is no distinction between server and client, +which could make a MITM attack easier. +However, no exploit is known in which a third party who is not already trusted by other nodes in the VPN could gain access. +Finally, the RSA keys are used to directly encrypt the session keys, which means that if the RSA keys are compromised, it is possible to decrypt all previous VPN traffic. +In other words, the legacy protocol does not provide perfect forward secrecy. -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. +@c ================================================================== +@node Simple Peer-to-Peer Security +@subsection Simple Peer-to-Peer Security +@cindex SPTPS -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. +The SPTPS protocol is designed to address the weaknesses in the legacy protocol. +SPTPS is based on TLS 1.2, but has been simplified: there is no support for exchanging public keys, and there is no cipher suite negotiation. +Instead, SPTPS always uses a very strong cipher suite: +peers authenticate each other using 521 bits ECC keys, +Diffie-Hellman using ephemeral 521 bits ECC keys is used to provide perfect forward secrecy (PFS), +AES-256-CTR is used for encryption, and HMAC-SHA-256 for message authentication. -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. +Similar to TLS, messages are split up in records. +A complete logical record contains the following information: -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. +@itemize +@item uint32_t seqno (network byte order) +@item uint16_t length (network byte order) +@item uint8_t type +@item opaque data[length] +@item opaque hmac[HMAC_SIZE] (HMAC over all preceding fields) +@end itemize -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. +Depending on whether SPTPS records are sent via TCP or UDP, either the seqno or the length field is omitted on the wire +(but they are still included in the calculation of the HMAC); +for TCP packets are guaranteed to arrive in-order so we can infer the seqno, but packets can be split or merged, so we still need the length field to determine the boundaries between records; +for UDP packets we know that there is exactly one record per packet, and we know the length of a packet, but packets can be dropped, duplicated and/or reordered, so we need to include the seqno. +The type field is used to distinguish between application records or handshake records. +Types 0 to 127 are application records, type 128 is a handshake record, and types 129 to 255 are reserved. + +Before the initial handshake, no fields are encrypted, and the HMAC field is not present. +After the authentication handshake, the length (if present), type and data fields are encrypted, and the HMAC field is present. +For UDP packets, the seqno field is not encrypted, as it is used to determine the value of the counter used for encryption. + +The authentication consists of an exchange of Key EXchange, SIGnature and ACKnowledge messages, transmitted using type 128 records. + +Overview: + +@example +Initiator Responder +--------------------- +KEX -> + <- KEX +SIG -> + <- SIG + +...encrypt and HMAC using session keys from now on... + +App -> + <- App +... + ... + +...key renegotiation starts here... + +KEX -> + <- KEX +SIG -> + <- SIG +ACK -> + <- ACK + +...encrypt and HMAC using new session keys from now on... + +App -> + <- App +... + ... +--------------------- +@end example + +Note that the responder does not need to wait before it receives the first KEX message, +it can immediately send its own once it has accepted an incoming connection. + +Key EXchange message: + +@itemize +@item uint8_t kex_version (always 0 in this version of SPTPS) +@item opaque nonce[32] (random number) +@item opaque ecdh_key[ECDH_SIZE] +@end itemize + +SIGnature message: + +@itemize +@item opaque ecdsa_signature[ECDSA_SIZE] +@end itemize + +ACKnowledge message: + +@itemize +@item empty (only sent after key renegotiation) +@end itemize + +Remarks: + +@itemize +@item At the start, both peers generate a random nonce and an Elliptic Curve public key and send it to the other in the KEX message. +@item After receiving the other's KEX message, both KEX messages are concatenated (see below), + and the result is signed using ECDSA. + The result is sent to the other. +@item After receiving the other's SIG message, the signature is verified. + If it is correct, the shared secret is calculated from the public keys exchanged in the KEX message using the Elliptic Curve Diffie-Helman algorithm. +@item The shared secret key is expanded using a PRF. + Both nonces and the application specific label are also used as input for the PRF. +@item An ACK message is sent only when doing key renegotiation, and is sent using the old encryption keys. +@item The expanded key is used to key the encryption and HMAC algorithms. +@end itemize + +The signature is calculated over this string: + +@itemize +@item uint8_t initiator (0 = local peer, 1 = remote peer is initiator) +@item opaque remote_kex_message[1 + 32 + ECDH_SIZE] +@item opaque local_kex_message[1 + 32 + ECDH_SIZE] +@item opaque label[label_length] +@end itemize + +The PRF is calculated as follows: + +@itemize +@item A HMAC using SHA512 is used, the shared secret is used as the key. +@item For each block of 64 bytes, a HMAC is calculated. For block n: hmac[n] = + HMAC_SHA512(hmac[n - 1] + seed) +@item For the first block (n = 1), hmac[0] is given by HMAC_SHA512(zeroes + seed), + where zeroes is a block of 64 zero bytes. +@end itemize + +The seed is as follows: + +@itemize +@item const char[13] "key expansion" +@item opaque responder_nonce[32] +@item opaque initiator_nonce[32] +@item opaque label[label_length] +@end itemize + +The expanded key is used as follows: + +@itemize +@item opaque responder_cipher_key[CIPHER_KEYSIZE] +@item opaque responder_digest_key[DIGEST_KEYSIZE] +@item opaque initiator_cipher_key[CIPHER_KEYSIZE] +@item opaque initiator_digest_key[DIGEST_KEYSIZE] +@end itemize + +Where initiator_cipher_key is the key used by session initiator to encrypt +messages sent to the responder. + +When using 521 bits EC keys, the AES-256-CTR cipher and HMAC-SHA-256 digest algorithm, +the sizes are as follows: + +@example +ECDH_SIZE: 67 (= ceil(521/8) + 1) +ECDSA_SIZE: 141 (= 2 * ceil(521/8) + 9) +CIPHER_KEYSIZE: 48 (= 256/8 + 128/8) +DIGEST_KEYSIZE: 32 (= 256/8) +@end example + +Note that the cipher key also includes the initial value for the counter. @c ================================================================== @node Encryption of network packets @@ -2761,11 +2920,11 @@ an attacker) in the beginning of the encrypted stream. 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. +to retrieve it. @cindex UDP -The UDP packet containing the network packet from the VPN has the following layout: +The UDP packets can be either encrypted with the legacy protocol or with SPTPS. +In case of the legacy protocol, 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 @@ -2775,12 +2934,38 @@ The UDP packet containing the network packet from the VPN has the following layo 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. +is added to the UDP packet to prevent alteration of packets. +Tinc by default encrypts network packets using Blowfish with 128 bit keys in CBC mode +and uses 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. + +The SPTPS protocol is described in @ref{Simple Peer-to-Peer Security}. +For comparison, this is how SPTPS UDP packets look: + +@example +... | IP header | UDP header | seqno | type | VPN packet | MAC | UDP trailer + \__________________/\_____/ + | | + V +---> digest algorithm + Encrypted with symmetric cipher +@end example + +The difference is that the seqno is not encrypted, since the encryption cipher is used in CTR mode, +and therefore the seqno must be known before the packet can be decrypted. +Furthermore, the MAC is never truncated. +The SPTPS protocol always uses the AES-256-CTR cipher and HMAC-SHA-256 digest, +this cannot be changed. + @c ================================================================== @node Security issues @@ -2803,8 +2988,10 @@ 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. +in the legacy protocol of tinc, but it is not as strong as TLS or IPsec. + +This version of tinc comes with an improved protocol, called Simple Peer-to-Peer Security, +which aims to be as strong as TLS with one of the strongest cipher suites. Cryptography is a hard thing to get right. We cannot make any guarantees. Time, review and feedback are the only things that can diff --git a/doc/tincd.8.in b/doc/tincd.8.in index 88da75d..3c5886b 100644 --- a/doc/tincd.8.in +++ b/doc/tincd.8.in @@ -92,7 +92,7 @@ is omitted, the default is Store a cookie in .Ar FILENAME which allows -.Xr tincctl 8 +.Xr tinc 8 to authenticate. If .Ar FILE @@ -186,7 +186,7 @@ If you find any bugs, report them to tinc@tinc-vpn.org. .Sh TODO A lot, especially security auditing. .Sh SEE ALSO -.Xr tincctl 8 , +.Xr tinc 8 , .Xr tinc.conf 5 , .Pa http://www.tinc-vpn.org/ , .Pa http://www.cabal.org/ . diff --git a/src/Makefile.am b/src/Makefile.am index eeee152..c073eec 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ ## Produce this file with automake to get Makefile.in -sbin_PROGRAMS = tincd tincctl sptps_test +sbin_PROGRAMS = tincd tinc sptps_test EXTRA_DIST = linux bsd solaris cygwin mingw openssl gcrypt @@ -22,11 +22,11 @@ endif nodist_tincd_SOURCES = \ device.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c rsa.c -tincctl_SOURCES = \ +tinc_SOURCES = \ utils.c getopt.c getopt1.c dropin.c \ info.c list.c subnet_parse.c tincctl.c top.c names.c -nodist_tincctl_SOURCES = \ +nodist_tinc_SOURCES = \ ecdsagen.c rsagen.c sptps_test_SOURCES = \ @@ -37,7 +37,7 @@ if TUNEMU tincd_SOURCES += bsd/tunemu.c endif -tincctl_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) +tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) DEFAULT_INCLUDES = diff --git a/src/Makefile.in b/src/Makefile.in index b1d4551..48f7dad 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -52,7 +52,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -sbin_PROGRAMS = tincd$(EXEEXT) tincctl$(EXEEXT) sptps_test$(EXEEXT) +sbin_PROGRAMS = tincd$(EXEEXT) tinc$(EXEEXT) sptps_test$(EXEEXT) @UML_TRUE@am__append_1 = uml_device.c @VDE_TRUE@am__append_2 = vde_device.c @TUNEMU_TRUE@am__append_3 = bsd/tunemu.c @@ -79,14 +79,14 @@ am_sptps_test_OBJECTS = logger.$(OBJEXT) cipher.$(OBJEXT) \ sptps_test.$(OBJEXT) utils.$(OBJEXT) sptps_test_OBJECTS = $(am_sptps_test_OBJECTS) sptps_test_LDADD = $(LDADD) -am_tincctl_OBJECTS = utils.$(OBJEXT) getopt.$(OBJEXT) \ - getopt1.$(OBJEXT) dropin.$(OBJEXT) info.$(OBJEXT) \ - list.$(OBJEXT) subnet_parse.$(OBJEXT) tincctl.$(OBJEXT) \ - top.$(OBJEXT) names.$(OBJEXT) -nodist_tincctl_OBJECTS = ecdsagen.$(OBJEXT) rsagen.$(OBJEXT) -tincctl_OBJECTS = $(am_tincctl_OBJECTS) $(nodist_tincctl_OBJECTS) +am_tinc_OBJECTS = utils.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ + dropin.$(OBJEXT) info.$(OBJEXT) list.$(OBJEXT) \ + subnet_parse.$(OBJEXT) tincctl.$(OBJEXT) top.$(OBJEXT) \ + names.$(OBJEXT) +nodist_tinc_OBJECTS = ecdsagen.$(OBJEXT) rsagen.$(OBJEXT) +tinc_OBJECTS = $(am_tinc_OBJECTS) $(nodist_tinc_OBJECTS) am__DEPENDENCIES_1 = -tincctl_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +tinc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am__tincd_SOURCES_DIST = utils.c getopt.c getopt1.c list.c \ splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c \ hash.c buffer.c conf.c connection.c control.c edge.c graph.c \ @@ -128,10 +128,9 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(sptps_test_SOURCES) $(tincctl_SOURCES) \ - $(nodist_tincctl_SOURCES) $(tincd_SOURCES) \ - $(nodist_tincd_SOURCES) -DIST_SOURCES = $(sptps_test_SOURCES) $(tincctl_SOURCES) \ +SOURCES = $(sptps_test_SOURCES) $(tinc_SOURCES) $(nodist_tinc_SOURCES) \ + $(tincd_SOURCES) $(nodist_tincd_SOURCES) +DIST_SOURCES = $(sptps_test_SOURCES) $(tinc_SOURCES) \ $(am__tincd_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ @@ -258,18 +257,18 @@ tincd_SOURCES = utils.c getopt.c getopt1.c list.c splay_tree.c \ nodist_tincd_SOURCES = \ device.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c rsa.c -tincctl_SOURCES = \ +tinc_SOURCES = \ utils.c getopt.c getopt1.c dropin.c \ info.c list.c subnet_parse.c tincctl.c top.c names.c -nodist_tincctl_SOURCES = \ +nodist_tinc_SOURCES = \ ecdsagen.c rsagen.c sptps_test_SOURCES = \ logger.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c \ sptps.c sptps_test.c utils.c -tincctl_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) +tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) DEFAULT_INCLUDES = noinst_HEADERS = \ xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \ @@ -357,9 +356,9 @@ clean-sbinPROGRAMS: sptps_test$(EXEEXT): $(sptps_test_OBJECTS) $(sptps_test_DEPENDENCIES) $(EXTRA_sptps_test_DEPENDENCIES) @rm -f sptps_test$(EXEEXT) $(LINK) $(sptps_test_OBJECTS) $(sptps_test_LDADD) $(LIBS) -tincctl$(EXEEXT): $(tincctl_OBJECTS) $(tincctl_DEPENDENCIES) $(EXTRA_tincctl_DEPENDENCIES) - @rm -f tincctl$(EXEEXT) - $(LINK) $(tincctl_OBJECTS) $(tincctl_LDADD) $(LIBS) +tinc$(EXEEXT): $(tinc_OBJECTS) $(tinc_DEPENDENCIES) $(EXTRA_tinc_DEPENDENCIES) + @rm -f tinc$(EXEEXT) + $(LINK) $(tinc_OBJECTS) $(tinc_LDADD) $(LIBS) tincd$(EXEEXT): $(tincd_OBJECTS) $(tincd_DEPENDENCIES) $(EXTRA_tincd_DEPENDENCIES) @rm -f tincd$(EXEEXT) $(LINK) $(tincd_OBJECTS) $(tincd_LDADD) $(LIBS) diff --git a/src/event.c b/src/event.c index 6b730f6..095e7c3 100644 --- a/src/event.c +++ b/src/event.c @@ -245,6 +245,12 @@ bool event_loop(void) { return true; } +void event_flush_output(void) { + for splay_each(io_t, io, &io_tree) + if(FD_ISSET(io->fd, &writefds)) + io->cb(io->data, IO_WRITE); +} + void event_exit(void) { running = false; } diff --git a/src/event.h b/src/event.h index d0129d0..bd91b7b 100644 --- a/src/event.h +++ b/src/event.h @@ -65,6 +65,7 @@ extern void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum); extern void signal_del(signal_t *sig); extern bool event_loop(void); +extern void event_flush_output(void); extern void event_exit(void); #endif diff --git a/src/graph.c b/src/graph.c index 7079f93..4506379 100644 --- a/src/graph.c +++ b/src/graph.c @@ -204,7 +204,7 @@ static void check_reachability(void) { for splay_each(node_t, n, node_tree) { if(n->status.visited != n->status.reachable) { n->status.reachable = !n->status.reachable; - n->last_state_change = time(NULL); + n->last_state_change = now.tv_sec; if(n->status.reachable) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Node %s (%s) became reachable", diff --git a/src/mingw/device.c b/src/mingw/device.c index aa05972..ac83d8c 100644 --- a/src/mingw/device.c +++ b/src/mingw/device.c @@ -80,6 +80,7 @@ static DWORD WINAPI tapreader(void *bla) { packet.len = len; packet.priority = 0; route(myself, &packet); + event_flush_output(); LeaveCriticalSection(&mutex); } } diff --git a/src/net.c b/src/net.c index 0d374e6..1487e81 100644 --- a/src/net.c +++ b/src/net.c @@ -406,7 +406,7 @@ int reload_configuration(void) { free(fname); } - last_config_check = time(NULL); + last_config_check = now.tv_sec; return 0; } diff --git a/src/net.h b/src/net.h index 8d236da..879dfff 100644 --- a/src/net.h +++ b/src/net.h @@ -135,6 +135,7 @@ extern int udp_sndbuf; extern bool do_prune; extern char *myport; extern int autoconnect; +extern bool disablebuggypeers; extern int contradicting_add_edge; extern int contradicting_del_edge; extern time_t last_config_check; diff --git a/src/net_packet.c b/src/net_packet.c index 5fd5632..27ca714 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -443,6 +443,9 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) { void receive_tcppacket(connection_t *c, const char *buffer, int len) { vpn_packet_t outpkt; + if(len > sizeof outpkt.data) + return; + outpkt.len = len; if(c->options & OPTION_TCPONLY) outpkt.priority = 0; @@ -458,7 +461,7 @@ static void send_sptps_packet(node_t *n, vpn_packet_t *origpkt) { logger(DEBUG_TRAFFIC, LOG_INFO, "No valid key known yet for %s (%s)", n->name, n->hostname); if(!n->status.waitingforkey) send_req_key(n); - else if(n->last_req_key + 10 < time(NULL)) { + else if(n->last_req_key + 10 < now.tv_sec) { logger(DEBUG_ALWAYS, LOG_DEBUG, "No key from %s after 10 seconds, restarting SPTPS", n->name); sptps_stop(&n->sptps); n->status.waitingforkey = false; diff --git a/src/net_setup.c b/src/net_setup.c index a4fd3a4..bf0c5a5 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -52,6 +52,7 @@ char *proxyuser; char *proxypass; proxytype_t proxytype; int autoconnect; +bool disablebuggypeers; char *scriptinterpreter; char *scriptextension; @@ -598,6 +599,8 @@ bool setup_myself_reloadable(void) { get_config_int(lookup_config(config_tree, "AutoConnect"), &autoconnect); + get_config_bool(lookup_config(config_tree, "DisableBuggyPeers"), &disablebuggypeers); + return true; } @@ -751,7 +754,7 @@ static bool setup_myself(void) { myself->nexthop = myself; myself->via = myself; myself->status.reachable = true; - myself->last_state_change = time(NULL); + myself->last_state_change = now.tv_sec; myself->status.sptps = experimental; node_add(myself); @@ -958,7 +961,7 @@ static bool setup_myself(void) { return false; } - last_config_check = time(NULL); + last_config_check = now.tv_sec; return true; } diff --git a/src/net_socket.c b/src/net_socket.c index a28be54..5332ed2 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -294,7 +294,7 @@ void retry_outgoing(outgoing_t *outgoing) { void finish_connecting(connection_t *c) { logger(DEBUG_CONNECTIONS, LOG_INFO, "Connected to %s (%s)", c->name, c->hostname); - c->last_ping_time = time(NULL); + c->last_ping_time = now.tv_sec; c->status.connecting = false; send_id(c); @@ -349,6 +349,9 @@ static void do_outgoing_pipe(connection_t *c, char *command) { } static void handle_meta_write(connection_t *c) { + if(c->outbuf.len <= c->outbuf.offset) + return; + ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0); if(outlen <= 0) { if(!errno || errno == EPIPE) { @@ -505,7 +508,7 @@ begin: c->outdigest = myself->connection->outdigest; c->outmaclength = myself->connection->outmaclength; c->outcompression = myself->connection->outcompression; - c->last_ping_time = time(NULL); + c->last_ping_time = now.tv_sec; connection_add(c); @@ -568,7 +571,7 @@ void handle_new_meta_connection(void *data, int flags) { c->address = sa; c->hostname = sockaddr2hostname(&sa); c->socket = fd; - c->last_ping_time = time(NULL); + c->last_ping_time = now.tv_sec; logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); @@ -607,7 +610,7 @@ void handle_new_unix_connection(void *data, int flags) { c->address = sa; c->hostname = xstrdup("localhost port unix"); c->socket = fd; - c->last_ping_time = time(NULL); + c->last_ping_time = now.tv_sec; logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname); diff --git a/src/protocol.c b/src/protocol.c index fc16ffe..ad0fa8d 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -195,7 +195,7 @@ bool seen_request(const char *request) { } else { new = xmalloc(sizeof *new); new->request = xstrdup(request); - new->firstseen = time(NULL); + new->firstseen = now.tv_sec; splay_insert(past_request_tree, new); timeout_add(&past_request_timeout, age_past_requests, NULL, &(struct timeval){10, rand() % 100000}); return false; diff --git a/src/protocol_auth.c b/src/protocol_auth.c index f4a30a4..5f2dcaa 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -160,7 +160,7 @@ bool id_h(connection_t *c, const char *request) { if(name[0] == '^' && !strcmp(name + 1, controlcookie)) { c->status.control = true; c->allow_request = CONTROL; - c->last_ping_time = time(NULL) + 3600; + c->last_ping_time = now.tv_sec + 3600; free(c->name); c->name = xstrdup(""); @@ -510,6 +510,17 @@ bool send_ack(connection_t *c) { static void send_everything(connection_t *c) { /* Send all known subnets and edges */ + if(disablebuggypeers) { + static struct { + vpn_packet_t pkt; + char pad[MAXBUFSIZE - MAXSIZE]; + } zeropkt; + + memset(&zeropkt, 0, sizeof zeropkt); + zeropkt.pkt.len = MAXBUFSIZE; + send_tcppacket(c, &zeropkt.pkt); + } + if(tunnelserver) { for splay_each(subnet_t, s, myself->subnet_tree) send_add_subnet(c, s); diff --git a/src/protocol_key.c b/src/protocol_key.c index 115845a..57377b2 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -111,7 +111,7 @@ bool send_req_key(node_t *to) { sptps_stop(&to->sptps); to->status.validkey = false; to->status.waitingforkey = true; - to->last_req_key = time(NULL); + to->last_req_key = now.tv_sec; to->incompression = myself->incompression; return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof label, send_initial_sptps_data, receive_sptps_record); } @@ -169,7 +169,7 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, in sptps_stop(&from->sptps); from->status.validkey = false; from->status.waitingforkey = true; - from->last_req_key = time(NULL); + from->last_req_key = now.tv_sec; sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof label, send_sptps_data, receive_sptps_record); sptps_receive_data(&from->sptps, buf, len); return true; diff --git a/src/protocol_misc.c b/src/protocol_misc.c index 7617091..a4ad73d 100644 --- a/src/protocol_misc.c +++ b/src/protocol_misc.c @@ -89,7 +89,7 @@ bool termreq_h(connection_t *c, const char *request) { bool send_ping(connection_t *c) { c->status.pinged = true; - c->last_ping_time = time(NULL); + c->last_ping_time = now.tv_sec; return send_request(c, "%d", PING); } diff --git a/src/route.c b/src/route.c index 1896374..00ba4c0 100644 --- a/src/route.c +++ b/src/route.c @@ -229,7 +229,7 @@ static void learn_mac(mac_t *address) { subnet = new_subnet(); subnet->type = SUBNET_MAC; - subnet->expires = time(NULL) + macexpire; + subnet->expires = now.tv_sec + macexpire; subnet->net.mac.address = *address; subnet->weight = 10; subnet_add(myself, subnet); @@ -244,7 +244,7 @@ static void learn_mac(mac_t *address) { timeout_add(&age_subnets_timeout, age_subnets, NULL, &(struct timeval){10, rand() % 100000}); } else { if(subnet->expires) - subnet->expires = time(NULL) + macexpire; + subnet->expires = now.tv_sec + macexpire; } } diff --git a/src/sptps_test.c b/src/sptps_test.c index 9db63ff..2a9fca0 100644 --- a/src/sptps_test.c +++ b/src/sptps_test.c @@ -77,8 +77,8 @@ int main(int argc, char *argv[]) { memset(&hint, 0, sizeof hint); hint.ai_family = AF_UNSPEC; - hint.ai_socktype = SOCK_STREAM; - hint.ai_protocol = IPPROTO_TCP; + hint.ai_socktype = datagram ? SOCK_DGRAM : SOCK_STREAM; + hint.ai_protocol = datagram ? IPPROTO_UDP : IPPROTO_TCP; hint.ai_flags = initiator ? 0 : AI_PASSIVE; if(getaddrinfo(initiator ? argv[3] : NULL, initiator ? argv[4] : argv[3], &hint, &ai) || !ai) { @@ -86,7 +86,7 @@ int main(int argc, char *argv[]) { return 1; } - int sock = socket(ai->ai_family, SOCK_STREAM, IPPROTO_TCP); + int sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if(sock < 0) { fprintf(stderr, "Could not create socket: %s\n", strerror(errno)); return 1; @@ -106,16 +106,35 @@ int main(int argc, char *argv[]) { fprintf(stderr, "Could not bind socket: %s\n", strerror(errno)); return 1; } - if(listen(sock, 1)) { - fprintf(stderr, "Could not listen on socket: %s\n", strerror(errno)); - return 1; - } - fprintf(stderr, "Listening...\n"); - sock = accept(sock, NULL, NULL); - if(sock < 0) { - fprintf(stderr, "Could not accept connection: %s\n", strerror(errno)); - return 1; + if(!datagram) { + if(listen(sock, 1)) { + fprintf(stderr, "Could not listen on socket: %s\n", strerror(errno)); + return 1; + } + fprintf(stderr, "Listening...\n"); + + sock = accept(sock, NULL, NULL); + if(sock < 0) { + fprintf(stderr, "Could not accept connection: %s\n", strerror(errno)); + return 1; + } + } else { + fprintf(stderr, "Listening...\n"); + + char buf[65536]; + struct sockaddr addr; + socklen_t addrlen = sizeof addr; + + if(recvfrom(sock, buf, sizeof buf, MSG_PEEK, &addr, &addrlen) <= 0) { + fprintf(stderr, "Could not read from socket: %s\n", strerror(errno)); + return 1; + } + + if(connect(sock, &addr, addrlen)) { + fprintf(stderr, "Could not accept connection: %s\n", strerror(errno)); + return 1; + } } fprintf(stderr, "Connected\n"); diff --git a/src/tincctl.c b/src/tincctl.c index 45bf6ee..e022cdd 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -112,11 +112,10 @@ static void usage(bool status) { "\n" "Valid commands are:\n" " init [name] Create initial configuration files.\n" - " config Change configuration:\n" - " [get] VARIABLE - print current value of VARIABLE\n" - " [set] VARIABLE VALUE - set VARIABLE to VALUE\n" - " add VARIABLE VALUE - add VARIABLE with the given VALUE\n" - " del VARIABLE [VALUE] - remove VARIABLE [only ones with watching VALUE]\n" + " get VARIABLE Print current value of VARIABLE\n" + " set VARIABLE VALUE Set VARIABLE to VALUE\n" + " add VARIABLE VALUE Add VARIABLE with the given VALUE\n" + " del VARIABLE [VALUE] Remove VARIABLE [only ones with watching VALUE]\n" " start [tincd options] Start tincd.\n" " stop Stop tincd.\n" " restart Restart tincd.\n" @@ -1148,7 +1147,7 @@ static int cmd_top(int argc, char *argv[]) { top(fd); return 0; #else - fprintf(stderr, "This version of tincctl was compiled without support for the curses library.\n"); + fprintf(stderr, "This version of tinc was compiled without support for the curses library.\n"); return 1; #endif } @@ -1199,10 +1198,11 @@ static int rstrip(char *value) { return len; } -static char *get_my_name() { +static char *get_my_name(bool verbose) { FILE *f = fopen(tinc_conf, "r"); if(!f) { - fprintf(stderr, "Could not open %s: %s\n", tinc_conf, strerror(errno)); + if(verbose) + fprintf(stderr, "Could not open %s: %s\n", tinc_conf, strerror(errno)); return NULL; } @@ -1228,7 +1228,8 @@ static char *get_my_name() { } fclose(f); - fprintf(stderr, "Could not find Name in %s.\n", tinc_conf); + if(verbose) + fprintf(stderr, "Could not find Name in %s.\n", tinc_conf); return NULL; } @@ -1309,6 +1310,9 @@ static int cmd_config(int argc, char *argv[]) { return 1; } + if(strcasecmp(argv[0], "config")) + argv--, argc++; + int action = -2; if(!strcasecmp(argv[1], "get")) { argv++, argc--; @@ -1402,7 +1406,7 @@ static int cmd_config(int argc, char *argv[]) { /* Should this go into our own host config file? */ if(!node && !(variables[i].type & VAR_SERVER)) { - node = get_my_name(); + node = get_my_name(true); if(!node) return 1; } @@ -1692,6 +1696,9 @@ static int cmd_generate_keys(int argc, char *argv[]) { return 1; } + if(!name) + name = get_my_name(false); + return !(rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true) && ecdsa_keygen(true)); } @@ -1701,6 +1708,9 @@ static int cmd_generate_rsa_keys(int argc, char *argv[]) { return 1; } + if(!name) + name = get_my_name(false); + return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true); } @@ -1710,6 +1720,9 @@ static int cmd_generate_ecdsa_keys(int argc, char *argv[]) { return 1; } + if(!name) + name = get_my_name(false); + return !ecdsa_keygen(true); } @@ -1831,7 +1844,7 @@ static int cmd_export(int argc, char *argv[]) { return 1; } - char *name = get_my_name(); + char *name = get_my_name(true); if(!name) return 1; @@ -1961,6 +1974,7 @@ static int cmd_exchange_all(int argc, char *argv[]) { static const struct { const char *command; int (*function)(int argc, char *argv[]); + bool hidden; } commands[] = { {"start", cmd_start}, {"stop", cmd_stop}, @@ -1976,7 +1990,11 @@ static const struct { {"pcap", cmd_pcap}, {"log", cmd_log}, {"pid", cmd_pid}, - {"config", cmd_config}, + {"config", cmd_config, true}, + {"add", cmd_config}, + {"del", cmd_config}, + {"get", cmd_config}, + {"set", cmd_config}, {"init", cmd_init}, {"generate-keys", cmd_generate_keys}, {"generate-rsa-keys", cmd_generate_rsa_keys}, @@ -2003,7 +2021,7 @@ static char *complete_command(const char *text, int state) { i++; while(commands[i].command) { - if(!strncasecmp(commands[i].command, text, strlen(text))) + if(!commands[i].hidden && !strncasecmp(commands[i].command, text, strlen(text))) return xstrdup(commands[i].command); i++; } @@ -2030,42 +2048,24 @@ static char *complete_dump(const char *text, int state) { } static char *complete_config(const char *text, int state) { - const char *sub[] = {"get", "set", "add", "del"}; static int i; - if(!state) { - i = 0; - if(!strchr(rl_line_buffer + 7, ' ')) - i = -4; - else { - bool found = false; - for(int i = 0; i < 4; i++) { - if(!strncasecmp(rl_line_buffer + 7, sub[i], strlen(sub[i])) && rl_line_buffer[7 + strlen(sub[i])] == ' ') { - found = true; - break; - } - } - if(!found) - return NULL; - } - } else { - i++; - } - while(i < 0 || variables[i].name) { - if(i < 0 && !strncasecmp(sub[i + 4], text, strlen(text))) - return xstrdup(sub[i + 4]); - if(i >= 0) { - char *dot = strchr(text, '.'); - if(dot) { - if((variables[i].type & VAR_HOST) && !strncasecmp(variables[i].name, dot + 1, strlen(dot + 1))) { - char *match; - xasprintf(&match, "%.*s.%s", dot - text, text, variables[i].name); - return match; - } - } else { - if(!strncasecmp(variables[i].name, text, strlen(text))) - return xstrdup(variables[i].name); + if(!state) + i = 0; + else + i++; + + while(variables[i].name) { + char *dot = strchr(text, '.'); + if(dot) { + if((variables[i].type & VAR_HOST) && !strncasecmp(variables[i].name, dot + 1, strlen(dot + 1))) { + char *match; + xasprintf(&match, "%.*s.%s", dot - text, text, variables[i].name); + return match; } + } else { + if(!strncasecmp(variables[i].name, text, strlen(text))) + return xstrdup(variables[i].name); } i++; } @@ -2118,7 +2118,13 @@ static char **completion (const char *text, int start, int end) { matches = rl_completion_matches(text, complete_command); else if(!strncasecmp(rl_line_buffer, "dump ", 5)) matches = rl_completion_matches(text, complete_dump); - else if(!strncasecmp(rl_line_buffer, "config ", 7)) + else if(!strncasecmp(rl_line_buffer, "add ", 4)) + matches = rl_completion_matches(text, complete_config); + else if(!strncasecmp(rl_line_buffer, "del ", 4)) + matches = rl_completion_matches(text, complete_config); + else if(!strncasecmp(rl_line_buffer, "get ", 4)) + matches = rl_completion_matches(text, complete_config); + else if(!strncasecmp(rl_line_buffer, "set ", 4)) matches = rl_completion_matches(text, complete_config); else if(!strncasecmp(rl_line_buffer, "info ", 5)) matches = rl_completion_matches(text, complete_info); diff --git a/src/tincd.c b/src/tincd.c index 8412c8f..333a207 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -346,7 +346,8 @@ int main(int argc, char **argv) { /* Slllluuuuuuurrrrp! */ - srand(time(NULL)); + gettimeofday(&now, NULL); + srand(now.tv_sec + now.tv_usec); crypto_init(); if(!read_server_config())