--- gvpe/doc/gvpe.texi 2011/02/15 13:31:22 1.5 +++ gvpe/doc/gvpe.texi 2016/11/10 15:15:23 1.8 @@ -144,7 +144,7 @@ @item EASY TO SETUP -A few lines of config (the config file is shared unmodified between all hosts) and a single run of @t{gvpectrl} to generate the keys suffices to make it work. +A few lines of config (the config file is shared unmodified between all hosts) and generating an RSA key-pair on each node suffices to make it work. @refill @@ -197,7 +197,7 @@ ./configure --enable-hmac-length=4 --enable-rand-length=0 @end example -Minimize the header overhead of VPN packets (the above will result in only 4 bytes of overhead over the raw ethernet frame). This is a insecure configuration because a HMAC length of 4 makes collision attacks based on the birthday paradox pretty easy. +Minimize the header overhead of VPN packets (the above will result in only 4 bytes of overhead over the raw ethernet frame). This is a insecure configuration because a HMAC length of 4 makes collision attacks almost trivial. @refill @@ -216,10 +216,10 @@ @example - ./configure --enable-hmac-length=16 --enable-rand-length=8 --enable-digest=sha1 + ./configure --enable-hmac-length=16 --enable-rand-length=12 --enable-digest=ripemd610 @end example -This uses a 16 byte HMAC checksum to authenticate packets (I guess 8-12 would also be pretty secure ;) and will additionally prefix each packet with 8 bytes of random data. In the long run, people should move to SHA-256 and beyond). +This uses a 16 byte HMAC checksum to authenticate packets (I guess 8-12 would also be pretty secure ;) and will additionally prefix each packet with 12 bytes of random data. @refill In general, remember that AES-128 seems to be as secure but faster than AES-192 or AES-256, more randomness helps against sniffing and a longer HMAC helps against spoofing. MD4 is a fast digest, SHA1, RIPEMD160, SHA256 are consecutively better, and Blowfish is a fast cipher (and also quite secure). @refill @@ -271,42 +271,47 @@ @refill -@subsection STEP 2: create the RSA key pairs for all hosts -Run the following command to generate all key pairs for all nodes (that might take a while): +@subsection STEP 2: create the RSA key pair for each node +Next you have to generate the RSA keys for the nodes. While you can set up GVPE so you can generate all keys on a single host and centrally distribute all keys, it is safer to generate the key for each node on the node, so that the secret/private key does not have to be copied over the network. +@refill +To do so, run the following command to generate a key pair: @refill @example - gvpectrl -c /etc/gvpe -g + gvpectrl -c /etc/gvpe -g nodekey @end example -This command will put the public keys into @t{/etc/gvpe/pubkeys/@emph{nodename}} and the private keys into @t{/etc/gvpe/hostkeys/@emph{nodename}}. +This will create two files, @file{nodekey} and @file{nodekey.privkey}. The former should be copied to @file{/etc/gvpe/pubkey/@emph{nodename}} on the host where your config file is (you will have to create the @file{pubkey} directory first): @refill -@subsection STEP 3: distribute the config files to all nodes -Now distribute the config files and private keys to the other nodes. This should be done in two steps, since only the private keys meant for a node should be distributed (so each node has only it's own private key). -@refill -The example uses rsync-over-ssh -@refill -First all the config files without the hostkeys should be distributed: +@example + scp nodekey confighost:/etc/gvpe/pubkey/nodename +@end example + +The private key @file{nodekey.privkey} should be moved to @file{/etc/gvpe/hostkey}: @refill @example - rsync -avzessh /etc/gvpe first.example.net:/etc/. --exclude hostkeys - rsync -avzessh /etc/gvpe 133.55.82.9:/etc/. --exclude hostkeys - rsync -avzessh /etc/gvpe third.example.net:/etc/. --exclude hostkeys + mkdir -p /etc/gvpe + mv nodekey.privkey /etc/gvpe/hostkey @end example -Then the hostkeys should be copied: + + +@subsection STEP 3: distribute the config files to all nodes +Now distribute the config files and public keys to the other nodes. +@refill +The example uses rsync-over-ssh to copy the config file and all the public keys: @refill @example - rsync -avzessh /etc/gvpe/hostkeys/first first.example.net:/etc/hostkey - rsync -avzessh /etc/gvpe/hostkeys/second 133.55.82.9:/etc/hostkey - rsync -avzessh /etc/gvpe/hostkeys/third third.example.net:/etc/hostkey + rsync -avzessh /etc/gvpe first.example.net:/etc/. --exclude hostkey + rsync -avzessh /etc/gvpe 133.55.82.9:/etc/. --exclude hostkey + rsync -avzessh /etc/gvpe third.example.net:/etc/. --exclude hostkey @end example You should now check the configuration by issuing the command @t{gvpectrl -c /etc/gvpe -s} on each node and verify it's output. @@ -337,10 +342,37 @@ @subsection STEP 5: enjoy -... and play around. Sending a -HUP (@t{gvpectrl -kHUP}) to the daemon will make it try to connect to all other nodes again. If you run it from inittab, as is recommended, @t{gvpectrl -k} (or simply @t{killall gvpe}) will kill the daemon, start it again, making it read it's configuration files again. +... and play around. Sending a -HUP (@t{gvpectrl -kHUP}) to the daemon will make it try to connect to all other nodes again. If you run it from inittab @t{gvpectrl -k} (or simply @t{killall gvpe}) will kill the daemon, start it again, making it read it's configuration files again. +@refill +To run the GVPE daemon permanently from your SysV init, you can add it to your @file{inittab}, e.g.: @refill +@example + t1:2345:respawn:/bin/sh -c "exec nice -n-20 /path/to/gvpe -D node >/var/log/gvpe.log 2>&1" +@end example + +For systems using systemd, you can use a unit file similar to this one: +@refill + + +@example + [Unit] + Description=gvpe + After=network.target + Before=remote-fs.target + + [Service] + ExecStart=/path/to/gvpe -D node + KillMode=process + Restart=always + + [Install] + WantedBy=multi-user.target +@end example + + + @section COPYRIGHTS AND LICENSES GVPE itself is distributed under the GENERAL PUBLIC LICENSE (see the file COPYING that should be part of your distribution). @refill @@ -608,9 +640,49 @@ @section DESCRIPTION The gvpe config file consists of a series of lines that contain @t{variable = value} pairs. Empty lines are ignored. Comments start with a @t{#} and extend to the end of the line. They can be used on their own lines, or after any directives. Whitespace is allowed around the @t{=} sign or after values, but not within the variable names or values themselves. @refill -The only exception to the above is the "on" directive that can prefix any @t{name = value} setting and will only "execute" it on the named node, or (if the nodename starts with "!") on all nodes except the named one. +All settings are applied "in order", that is, later settings of the same variable overwrite earlier ones. +@refill +The only exceptions to the above are the following directives: +@refill + + +@itemize + + +@item +node nodename + +Introduces a node section. The nodename is used to select the right configuration section and is the same string as is passed as an argument to the gvpe daemon. @refill -For example, set the MTU to @t{1450} everywhere, loglevel to @t{noise} on branch1, and connect to @t{ondemand} everywhere but on branch2: +Multiple @t{node} statements with the same node name are supported and will be merged together. +@refill + + +@item +global + +This statement switches back to the global section, which is mainly useful if you want to include a second config file, e..g for local customisations. To do that, simply include this at the very end of your config file: +@refill + + +@example + global + include local.conf +@end example + + + +@item +on nodename ... + + + +@item +on !nodename ... + +You can prefix any configuration directive with @t{on} and a nodename. GVPE will will only "execute" it on the named node, or (if the nodename starts with @t{!}) on all nodes except the named one. +@refill +Example: set the MTU to @t{1450} everywhere, @t{loglevel} to @t{noise} on @t{branch1}, and @t{connect} to @t{ondemand} everywhere but on branch2. @refill @@ -620,10 +692,37 @@ on !branch2 connect = ondemand @end example -All settings are applied "in order", that is, later settings of the same variable overwrite earlier ones. + + +@item +include relative-or-absolute-path + +Reads the specified file (the path must not contain whitespace or @t{=} characters) and evaluate all config directives in it as if they were spelled out in place of the @t{include} directive. +@refill +The path is a printf format string, that is, you must escape any @t{%} by doubling it, and you can have a single @t{%s} inside, which will be replaced by the current nodename. +@refill +Relative paths are interpreted relative to the GVPE config directory. +@refill +Example: include the file @file{local.conf} in the config directory on every node. +@refill + + +@example + include local.conf +@end example + +Example: include a file @file{conf/}nodename@file{.conf} @refill +@example + include conf/%s.conf +@end example + +@end itemize + + + @section ANATOMY OF A CONFIG FILE Usually, a config file starts with a few global settings (like the UDP port to listen on), followed by node-specific sections that begin with a @t{node = nickname} line. @refill @@ -645,6 +744,40 @@ @item +chroot = path or / + +@cindex chroot +Tells GVPE to chroot(2) to the specified path after reading all necessary files, binding to sockets and running the @t{if-up} script, but before running @t{node-up} or any other scripts. +@refill +The special path @file{/} instructs GVPE to create (and remove) an empty temporary directory to use as new root. This is most secure, but makes it impossible to use any scripts other than the @t{if-up} one. +@refill + + +@item +chuid = numerical-uid + +@cindex chuid + + +@item +chgid = numerical-gid + +@cindex chgid +These two options tell GVPE to change to the given user and/or group id after reading all necessary files, binding to sockets and running the @t{if-up} script. +@refill +Other scripts, such as @t{node-up}, are run with the new user id or group id. +@refill + + +@item +chuser = username + +@cindex chuser +Alternative to @t{chuid} and @t{chgid}: Sets both @t{chuid} and @t{chgid} to the user and (primary) group ids of the specified user (for example, @t{nobody}). +@refill + + +@item dns-forw-host = hostname/ip @cindex dns-forw-host @@ -661,6 +794,16 @@ @item +dns-case-preserving = yes|true|on | no|false|off + +@cindex dns-case-preserving +Sets whether the DNS transport forwarding server preserves case (DNS servers have to, but some access systems are even more broken than others) (default: true). +@refill +Normally, when the forwarding server changes the case of domain names then GVPE will automatically set this to false. +@refill + + +@item dns-max-outstanding = integer-number-of-requests @cindex dns-max-outstanding @@ -896,7 +1039,7 @@ keepalive = seconds @cindex keepalive -Sets the keepalive probe interval in seconds (default: @t{60}). After this many seconds of inactivity the daemon will start to send keepalive probe every 3 seconds until it receives a reply from the other end. If no reply is received within 15 seconds, the peer is considered unreachable and the connection is closed. +Sets the keepalive probe interval in seconds (default: @t{60}). After this many seconds of inactivity the daemon will start to send keepalive probe every 3 seconds until it receives a reply from the other end. If no reply is received within 15 seconds, the peer is considered unreachable and the connection is closed. @refill @@ -921,11 +1064,19 @@ @item -node = nickname +nfmark = integer -@cindex node -Not really a config setting but introduces a node section. The nickname is used to select the right configuration section and must be passed as an argument to the gvpe daemon. +@cindex nfmark +This advanced option, when set to a nonzero value (default: @t{0}), tries to set the netfilter mark (or fwmark) value on all sockets gvpe uses to send packets. @refill +This can be used to make gvpe use a different set of routing rules. For example, on GNU/Linux, the @t{if-up} could set @t{nfmark} to 1000 and then put all routing rules into table @t{99} and then use an ip rule to make gvpe traffic avoid that routing table, in effect routing normal traffic via gvpe and gvpe traffic via the normal system routing tables: +@refill + + +@example + ip rule add not fwmark 1000 lookup 99 +@end example + @item @@ -998,7 +1149,7 @@ @{ echo update delete $DESTNODE.lowttl.example.net. a echo update add $DESTNODE.lowttl.example.net. 1 in a $DESTIP - echo + echo @} | nsupdate -d -k $CONFBASE:key.example.net. @end example @@ -1024,7 +1175,7 @@ pid-file = path @cindex pid-file -The path to the pid file to check and create (default: @t{LOCALSTATEDIR/run/gvpe.pid}). +The path to the pid file to check and create (default: @t{LOCALSTATEDIR/run/gvpe.pid}). The first @t{%s} is replaced by the nodename - any other use of @t{%} must be written as @t{%%}. @refill @@ -1032,9 +1183,9 @@ private-key = relative-path-to-key @cindex private-key -Sets the path (relative to the config directory) to the private key (default: @t{hostkey}). This is a printf format string so every @t{%} must be doubled. A single @t{%s} is replaced by the hostname, so you could use paths like @t{hostkeys/%s} to fetch the files at the location where @t{gvpectrl} puts them. +Sets the path (relative to the config directory) to the private key (default: @t{hostkey}). This is a printf format string so every @t{%} must be doubled. A single @t{%s} is replaced by the hostname, so you could use paths like @t{hostkeys/%s} to be able to share the same config directory between nodes. @refill -Since only the private key file of the current node is used and the private key file should be kept secret per-node to avoid spoofing, it is not recommended to use this feature. +Since only the private key file of the current node is used and the private key file should be kept secret per-node to avoid spoofing, it is not recommended to use this feature this way though. @refill @@ -1042,24 +1193,44 @@ rekey = seconds @cindex rekey -Sets the rekeying interval in seconds (default: @t{3600}). Connections are reestablished every @t{rekey} seconds, making them use a new encryption key. +Sets the rekeying interval in seconds (default: @t{3607}). Connections are reestablished every @t{rekey} seconds, making them use a new encryption key. @refill @item -nfmark = integer +seed-device = path -@cindex nfmark -This advanced option, when set to a nonzero value (default: @t{0}), tries to set the netfilter mark (or fwmark) value on all sockets gvpe uses to send packets. +@cindex seed-device +The random device used to initially and regularly seed the random number generator (default: @file{/dev/urandom}). Randomness is of paramount importance to the security of the algorithms used in gvpe. @refill -This can be used to make gvpe use a different set of routing rules. For example, on GNU/Linux, the @t{if-up} could set @t{nfmark} to 1000 and then put all routing rules into table @t{99} and then use an ip rule to make gvpe traffic avoid that routing table, in effect routing normal traffic via gvpe and gvpe traffic via the normal system routing tables: +On program start and every seed-interval, gvpe will read 64 octets. +@refill +Setting this path to the empty string will disable this functionality completely (the underlying crypto library will likely look for entropy sources on it's own though, so not all is lost). @refill -@example - ip rule add not fwmark 1000 lookup 99 -@end example +@item +seed-interval = seconds + +@cindex seed-interval +The number of seconds between reseeds of the random number generator (default: @t{3613}). A value of @t{0} disables this regular reseeding. +@refill + +@item +serial = string + +@cindex serial +The configuration serial number. This can be any string up to 16 bytes length. Only when the serial matches on both sides of a conenction will the connection succeed. This is @emph{not} a security mechanism and eay to spoof, this mechanism exists to alert users that their config is outdated. +@refill +It's recommended to specify this is a date string such as @t{2013-05-05} or @t{20121205084417}. +@refill +The exact algorithm is as this: if a connection request is received form a node with an identical serial, then it succeeds normally. +@refill +If the remote serial is lower than the local serial, it is ignored. +@refill +If the remote serial is higher than the local serial, a warning message is logged. +@refill @end itemize @@ -1208,9 +1379,7 @@ @cindex enable-udp See gvpe.protocol(7) for a description of the UDP transport protocol. @refill -Enable the UDPv4 transport using the @t{udp-port} port (default: @t{no}, unless no other protocol is enabled for a node, in which case this protocol is enabled automatically). -@refill -NOTE: Please specify @t{enable-udp = yes} if you want to use it even though it might get switched on automatically, as some future version might default to another default protocol. +Enable the UDPv4 transport using the @t{udp-port} port (default: @t{no}). @refill @@ -1251,6 +1420,16 @@ @item +low-power = yes|true|on | no|false|off + +@cindex low-power +If true, designates a node as a low-power node. Low-power nodes use larger timeouts and try to reduce cpu time. Other nodes talking to a low-power node will also use larger timeouts, and will use less aggressive optimisations, in the hope of reducing load. Security is not compromised. +@refill +The typical low-power node would be a mobile phone, where wakeups and encryption can significantly increase power drain. +@refill + + +@item max-retry = positive-number @cindex max-retry @@ -1342,7 +1521,7 @@ @item hostkey -The private key (taken from @t{hostkeys/nodename}) of the current host. +The (default path of the) private key of the current host. @refill @@ -1389,9 +1568,30 @@ @item -@strong{-g}, @strong{--generate-keys} +@strong{-g}, @strong{--generate-key=path} -Generate public/private RSA key-pair and exit. +Generates a single RSA key-pair. The public key will be stored in @file{@emph{path}} while the private key will be stored in @file{@emph{path} .privkey}. Neither file must be non-empty for this to succeed. +@refill +The public key file @file{@emph{path}} is normally copied to @file{pubkey/nodename} in the config directory on all nodes, while the private key @file{@emph{path}.privkey} should be copied to the file @file{hostkey} on the node the key is for. +@refill +It's recommended to generate the keypair on the node where it will be used, so that the private key file does not have to travel over the network. +@refill + + +@item +@strong{-G}, @strong{--generate-keys} + +Generate public/private RSA key-pairs for all nodes not having a key and exit. +@refill +Note that in normal configurations this will fail, as there cna only be one private key per host. To make this configuration work you need to specify separate keyfiles for hostkeys in your config file, e.g.: +@refill + + +@example + private-key = hostkeys/%s +@end example + +Such a configuration makes it easier to distribute a configuration centrally but requires private keys to be transported securely over the network. @refill @@ -1597,7 +1797,14 @@ @item @t{/etc/gvpe/pubkey/*} -The directory containing the public keys for every node, usually autogenerated by executing @t{gvpectrl --generate-keys}. +The directory containing the public keys for every node, one file per node with the name of the node. +@refill + + +@item +@t{/etc/gvpe/hostkey} + +The file containing the private key of the node GVPE runs on. Unlike all the other files in the @file{/etc/gvpe} directory, this file usually differes for each node that GVPE runs on. @refill @@ -1628,7 +1835,7 @@ @section Overview GVPE can make use of a number of protocols. One of them is the GNU VPE protocol which is used to authenticate tunnels and send encrypted data packets. This protocol is described in more detail the second part of this document. @refill -The first part of this document describes the transport protocols which are used by GVPE to send it's data packets over the network. +The first part of this document describes the transport protocols which are used by GVPE to send its data packets over the network. @refill @@ -1665,7 +1872,7 @@ @subsection TCP -This protocol is a very bad choice, as it not only has high overhead (more than 60 bytes), but the transport also retries on it's own, which leads to congestion when the link has moderate packet loss (as both the TCP transport and the tunneled traffic will retry, increasing congestion more and more). It also has high latency and is quite inefficient. +This protocol is a very bad choice, as it not only has high overhead (more than 60 bytes), but the transport also retries on its own, which leads to congestion when the link has moderate packet loss (as both the TCP transport and the tunneled traffic will retry, increasing congestion more and more). It also has high latency and is quite inefficient. @refill It's only useful when tunneling through firewalls that block better protocols. If a node doesn't have direct internet access but a HTTP proxy that supports the CONNECT method it can be used to tunnel through a web proxy. For this to work, the @t{tcp-port} should be @t{443} (@t{https}), as most proxies do not allow connections to other ports. @refill @@ -1682,7 +1889,7 @@ @refill In addition, the same problems as the TCP transport also plague this protocol. @refill -It's only use is to tunnel through firewalls that do not allow direct internet access. Similar to using a HTTP proxy (as the TCP transport does), it uses a local DNS server/forwarder (given by the @t{dns-forw-host} configuration value) as a proxy to send and receive data as a client, and an @t{NS} record pointing to the GVPE server (as given by the @t{dns-hostname} directive). +Its only use is to tunnel through firewalls that do not allow direct internet access. Similar to using a HTTP proxy (as the TCP transport does), it uses a local DNS server/forwarder (given by the @t{dns-forw-host} configuration value) as a proxy to send and receive data as a client, and an @t{NS} record pointing to the GVPE server (as given by the @t{dns-hostname} directive). @refill The only good side of this protocol is that it can tunnel through most firewalls mostly undetected, iff the local DNS server/forwarder is sane (which is true for most routers, wireless LAN gateways and nameservers). @refill @@ -1706,7 +1913,7 @@ +------+------+--------+------+ @end example -The HMAC field is present in all packets, even if not used (e.g. in auth request packets), in which case it is set to all zeroes. The checksum itself is calculated over the TYPE, SRCDST and DATA fields in all cases. +The HMAC field is present in all packets, even if not used (e.g. in auth request packets), in which case it is set to all zeroes. The MAC itself is calculated over the TYPE, SRCDST and DATA fields in all cases. @refill The TYPE field is a single byte and determines the purpose of the packet (e.g. RESET, COMPRESSED/UNCOMPRESSED DATA, PING, AUTH REQUEST/RESPONSE, CONNECT REQUEST/INFO etc.). @refill @@ -1717,27 +1924,61 @@ @example - +------+------+--------+------+-------+------+ - | HMAC | TYPE | SRCDST | RAND | SEQNO | DATA | - +------+------+--------+------+-------+------+ + +------+------+--------+-------+------+ + | HMAC | TYPE | SRCDST | SEQNO | DATA | + +------+------+--------+-------+------+ @end example -RAND is a sequence of fully random bytes, used to increase the entropy of the data for encryption purposes. +SEQNO is a 32-bit sequence number. It is negotiated at every connection initialization and starts at some random 31 bit value. GVPE currently uses a sliding window of 512 packets/sequence numbers to detect reordering, duplication and replay attacks. @refill -SEQNO is a 32-bit sequence number. It is negotiated at every connection initialization and starts at some random 31 bit value. VPE currently uses a sliding window of 512 packets/sequence numbers to detect reordering, duplication and replay attacks. +The encryption is done on SEQNO+DATA in CTR mode with IV generated from the seqno (for AES: seqno || seqno || seqno || (u32)0), which ensures uniqueness for a given key. @refill -@subsection The authentication protocol +@subsection The authentication/key exchange protocol Before nodes can exchange packets, they need to establish authenticity of the other side and a key. Every node has a private RSA key and the public RSA keys of all other nodes. @refill -A host establishes a simplex connection by sending the other node an RSA encrypted challenge containing a random challenge (consisting of the encryption key to use when sending packets, more random data and PKCS1_OAEP padding) and a random 16 byte "challenge-id" (used to detect duplicate auth packets). The destination node will respond by replying with an (unencrypted) RIPEMD160 hash of the decrypted challenge, which will authenticate that node. The destination node will also set the outgoing encryption parameters as given in the packet. +When a node wants to establish a connection to another node, it sends an RSA-OEAP-encrypted challenge and an ECDH (curve25519) key. The other node replies with its own ECDH key and a HKDF of the challenge and both ECDH keys to prove its identity. +@refill +The remote node enganges in exactly the same protocol. When both nodes have exchanged their challenge and verified the response, they calculate a cipher key and a HMAC key and start exchanging data packets. +@refill +In detail, the challenge consist of: +@refill + + +@example + RSA-OAEP (SEQNO MAC CIPHER SALT EXTRA-AUTH) ECDH1 +@end example + +That is, it encrypts (with the public key of the remote node) an initial sequence number for data packets, key material for the HMAC key, key material for the cipher key, a salt used by the HKDF (as shown later) and some extra random bytes that are unused except for authentication. It also sends the public key of a curve25519 exchange. +@refill +The remote node decrypts the RSA data, generates its own ECDH key (ECDH2), and replies with: +@refill + + +@example + HKDF-Expand (HKDF-Extract (ECDH2, RSA), ECDH1, AUTH_DIGEST_SIZE) ECDH2 +@end example + +That is, it extracts from the decrypted RSA challenge, using its ECDH key as salt, and then expands using the requesting node's ECDH1 key. The resulting hash is returned as a proof that the node could decrypt the RSA challenge data, together with the ECDH key. +@refill +After both nodes have done this to each other, they calculate the shared ECDH secret, cipher and HMAC keys for the session (each node generates two cipher and HMAC keys, one for sending and one for receiving). +@refill +The HMAC key for sending is generated as follow: +@refill + + +@example + HMAC_KEY = HKDF-Expand (HKDF-Extract (REMOTE_SALT, MAC ECDH_SECRET), info, HMAC_MD_SIZE) +@end example + +It extracts from MAC and ECDH_SECRET using the @emph{remote} SALT, then expands using a static info string. @refill -When the source node receives a correct auth reply (by verifying the hash and the id, which will expire after 120 seconds), it will start to accept data packets from the destination node. +The cipher key is generated in the same way, except using the CIPHER part of the original challenge. @refill -This means that a node can only initiate a simplex connection, telling the other side the key it has to use when it sends packets. The challenge reply is only used to set the current IP address of the other side and protocol parameters. +The result of this process is to authenticate each node to the other node, while exchanging keys using both RSA and ECDH, the latter providing perfect forward secrecy. @refill -This protocol is completely symmetric, so to be able to send packets the destination node must send a challenge in the exact same way as already described (so, in essence, two simplex connections are created per node pair). +The protocol has been overdesigned where this was possible without increasing implementation complexity, in an attempt to protect against implementation or protocol failures. For example, if the ECDH challenge was found to be flawed, perfect forward secrecy would be lost, but the data would likely still be protected. Likewise, standard algorithms and implementations are used where possible. @refill @@ -1753,7 +1994,7 @@ @subsection Routing and Protocol translation -The GVPE routing algorithm is easy: there isn't much routing to speak of: When routing packets to another node, GVPE trues the following options, in order: +The GVPE routing algorithm is easy: there isn't much routing to speak of: When routing packets to another node, GVPE tries the following options, in order: @refill @@ -1785,11 +2026,11 @@ @end itemize -A host can usually declare itself unreachable directly by setting it's port number(s) to zero. It can declare other hosts as unreachable by using a config-file that disables all protocols for these other hosts. Another option is to disable all protocols on that host in the other config files. +A host can usually declare itself unreachable directly by setting its port number(s) to zero. It can declare other hosts as unreachable by using a config-file that disables all protocols for these other hosts. Another option is to disable all protocols on that host in the other config files. @refill If two hosts cannot connect to each other because their IP address(es) are not known (such as dial-up hosts), one side will send a @emph{mediated} connection request to a router (routers must be configured to act as routers!), which will send both the originating and the destination host a connection info request with protocol information and IP address of the other host (if known). Both hosts will then try to establish a direct connection to the other peer, which is usually possible even when both hosts are behind a NAT gateway. @refill -Routing via other nodes works because the SRCDST field is not encrypted, so the router can just forward the packet to the destination host. Since each host uses it's own private key, the router will not be able to decrypt or encrypt packets, it will just act as a simple router and protocol translator. +Routing via other nodes works because the SRCDST field is not encrypted, so the router can just forward the packet to the destination host. Since each host uses its own private key, the router will not be able to decrypt or encrypt packets, it will just act as a simple router and protocol translator. @refill