+@node Technical information
+@chapter Technical information
+
+
+@menu
+* The connection::
+* The meta-protocol::
+* Security::
+@end menu
+
+
+@c ==================================================================
+@node The connection
+@section The connection
+
+@cindex connection
+Tinc is a daemon that takes VPN data and transmit that to another host
+computer over the existing Internet infrastructure.
+
+@menu
+* The UDP tunnel::
+* The meta-connection::
+@end menu
+
+
+@c ==================================================================
+@node The UDP tunnel
+@subsection The UDP tunnel
+
+@cindex virtual network device
+@cindex frame type
+The data itself is read from a character device file, the so-called
+@emph{virtual network device}. This device is associated with a network
+interface. Any data sent to this interface can be read from the device,
+and any data written to the device gets sent from the interface.
+There are two possible types of virtual network devices:
+`tun' style, which are point-to-point devices which can only handle IPv4 and/or IPv6 packets,
+and `tap' style, which are Ethernet devices and handle complete Ethernet frames.
+
+So when tinc reads an Ethernet frame from the device, it determines its
+type. When tinc is in it's default routing mode, it can handle IPv4 and IPv6
+packets. Depending on the Subnet lines, it will send the packets off to their destination IP address.
+In the `switch' and `hub' mode, tinc will use broadcasts and MAC address discovery
+to deduce the destination of the packets.
+Since the latter modes only depend on the link layer information,
+any protocol that runs over Ethernet is supported (for instance IPX and Appletalk).
+However, only `tap' style devices provide this information.
+
+After the destination has been determined,
+the packet will be compressed (optionally),
+a sequence number will be added to the packet,
+the packet will then be encrypted
+and a message authentication code will be appended.
+
+@cindex encapsulating
+@cindex UDP
+When that is done, time has come to actually transport the
+packet to the destination computer. We do this by sending the packet
+over an UDP connection to the destination host. This is called
+@emph{encapsulating}, the VPN packet (though now encrypted) is
+encapsulated in another IP datagram.
+
+When the destination receives this packet, the same thing happens, only
+in reverse. So it checks the message authentication code, decrypts the contents of the UDP datagram,
+checks the sequence number
+and writes the decrypted information to its own virtual network device.
+
+If the virtual network device is a `tun' device (a point-to-point tunnel),
+there is no problem for the kernel to accept a packet.
+However, if it is a `tap' device (this is the only available type on FreeBSD),
+the destination MAC address must match that of the virtual network interface.
+If tinc is in it's default routing mode, ARP does not work, so the correct destination MAC
+can not be known by the sending host.
+Tinc solves this by letting the receiving end detect the MAC address of its own virtual network interface
+and overwriting the destination MAC address of the received packet.
+
+In switch or hub modes ARP does work so the sender already knows the correct destination MAC address.
+In those modes every interface should have a unique MAC address, so make sure they are not the same.
+Because switch and hub modes rely on MAC addresses to function correctly,
+these modes cannot be used on the following operating systems which don't have a `tap' style virtual network device:
+OpenBSD, NetBSD, Darwin and Solaris.
+
+
+@c ==================================================================
+@node The meta-connection
+@subsection The meta-connection
+
+Having only a UDP connection available is not enough. Though suitable
+for transmitting data, we want to be able to reliably send other
+information, such as routing and session key information to somebody.
+
+@cindex TCP
+TCP is a better alternative, because it already contains protection
+against information being lost, unlike UDP.
+
+So we establish two connections. One for the encrypted VPN data, and one
+for other information, the meta-data. Hence, we call the second
+connection the meta-connection. We can now be sure that the
+meta-information doesn't get lost on the way to another computer.
+
+@cindex data-protocol
+@cindex meta-protocol
+Like with any communication, we must have a protocol, so that everybody
+knows what everything stands for, and how she should react. Because we
+have two connections, we also have two protocols. The protocol used for
+the UDP data is the ``data-protocol,'' the other one is the
+``meta-protocol.''
+
+The reason we don't use TCP for both protocols is that UDP is much
+better for encapsulation, even while it is less reliable. The real
+problem is that when TCP would be used to encapsulate a TCP stream
+that's on the private network, for every packet sent there would be
+three ACKs sent instead of just one. Furthermore, if there would be
+a timeout, both TCP streams would sense the timeout, and both would
+start re-sending packets.
+
+
+@c ==================================================================
+@node The meta-protocol
+@section The meta-protocol
+
+The meta protocol is used to tie all tinc daemons together, and
+exchange information about which tinc daemon serves which virtual
+subnet.
+
+The meta protocol consists of requests that can be sent to the other
+side. Each request has a unique number and several parameters. All
+requests are represented in the standard ASCII character set. It is
+possible to use tools such as telnet or netcat to connect to a tinc
+daemon started with the --bypass-security option
+and to read and write requests by hand, provided that one
+understands the numeric codes sent.
+
+The authentication scheme is described in @ref{Authentication protocol}. After a
+successful authentication, the server and the client will exchange all the
+information about other tinc daemons and subnets they know of, so that both
+sides (and all the other tinc daemons behind them) have their information
+synchronised.
+
+@cindex ADD_EDGE
+@cindex ADD_SUBNET
+@example
+message
+------------------------------------------------------------------
+ADD_EDGE node1 node2 21.32.43.54 655 222 0
+ | | | | | +-> options
+ | | | | +----> weight
+ | | | +--------> UDP port of node2
+ | | +----------------> real address of node2
+ | +-------------------------> name of destination node
+ +-------------------------------> name of source node
+
+ADD_SUBNET node 192.168.1.0/24
+ | | +--> prefixlength
+ | +--------> network address
+ +------------------> owner of this subnet
+------------------------------------------------------------------
+@end example
+
+The ADD_EDGE messages are to inform other tinc daemons that a connection between
+two nodes exist. The address of the destination node is available so that
+VPN packets can be sent directly to that node.
+
+The ADD_SUBNET messages inform other tinc daemons that certain subnets belong
+to certain nodes. tinc will use it to determine to which node a VPN packet has
+to be sent.
+
+@cindex DEL_EDGE
+@cindex DEL_SUBNET
+@example
+message
+------------------------------------------------------------------
+DEL_EDGE node1 node2
+ | +----> name of destination node
+ +----------> name of source node
+
+DEL_SUBNET node 192.168.1.0/24
+ | | +--> prefixlength
+ | +--------> network address
+ +------------------> owner of this subnet
+------------------------------------------------------------------
+@end example
+
+In case a connection between two daemons is closed or broken, DEL_EDGE messages
+are sent to inform the other daemons of that fact. Each daemon will calculate a
+new route to the the daemons, or mark them unreachable if there isn't any.
+
+@cindex REQ_KEY
+@cindex ANS_KEY
+@cindex KEY_CHANGED
+@example
+message
+------------------------------------------------------------------
+REQ_KEY origin destination
+ | +--> name of the tinc daemon it wants the key from
+ +----------> name of the daemon that wants the key
+
+ANS_KEY origin destination 4ae0b0a82d6e0078 91 64 4
+ | | \______________/ | | +--> MAC length
+ | | | | +-----> digest algorithm
+ | | | +--------> cipher algorithm
+ | | +--> 128 bits key
+ | +--> name of the daemon that wants the key
+ +----------> name of the daemon that uses this key
+
+KEY_CHANGED origin
+ +--> daemon that has changed it's packet key
+------------------------------------------------------------------
+@end example
+
+The keys used to encrypt VPN packets are not sent out directly. This is
+because it would generate a lot of traffic on VPNs with many daemons, and
+chances are that not every tinc daemon will ever send a packet to every
+other daemon. Instead, if a daemon needs a key it sends a request for it
+via the meta connection of the nearest hop in the direction of the
+destination.
+
+@cindex PING
+@cindex PONG
+@example
+daemon message
+------------------------------------------------------------------
+origin PING
+dest. PONG
+------------------------------------------------------------------
+@end example
+
+There is also a mechanism to check if hosts are still alive. Since network
+failures or a crash can cause a daemon to be killed without properly
+shutting down the TCP connection, this is necessary to keep an up to date
+connection list. PINGs are sent at regular intervals, except when there
+is also some other traffic. A little bit of salt (random data) is added
+with each PING and PONG message, to make sure that long sequences of PING/PONG
+messages without any other traffic won't result in known plaintext.
+
+This basically covers what is sent over the meta connection by tinc.
+
+
+@c ==================================================================
+@node Security
+@section Security
+
+@cindex TINC
+@cindex Cabal
+Tinc got its name from ``TINC,'' short for @emph{There Is No Cabal}; the
+alleged Cabal was/is an organisation that was said to keep an eye on the
+entire Internet. As this is exactly what you @emph{don't} want, we named
+the tinc project after TINC.
+
+@cindex SVPN
+But in order to be ``immune'' to eavesdropping, you'll have to encrypt
+your data. Because tinc is a @emph{Secure} VPN (SVPN) daemon, it does
+exactly that: encrypt.
+Tinc by default uses blowfish encryption with 128 bit keys in CBC mode, 32 bit
+sequence numbers and 4 byte long message authentication codes to make sure
+eavesdroppers cannot get and cannot change any information at all from the
+packets they can intercept. The encryption algorithm and message authentication
+algorithm can be changed in the configuration. The length of the message
+authentication codes is also adjustable. The length of the key for the
+encryption algorithm is always the default length used by OpenSSL.
+
+@menu
+* Authentication protocol::
+* Encryption of network packets::
+* Security issues::
+@end menu
+
+
+@c ==================================================================
+@node Authentication protocol
+@subsection Authentication protocol
+
+@cindex authentication
+A new scheme for authentication in tinc has been devised, which offers some
+improvements over the protocol used in 1.0pre2 and 1.0pre3. Explanation is
+below.
+
+@cindex ID
+@cindex META_KEY
+@cindex CHALLENGE
+@cindex CHAL_REPLY
+@cindex ACK
+@example
+daemon message
+--------------------------------------------------------------------------
+client <attempts connection>
+
+server <accepts connection>
+
+client ID client 12
+ | +---> version
+ +-------> name of tinc daemon
+
+server ID server 12
+ | +---> version
+ +-------> name of tinc daemon
+
+client META_KEY 5f0823a93e35b69e...7086ec7866ce582b
+ \_________________________________/
+ +-> RSAKEYLEN bits totally random string S1,
+ encrypted with server's public RSA key
+
+server META_KEY 6ab9c1640388f8f0...45d1a07f8a672630
+ \_________________________________/
+ +-> RSAKEYLEN bits totally random string S2,
+ encrypted with client's public RSA key
+
+From now on:
+ - the client will symmetrically encrypt outgoing traffic using S1
+ - the server will symmetrically encrypt outgoing traffic using S2
+
+client CHALLENGE da02add1817c1920989ba6ae2a49cecbda0
+ \_________________________________/
+ +-> CHALLEN bits totally random string H1
+
+server CHALLENGE 57fb4b2ccd70d6bb35a64c142f47e61d57f
+ \_________________________________/
+ +-> CHALLEN bits totally random string H2
+
+client CHAL_REPLY 816a86
+ +-> 160 bits SHA1 of H2
+
+server CHAL_REPLY 928ffe
+ +-> 160 bits SHA1 of H1
+
+After the correct challenge replies are received, both ends have proved
+their identity. Further information is exchanged.
+
+client ACK 655 123 0
+ | | +-> options
+ | +----> estimated weight
+ +--------> listening port of client
+
+server ACK 655 321 0
+ | | +-> options
+ | +----> estimated weight
+ +--------> listening port of server
+--------------------------------------------------------------------------
+@end example
+
+This new scheme has several improvements, both in efficiency and security.
+
+First of all, the server sends exactly the same kind of messages over the wire
+as the client. The previous versions of tinc first authenticated the client,
+and then the server. This scheme even allows both sides to send their messages
+simultaneously, there is no need to wait for the other to send something first.
+This means that any calculations that need to be done upon sending or receiving
+a message can also be done in parallel. This is especially important when doing
+RSA encryption/decryption. Given that these calculations are the main part of
+the CPU time spent for the authentication, speed is improved by a factor 2.
+
+Second, only one RSA encrypted message is sent instead of two. This reduces the
+amount of information attackers can see (and thus use for a cryptographic
+attack). It also improves speed by a factor two, making the total speedup a
+factor 4.
+
+Third, and most important:
+The symmetric cipher keys are exchanged first, the challenge is done
+afterwards. In the previous authentication scheme, because a man-in-the-middle
+could pass the challenge/chal_reply phase (by just copying the messages between
+the two real tinc daemons), but no information was exchanged that was really
+needed to read the rest of the messages, the challenge/chal_reply phase was of
+no real use. The man-in-the-middle was only stopped by the fact that only after
+the ACK messages were encrypted with the symmetric cipher. Potentially, it
+could even send it's own symmetric key to the server (if it knew the server's
+public key) and read some of the metadata the server would send it (it was
+impossible for the mitm to read actual network packets though). The new scheme
+however prevents this.
+
+This new scheme makes sure that first of all, symmetric keys are exchanged. The
+rest of the messages are then encrypted with the symmetric cipher. Then, each
+side can only read received messages if they have their private key. The
+challenge is there to let the other side know that the private key is really
+known, because a challenge reply can only be sent back if the challenge is
+decrypted correctly, and that can only be done with knowledge of the private
+key.
+
+Fourth: the first thing that is sent via the symmetric cipher encrypted
+connection is a totally random string, so that there is no known plaintext (for
+an attacker) in the beginning of the encrypted stream.
+
+
+@c ==================================================================
+@node Encryption of network packets
+@subsection Encryption of network packets
+@cindex encryption
+
+A data packet can only be sent if the encryption key is known to both
+parties, and the connection is activated. If the encryption key is not
+known, a request is sent to the destination using the meta connection
+to retrieve it. The packet is stored in a queue while waiting for the
+key to arrive.
+
+@cindex UDP
+The UDP packet containing the network packet from the VPN has the following layout:
+
+@example
+... | IP header | UDP header | seqno | VPN packet | MAC | UDP trailer
+ \___________________/\_____/
+ | |
+ V +---> digest algorithm
+ Encrypted with symmetric cipher
+@end example
+
+So, the entire VPN packet is encrypted using a symmetric cipher, including a 32 bits
+sequence number that is added in front of the actual VPN packet, to act as a unique
+IV for each packet and to prevent replay attacks. A message authentication code
+is added to the UDP packet to prevent alteration of packets. By default the
+first 4 bytes of the digest are used for this, but this can be changed using
+the MACLength configuration variable.
+
+@c ==================================================================
+@node Security issues
+@subsection Security issues
+
+In August 2000, we discovered the existence of a security hole in all versions
+of tinc up to and including 1.0pre2. This had to do with the way we exchanged
+keys. Since then, we have been working on a new authentication scheme to make
+tinc as secure as possible. The current version uses the OpenSSL library and
+uses strong authentication with RSA keys.
+
+On the 29th of December 2001, Jerome Etienne posted a security analysis of tinc
+1.0pre4. Due to a lack of sequence numbers and a message authentication code
+for each packet, an attacker could possibly disrupt certain network services or
+launch a denial of service attack by replaying intercepted packets. The current
+version adds sequence numbers and message authentication codes to prevent such
+attacks.
+
+On the 15th of September 2003, Peter Gutmann posted a security analysis of tinc
+1.0.1. He argues that the 32 bit sequence number used by tinc is not a good IV,
+that tinc's default length of 4 bytes for the MAC is too short, and he doesn't
+like tinc's use of RSA during authentication. We do not know of a security hole
+in this version of tinc, but tinc's security is not as strong as TLS or IPsec.
+We will address these issues in tinc 2.0.
+
+Cryptography is a hard thing to get right. We cannot make any
+guarantees. Time, review and feedback are the only things that can
+prove the security of any cryptographic product. If you wish to review
+tinc or give us feedback, you are stronly encouraged to do so.
+
+
+@c ==================================================================
+@node Platform specific information
+@chapter Platform specific information
+
+@menu
+* Interface configuration::
+* Routes::
+@end menu
+
+@c ==================================================================
+@node Interface configuration
+@section Interface configuration
+
+When configuring an interface, one normally assigns it an address and a
+netmask. The address uniquely identifies the host on the network attached to
+the interface. The netmask, combined with the address, forms a subnet. It is
+used to add a route to the routing table instructing the kernel to send all
+packets which fall into that subnet to that interface. Because all packets for
+the entire VPN should go to the virtual network interface used by tinc, the
+netmask should be such that it encompasses the entire VPN.
+
+For IPv4 addresses:
+
+@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
+@item Linux
+@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
+@item Linux iproute2
+@tab @code{ip addr add} @var{address}@code{/}@var{prefixlength} @code{dev} @var{interface}
+@item FreeBSD
+@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
+@item OpenBSD
+@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
+@item NetBSD
+@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
+@item Solaris
+@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
+@item Darwin (MacOS/X)
+@tab @code{ifconfig} @var{interface} @var{address} @code{netmask} @var{netmask}
+@item Windows
+@tab @code{netsh interface ip set address} @var{interface} @code{static} @var{address} @var{netmask}
+@end multitable
+
+For IPv6 addresses:
+
+@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
+@item Linux
+@tab @code{ifconfig} @var{interface} @code{add} @var{address}@code{/}@var{prefixlength}
+@item FreeBSD
+@tab @code{ifconfig} @var{interface} @code{inet6} @var{address} @code{prefixlen} @var{prefixlength}
+@item OpenBSD
+@tab @code{ifconfig} @var{interface} @code{inet6} @var{address} @code{prefixlen} @var{prefixlength}
+@item NetBSD
+@tab @code{ifconfig} @var{interface} @code{inet6} @var{address} @code{prefixlen} @var{prefixlength}
+@item Solaris
+@tab @code{ifconfig} @var{interface} @code{inet6 plumb up}
+@item
+@tab @code{ifconfig} @var{interface} @code{inet6 addif} @var{address} @var{address}
+@item Darwin (MacOS/X)
+@tab @code{ifconfig} @var{interface} @code{inet6} @var{address} @code{prefixlen} @var{prefixlength}
+@item Windows
+@tab @code{netsh interface ipv6 add address} @var{interface} @code{static} @var{address}/@var{prefixlength}
+@end multitable
+
+On some platforms, when running tinc in switch mode, the VPN interface must be set to tap mode with an ifconfig command:
+
+@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
+@item OpenBSD
+@tab @code{ifconfig} @var{interface} @code{link0}
+@end multitable
+
+On Linux, it is possible to create a persistent tun/tap interface which will
+continue to exist even if tinc quit, although this is normally not required.
+It can be useful to set up a tun/tap interface owned by a non-root user, so
+tinc can be started without needing any root privileges at all.
+
+@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
+@item Linux
+@tab @code{ip tuntap add dev} @var{interface} @code{mode} @var{tun|tap} @code{user} @var{username}
+@end multitable
+
+@c ==================================================================
+@node Routes
+@section Routes
+
+In some cases it might be necessary to add more routes to the virtual network
+interface. There are two ways to indicate which interface a packet should go
+to, one is to use the name of the interface itself, another way is to specify
+the (local) address that is assigned to that interface (@var{local_address}). The
+former way is unambiguous and therefore preferable, but not all platforms
+support this.
+
+Adding routes to IPv4 subnets:
+
+@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
+@item Linux
+@tab @code{route add -net} @var{network_address} @code{netmask} @var{netmask} @var{interface}
+@item Linux iproute2
+@tab @code{ip route add} @var{network_address}@code{/}@var{prefixlength} @code{dev} @var{interface}
+@item FreeBSD
+@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address}
+@item OpenBSD
+@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address}
+@item NetBSD
+@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address}
+@item Solaris
+@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address} @code{-interface}
+@item Darwin (MacOS/X)
+@tab @code{route add} @var{network_address}@code{/}@var{prefixlength} @var{local_address}
+@item Windows
+@tab @code{netsh routing ip add persistentroute} @var{network_address} @var{netmask} @var{interface} @var{local_address}
+@end multitable
+
+Adding routes to IPv6 subnets:
+
+@multitable {Darwin (MacOS/X)} {ifconfig route add -bla network address netmask netmask prefixlength interface}
+@item Linux
+@tab @code{route add -A inet6} @var{network_address}@code{/}@var{prefixlength} @var{interface}
+@item Linux iproute2
+@tab @code{ip route add} @var{network_address}@code{/}@var{prefixlength} @code{dev} @var{interface}
+@item FreeBSD
+@tab @code{route add -inet6} @var{network_address}@code{/}@var{prefixlength} @var{local_address}
+@item OpenBSD
+@tab @code{route add -inet6} @var{network_address} @var{local_address} @code{-prefixlen} @var{prefixlength}
+@item NetBSD
+@tab @code{route add -inet6} @var{network_address} @var{local_address} @code{-prefixlen} @var{prefixlength}
+@item Solaris
+@tab @code{route add -inet6} @var{network_address}@code{/}@var{prefixlength} @var{local_address} @code{-interface}
+@item Darwin (MacOS/X)
+@tab ?
+@item Windows
+@tab @code{netsh interface ipv6 add route} @var{network address}/@var{prefixlength} @var{interface}
+@end multitable
+
+
+@c ==================================================================
+@node About us