chiark / gitweb /
@@ -1,8 +1,11 @@
authorian <ian>
Mon, 18 Sep 2000 00:31:11 +0000 (00:31 +0000)
committerian <ian>
Mon, 18 Sep 2000 00:31:11 +0000 (00:31 +0000)
 userv-utils (0.2.0) unstable; urgency=low

-  * ipif/INSTALL instructions &c improved, slattach patch included.
+  Improvements to ipif (tunnelling/VPN facility):
+  * INSTALL instructions much improved and README created.
+  * Patch to slattach included.
+  * Documentation comments improved.

- --
+ -- Ian Jackson <ian@davenant.greenend.org.uk>  Mon, 18 Sep 2000 01:31:01 +0100

 userv-utils (0.1.90) unstable; urgency=low

12 files changed:
README
changelog
debian/changelog
ipif/INSTALL
ipif/README [new file with mode: 0644]
ipif/mech-blowfish.c
ipif/mech-null.c
ipif/mech-pkcs5.c
ipif/mech-sequence.c
ipif/mech-timestamp.c
ipif/service.c
ipif/udptunnel

diff --git a/README b/README
index dfe735b..4dca21a 100644 (file)
--- a/README
+++ b/README
@@ -21,8 +21,8 @@ Here is a quick summary of the currently available utilities
 Directory      Status  Description (UC=`users can ...')
 --------------- -----  ------------------------------------------------
 groupmanage    Y Y A   UC create groups, add/remove members, &c
+ipif           Y Y A   UC create IP interfaces/VPNs (Linux-specific)
 www-cgi                Y B A   UC provide CGIs which run as themselves
-ipif           Y B P   UC create IP interfaces/VPNs (Linux-specific)
 misc/mailq     Y S S   UC list mail queue even if sendmail forbids
 misc/ndc-reload        Y S S   UC reload named after editing own zone files
 newsrc-lg      X B X   Acquire list of subscribed groups from .newsrcs
@@ -66,6 +66,8 @@ address above or write to the Free Software Foundation, 59 Temple
 Place - Suite 330, Boston, MA 02111-1307, USA.
 
 
+$Id$
+
 Local variables:
 mode: text
 fill-column: 77
index b2bb618..1ced792 100644 (file)
--- a/changelog
+++ b/changelog
@@ -1,8 +1,11 @@
 userv-utils (0.2.0) unstable; urgency=low
 
-  * ipif/INSTALL instructions &c improved, slattach patch included.
+  Improvements to ipif (tunnelling/VPN facility):
+  * INSTALL instructions much improved and README created.
+  * Patch to slattach included.
+  * Documentation comments improved.
 
- --
+ -- Ian Jackson <ian@davenant.greenend.org.uk>  Mon, 18 Sep 2000 01:31:01 +0100
 
 userv-utils (0.1.90) unstable; urgency=low
 
index b2bb618..1ced792 100644 (file)
@@ -1,8 +1,11 @@
 userv-utils (0.2.0) unstable; urgency=low
 
-  * ipif/INSTALL instructions &c improved, slattach patch included.
+  Improvements to ipif (tunnelling/VPN facility):
+  * INSTALL instructions much improved and README created.
+  * Patch to slattach included.
+  * Documentation comments improved.
 
- --
+ -- Ian Jackson <ian@davenant.greenend.org.uk>  Mon, 18 Sep 2000 01:31:01 +0100
 
 userv-utils (0.1.90) unstable; urgency=low
 
index 6f23ec6..841ff22 100644 (file)
-This directory contains:
+This file, INSTALL, is a tutorial on how to
+ * install userv ipif and udptunnel, and
+ * configure them to create a VPN tunnel between two hosts or networks.
 
-* A userv service (`ipif') for allowing users to create network
-interfaces and handle the traffic for them.  For instructions, see the
-comment at the top of service.c.
+See README for details of other available documentation.
 
-* A VPN tunnelling system based on that userv service, which does
-encryption and can be used to join two networks.  It uses its own
-nonstandard protocols, not IPSEC.  Key setup is done via an ssh
-connection.  For installation instructions, read this file.
 
-These tools have only been tested on GNU/Linux, and the ipif service
-in particular uses the Linux-specific `slattach' utility.
+BUILD AND INSTALLATION INSTRUCTIONS
+-----------------------------------
 
-NB that this is a very bare set of installation instructions for the
-VPN system !  It describes a fairly `default' configuration; you can
-do more esoteric things if you wish.
+1. Install userv, 1.0.1 or later.  This is in Debian GNU/Linux.
 
+2. Make sure your Linux kernel has SLIP and CSLIP compiled in.
+   You will need to be using Linux 2.2 (with Unix98-style ptys).
 
-In any case, on each tunnel endpoint system (not the eventual
-end-system, but the point where the packets are `detunnelled'):
+3. Obtain a fresh copy of userv-utils, if you haven't already.
+   cd to ipif, and run `make' and (as root) `make install'.
+
+ After you have done this the software will still not do anything, and
+ by default userv ipif will not allow anyone (except root) to create
+ network interfaces.
 
-* Install userv, 1.0.1 or later.  This should be in Debian.  Get this
-* package, userv-utils from the location above, unpack it, cd to the
-  `ipif' subdirectory, and say `make' then as root `make install'.
+ The software will probably only work on Linux - in particular, userv
+ ipif's service program (service.c) uses Linux-specific ways of
+ setting up SLIP interfaces.  It might be possible in principle to
+ create alternatives for other platforms.
 
+`slattach' problem:
 
-The tunnel is always set up by one of its endpoints, using ssh (we
-recommend you use OpenSSH).  So the active endpoint must have ssh
-installed; the passive endpoint must have sshd accessible to the
-active endpoint, and be willing to allow the active endpoint to run
-the appropriate command.
-
-So: create an account for the active endpoint on the passive.  You
-probably want to use RSAAuthentication, so configure the relevant key
-into the passive account's authorized_keys file.
-
-Each account must have the ability to run the `userv ipif' service
-with appropriate parameters.  This is achieved by editing
-/etc/userv/ipif-networks, each line of which is in the format:
-
-<gid>,[=]<network-prefix>/<prefix-length>,  <groupname>,  <comment>
-
-Both the local and remote endpoint addresses, and the remote network
-address(es), need to be recorded in this file.  The `=' restricts the
-address to be used, by that group, as the local tunnel endpoint
-address; without `=' the address ranges specified may refer to remote
-endpoints and networks.  Every address involved with the tunnel must
-be covered by an appropriate line in ipif-networks.
-
-For example, a configuration to talk to Relativity, the author's home
-site, would include:
-<gid>,172.31.80.6/32,       <group>,    Relativity tunnel endpoint
-<gid>,172.18.45.0/24,       <group>,    Relativity house ethernet
-as well as the local tunnel endpoint address, for example:
-<gid>,=192.168.160.124/32,  <group>,    Local tunnel endpoint
+ There is a problem with some versions of `slattach' on Linux.  If you
+ see a message from it about being unable to open /dev/2 or some such,
+ then you need to upgrade or patch your `slattach'.  In Debian
+ GNU/Linux it's in the `netbase' package, and the fix is in Debian 2.1
+ in 3.16-3 and later; however the bug has regressed, and is known to
+ be in Debian 2.2's 3.18-4 and earlier.  The relevant Debian bug
+ reports are #45515 (now closed) and #45944.  A patch to correct
+ 3.18-4 is provided here as `slattach.diff', and a fixed binary is
+ available from the author.
 
-There is no NAT (address translation) in the tunnelling software, so
-all the addresses must be RFC1918-allocated and distinct (except that
-a single tunnel endpoint address can be used for all the tunnels
-terminating on a particular endpoint system).
 
-You are strongly advised to choose your private network ranges
-randomly, as recommended in BCP5 (currently RFC1918).  Users in
-Cambridge may like to use the Cambridge G-RIN at
-http://www.ucam.org/cam-grin/ to choose and register their networks.
 
+UDPTUNNEL SETUP TUTORIAL
+------------------------
 
-When these things are all thought to be set up, you can test the
-tunnel by running `udptunnel' in the active account.  It is invoked
-something like this:
-
-authbind udptunnel                                              \
-        -m                                                      \
-        -e nonce -e timestamp/10/30 -e pkcs5/8                  \
-        -e blowfish-cbcmac/128 -e blowfish-cbc/128              \
-        davenant-external,410                                   \
-        chiark-public,Command                                   \
-        172.31.80.6,172.31.80.9,1000,cslip                      \
-        30,120,1800                                             \
-        - 172.18.45.0/24                                        \
-        ssh     -o 'ForwardAgent no' -o 'ForwardX11 no'         \
-                -o 'BatchMode yes'                              \
-                -i ~ian/.ssh/identity -l ian                    \
-                -v chiark.greenend.org.uk                       \
-                udptunnel
 
-This example is the tunnel between chiark and Relativity.  I'll quote
-it and explain the details, below.  See also the comment at the top of
-udptunnel.
+1. BACKGROUND INFORMATION
 
+ Firstly, note that userv ipif and udptunnel are extremely flexible,
+ as they aim to be `Lego brick' networking components.  Many much more
+ interesting configurations can be constructed than there is room to
+ document here.  If you want to do something strange, consult the
+ README to locate the appropriate reference documentation.
 
-Because at Relativity the tunnel endpoint has to not be our firewall,
-because the firewall is a 386SX/16 and so not powerful enough,
-Relativity practically has to be the active partner in any tunnels it
-is involved in.  This also necessitates the use of the `-m' option and
-various other things.
-
+1.1. About udptunnel
 
-Exposition of an example udptunnel invocation:
+ udptunnel is point-to-point; you need a separate `invocation' for
+ each pair of machines (or networks) you wish to connect.
 
-> authbind udptunnel                                              \
+ It is `one-shot': it will set up a tunnel and keep it going as long
+ as it can, and then exit; if you want a permanent tunnel you must
+ arrange to reinvoke udptunnel.
 
-`authbind' is used because at Relativity the tunnel endpoint address
-has to be on a fixed port because our tunnel endpoint is not on the
-firewall system (if it's not on a fixed port we can't write a firewall
-rule to let it through).
+ It is asymmetric, in that one of the endpoints starts the tunnel, and
+ the other sits and waits to be contacted.  We'll call the active
+ endpoint `alice' and the passive endpoint `bob'.  Usually alice
+ invokes udptunnel on bob via OpenSSH (`ssh').
 
-The port is port 410, so root privilege or authbind is needed.
-authbind is in Debian GNU/Linux.
+ udptunnel does not need root privilege to run.  However, you do need
+ to configure userv ipif to know that the user who will be running
+ udptunnel is permitted to use the IP addresses and network ranges
+ which will be used.  So, though most of the configuration can be done
+ as the normal users who will run udptunnel on each end, a small
+ amount (editing /etc/userv/ipif-networks) needs to be done as root on
+ each end - and the information configured as root needs to match up
 
->         -m                                                      \
+ This tutorial will explain how to do these things.
 
--m tells this invocation of udptunnel that its endpoint address and
-port (for encapsulated packets) are going to be NATted before the far
-end sees them.  The effect is that instead of supplying this
-information to the far end, the far end is told to `wait and see'.
+1.2. About point-to-point tunnelling in general
 
-This should not usually be used in other circumstances.  (For full
-details see the comment at the top of udptunnel.)
+ A tunnel is an _additional_ (in the case of udptunnel, encrypted)
+ network link between a pair of machines.  Packets are encapsulated at
+ one end, sent over the real network between them, and decoded again
+ at the other end.  As with any network connection, it is possible to
+ arrange for networks behind the endpoint machines to be able to
+ communicate via the tunnel.
 
->         -e nonce -e timestamp/10/30 -e pkcs5/8                  \
->         -e blowfish-cbcmac/128 -e blowfish-cbc/128              \
-
-This is the crypto configuration.  I wouldn't mess with it too much if
-I were you.  If you have serious (>10s) clock skew then the -e
-timestamp option may not work properly; I'd recommend having your
-systems NTP-synchronised.  Here 10 is the maximum number of seconds
-into the future the timestamp on an incoming packet might be, and 30
-the maximum age of an incoming packet.  You can tweak these numbers if
-you really want.  If you really can't get any kind of good clock
-synch, then it's probably OK to replace
-     -e nonce -e timestamp/10/30
-with
-     -e sequence
-(NB that we don't use -e sequence so it has not been well tested.)
+ Each endpoint machine will have at least two network interfaces:
+ Firstly, the real `physical' interface through which the encapsulated
+ packets will be really sent and received.  Secondly, the `virtual'
+ interface created by the tunnelling software, which represents its
+ end of the (encrypted) tunnel link.  The physical and virtual
+ interfaces MUST have different addresses.
 
->         davenant-external,410                                   \
-
-This is the local address and port for sending/receiving encapsulated
-packets.  davenant is the tunnel endpoint, and davenant-external is
-its globally-reachable address (we run two networks on the wire at
-Relativity, an internal one and a globally-reachable one).
-
->         chiark-public,Command                                   \
-
-This is the remote address and port for encapsulated packets.
-`Command' means find out the remote address or port to send
-encapsulated packets to by having udptunnel at the far end print its
-address and port when they have been allocated.
-
-Another possibility here is to use a fixed remote port number.
+ Each endpoint machine may also have additional network interfaces;
+ for example, it may be the router for a network which sits behind it,
+ which an interface on that network, or it may be the endpoint for
+ more than one tunnel.  It is OK for several tunnels terminating at
+ the same machine to use the same virtual address (provided that the
+ tunnels are not `layered' on top of each other but are `in
+ parallel'), and it is also OK to use as the virtual tunnel address a
+ router's address on a private network which will be sent via the
+ tunnel.
 
-The DNS at GR has just `chiark' meaning chiark via the tunnel, so we
-have to use chiark-public which means its public IP address.
+1.3. Diagram
 
->         172.31.80.6,172.31.80.9,1000,cslip                      \
+     ____        ______________               ______________        ____
+  __(    )__    |ALICE         |             |           BOB|    __(    )__
+,'  `   '   `.  |        _     |  Tunnel     |     _        |  ,'  `   '   `.
+|   alice    |  |       |\\ ,- - - - - - - - - -. //|       |  |    bob     |
+`._private _.'  |       | ||   |             |   || |       |  `._private _.'
+|  networks  |==+--------'||   |  Public     |   ||`--------+==|  networks  |
+|            |  |      alice   |  Network    |   bob        |  |            |
+`.~       ~.'   |     virtual  +=============+  virtual     |  `.~       ~.'
+  (__,'`.__)    |______________|alice     bob|______________|    (__,'`.__)
+                              physical  physical
+                                                             _
+ Key:  HOSTNAME                 +===+ Actual Network        |\\ Tunnel
+       Descriptive Text         ----- Data Flow             | ||Endpoint
+       host or network number   - - - Encrypted Data Flow     ||
+
+
+2. SETUP INSTRUCTIONS
+
+ All of these steps can be done using the appropriate normal user
+ accounts, unless otherwise indicated.
+
+2.1. Find out, or choose, private network numbers
+
+ You need to make sure you know what all of the addresses in the above
+ diagram are going to be.
+
+ Usually you must choose the private and virtual addresses yourself:
+ hosts on the private networks usually won't communicate with the
+ global Internet other than through proxies or masquerading firewalls.
+
+ You MUST choose from the reserved ranges in RFC1918, which are:
+    172.16.0.0/12   192.168.0.0/16   10.0.0.0/8
+ If you do not do so you'll end up reusing someone else's addresses,
+ which can cause lots of hard-to-diagnose and embarrasing problems.
+
+ You should CHOOSE RANDOMLY !  This makes sure that when you decide to
+ connect your VPN to someone else's VPN, your network allocation
+ numbers are unlikely to clash.  If you both choose 192.168.0.0/24
+ you'll have to renumber (and will look like fools).
+
+ To help with choosing random network numbers from RFC1918 space, the
+ author maintains a web page at <http://www.ucam.org/cam-grin/>, which
+ can pick network numbers for you.
+
+ Additionally, there is a database there - people in Cambridge (in
+ England) are encouraged to register their network address usage
+ there.  Please do not register in the database unless you're likely
+ to want to connect your VPN to others already listed.
+
+2.2. Find out, or choose, public network numbers
+
+ These are usually specified by your ISP, either statically or
+ dynamically assigned.  If the active end (`alice physical') is
+ dynamically assigned you can use the `Wait' option (see below) to
+ avoid specifying it, but otherwise you will need to have some kind of
+ script to find it each time you invoke udptunnel, or use a hostname
+ which automatically tracks the source host using dynamic DNS.
+
+ In some situations you may find yourself using a `public network'
+ which is not actually the public Internet - for example, you may want
+ to run one tunnel `through' another, or your `public network' is
+ actually a private radio LAN.  In this case you'll have to choose the
+ addresses to use from RFC1918-space, as above.
+
+2.3. Decide which user account(s) on alice and bob you will use
+
+ These user accounts will see the plaintext for all network packets
+ going over the tunnel and if compromised will be able steal or forge
+ tunnel traffic.  So, they should be reasonably secure.
+
+ Let us assume that the account on alice is called Tbob, and the
+ account on bob is called Talice.  (NB that your system may not
+ correctly handle usernames containing uppercase.)
+
+ Each account should be in a group of its own, which will be used for
+ the userv ipif access control.
+
+ Arrange that Tbob@alice can ssh to Talice@bob without needing a
+ passphrase or other user interaction.
+
+ (Obviously, if you need to create accounts, edit groups, or change
+ the sshd configuratioon, you may need to be root.)
+
+2.3. Configure the private network numbers in /etc/userv/ipif-networks
+
+ (This step needs to be done as root.)
+
+ On alice, in /etc/userv/ipif-networks, put
+  <Tbob-gid>,=<alice-virt-addr>/32,     <Tbob-group>,   <comment>
+  <Tbob-gid>,<bob-virt-addr>/32,        <Tbob-group>,   <comment>
+ and for each of bob's private networks
+  <Tbob-gid>,<network>/<prefix-len>,    <Tbob-group>,   <comment>
+ You can leave out the <bob-virt-addr>/32 line if bob's virtual
+ address is in one of bob's private networks.
+
+ On bob, do the corresponding.  In /etc/userv/ipif-networks, put
+  <Talice-gid>,=<bob-virt-addr>/32,     <Talice-group>, <comment>
+  <Talice-gid>,<alice-virt-addr>/32,    <Talice-group>, <comment>
+ and for each of alice's private networks
+  <Talice-gid>,<network>/<prefix-len>,  <Talice-group>, <comment>
+ Again, you can leave out <alice-virt-addr> if one of the virtual
+ networks covers it.
+
+ All the specifications in /etc/userv/ipif-networks must be numerical
+ addresses - hostnames are not allowed.  Also, the /32 indicating a
+ specific host cannot be omitted.
+
+ Note the use of `=' for each host's own virtual address, which
+ indicates to userv ipif that it's OK for that gid to create a local
+ interface with that address, but the address may not be assigned to a
+ remote host or route.
+
+2.4. Construct the udptunnel invocation (on alice)
+
+ udptunnel has a long and complicated command line, rather than a
+ configuration file.  The best way to deal with this is to create a
+ shell script which runs udptunnel with the right options.  This
+ script will live on alice in ~Tbob, and be run by Tbob.  Let us call
+ it `udptunnel-invoke-bob'.
+
+ For the most basic setup, it should look something like this:
+
+  #!/bin/sh
+  set -e
+  set -x
+
+  udptunnel                                                      \
+          -e nonce -e timestamp/10/30                            \
+          -e pkcs5/8 -e blowfish-cbcmac/128 -e blowfish-cbc/128  \
+          <alice-physical-hostname>,Any                          \
+          <bob-physical-hostname>,Command                        \
+          <alice-virtual>,<bob-virtual>,1000,cslip               \
+          30,130,1800                                            \
+          <bob-private-nets> <alice-private-nets>                \
+          ssh     -o 'BatchMode yes'                             \
+                  -v <Talice>@<bob-physical-hostname>            \
+                  udptunnel
+
+ You have to fill in the right values for things in angle brackets.
+ (See also section 6. for a moderately complex example, below.)
+
+2.4.1. Syntax of <alice-private-nets> and <bob-private-nets>
+
+ These arguments to udptunnel are the network address ranges at each
+ end which are to be connected via the tunnel.  Let us consider just
+ <alice-private-nets>; <bob-private-nets> is just the same, but for
+ bob's end.
+
+ <alice-private-nets> is a comma-separated list of networks specified
+ as <network>/<prefix-len>.  The network address must be numerical,
+ and the prefix length must always be specified.
+
+ If there are no private networks `behind' alice, ie the tunnel is
+ just to connect alice to bob and things at bob's end, then specify
+ `-' for <alice-private-nets>.
+
+2.4.2. IP masquerading (NAT) at alice's end
+
+ If alice is behind a masquerading (NAT) firewall, you can still get
+ it to work.  You need to add an option `-m' before the other
+ arguments.  This will make udptunnel on alice tell udptunnel on bob
+ to wait for alice's first encapsulated packet before deciding what
+ alice's physcial address and port number are, as seen by bob.  That
+ way alice doesn't need to know what port number the NAT proxy will
+ use.
+
+2.4.3. Using fixed UDP port numbers (eg to make firewally happy)
+
+ If alice is behind a firewall which will not allow incoming UDP to
+ arbitrary ports, even when sent in reply to packets of alice's, you
+ have to arrange for alice to use a fixed port number.  Change
+          <alice-physical-hostname>,Any                         \
+ to
+          <alice-physical-hostname>,<alice-physical-port>       \
+
+ udptunnel will need to be able to bind to the relevant port, so you
+ must either (i) choose a port number over 1024, which risks other
+ processes on alice accidentally using that port, (ii) run udptunnel
+ as root on alice, or (iii) use authbind (authbind is a utility,
+ included in Debian, which can allow non-root programs to bind to low
+ ports in a controlled way).
+
+ If bob is behind such a firewall too, you can replace
+          <bob-physical-hostname>,Command                       \
+ with
+          <bob-physical-hostname>,<bob-physical-port>           \
+
+2.4.4. Clock skew and excessive delay
+
+ The default configuration given above, which includes this
+          -e nonce -e timestamp/10/30                            \
+ will not work if there is more than 10s of clock skew between alice
+ and bob's system clocks, or if the lag in either direction is more
+ than 30s.  It is best if your systems run with synchronised clocks
+ (you can run NTP over the tunnel if necessary) and don't have such
+ bad lag, of course.
+
+ However, you can increase these parameters if you really want.  To
+ increase the tolerance to clock skew to some amount, make sure that
+ both numbers are at least the amount of clock skew you're willing to
+ tolerate.  To increase the tolerance to delay it's only necessary to
+ increase the second number.
+
+ Warning: if you increase these numbers too much there is a risk that
+ packets delayed or repeated by an attacker will be treated as genuine
+ and cause communication or security problems.  I would not recommend
+ using a value more than 120 (2 minutes).
+
+ If you really can't get reasonable clock synch at all, you can use
+ sequence number replay detection instead of clock-based replay
+ detection.  Replace
+          -e nonce -e timestamp/10/30                            \
+ with
+          -e sequence                                            \
+
+2.4.5. Other things to tweak (it's usually safe to ignore this part)
+
+ Do not mess with the `-e' parameters and arguments except as
+ explained above, unless you are a cryptographer.
+
+ 30,130,1800 are timeouts which control the `dead tunnel detection'.
+ The first is the keepalive interval: when one end hasn't sent
+ anything for that many seconds, it will send an empty keepalive
+ packet.  The second is the dead tunnel timeout: when one end hasn't
+ received anything for that many seconds, it assumes the tunnel is
+ dead and dies (the other end will then usually die shortly if it
+ hasn't already).  The third is the status reporting interval - at
+ intervals of that many seconds each end will report (to udptunnel's
+ stdout) that the tunnel is still open and give some statistics; these
+ diagnostics also prevent the controlling ssh connection's entry in
+ masquerading and firewall tables from timing out.
+
+ 1000 (in ...,...,1000,cslip) is the MTU - the maximum size of packet
+ which will be sent through the tunnel.  It is best if this number is
+ a certain amount smaller than the path MTU over the physical network,
+ so that encapsulated packets do not get fragmented.  (Each packet
+ will be increased in size by 24 bytes + the size of a UDP and IP
+ header + the effects of SLIP duplication of certain bytes.)
+
+
+3. Test your udptunnel invocation script
+
+3.1. Invocation
+
+ Log into alice as Tbob, and run ./udptunnel-invoke-bob.
+ A great deal of diagnostic output will ensue.
+
+ If all is well you will see two messages looking something like this
+  udptunnel-forwarder: bob: tunnel open with peer 127.0.0.3:76543
+  udptunnel-forwarder: alice: tunnel open
+ and the session will just sit there.  Go to 3.2.
+
+ If it didn't say that, here are some debugging tips:
+
+ * If it just sits there for a minute or two and then udptunnel times
+ out, the physical packets aren't getting back and forth.  Use
+ tcpdump, check your firewall and routing (as below), and consult the
+ sections above about NAT and firewalls.
+
+ * If it bombed out, look for an error message in the diagnostics.
+ There will be lots of `subprocess somethingorother exited with
+ nonzero exit status 47', `no details received from remote' and the
+ like, but these are probably not the ones you want to look at,
+ because they're usually just consequences of some other failure.
+
+  Permission denied.
+  udptunnel - alice: fatal error: remote command failed (code ...)
+    Tbob had trouble ssh'ing to Talice@bob.  Check that the ssh
+    configuration is set up, and test it separately.
+
+  userv-ipif service: access denied for ...., ....
+  udptunnel - alice: subprocess local command failed with code 2048
+    The arguments to udptunnel don't correspond to
+    /etc/userv/ipif-networks on alice.  Either the arguments to
+    udptunnel or the ipif-networks file is wrong.  (Or, if the message
+    about `local command failed' mentions bob, look on bob.)
+
+  udptunnel - alice: subprocess forwarder failed with code 14
+    The tunnel timed out - no packets were successfully received for
+    130 seconds.  See 2.4.5 above for details of the timeout
+    parameters.  (NB, applies to `code 14' only.)
+
+  usage errors from udptunnel or ssh, or sh: ...: unknown command
+    Perhaps you dropped a \ from the udptunnel-invoke-bob script ?
+
+  udptunnel not found, udptunnel-forwarder not found
+    Check that the PATH includes /usr/local/bin.  Noninteractive `ssh'
+    invocations (ie, ones with a command specified) often have a
+    different PATH.
+
+  slattach cannot open /dev/2 (or similar messages)
+    Your slattach is buggy.  See under `slattach problem' in the build
+    and installation instructions, above.
+
+  slattach cannot change line discipline (or some other weird message)
+    Check whether your kernel is compiled with SLIP and/or CSLIP
+    support.
+
+ * Other messages:
+
+  udptunnel-forwarder: alice: bad packet: blowfish-cbcmac: verify failed
+    This can be caused by actual packet corruption on the physical
+    network (or even by an actual hostile attack), but when using
+    fixed port numbers these messages are common after the tunnel has
+    died and been restarted: they correspond to packets from the
+    previous invocation (which is usung different keys) being rejected
+    because their checksums don't match.  In this case they should go
+    away in a minute or two.
+
+3.2. Testing, once the tunnel claims to be working
+
+ In another session on alice, you should be able to ping bob's virtual
+ interface.  If this works, test pinging between hosts on the private
+ networks behind alice and bob.  If all is well, go onto step 4.
+
+ If not, here are some troubleshooting hints:
+
+ * Use numerical addresses when testing.  This eliminates DNS problems
+ from your test strategy.
+
+ * Use `ifconfig' and `route -n' on alice and bob to check that the
+ interfaces and routes all look right.  The tunnel will show up as a
+ `sl<n>' for some <n>.
+
+ * Use `tcpdump -n -i <interface>' to watch the traffic go across some
+ interface, to try to figure out where the traffic is going.  Look
+ both for the private traffic before it goes into the tunnel, and the
+ physical traffic, to try to find out where it disappears.  The
+ diagnostics will tell you which physical ports it's using, something
+ like this:
+   udptunnel - alice: debug: using remote Wait,Wait local 131.111.232.108,1422
+   udptunnel - bob: debug: using remote 131.111.232.108,1422 local 195.224.38.6,2413
+
+ * alice and bob can see each other but the private networks can't ?
+ Make sure alice and bob both have IP forwarding enabled.
 
-172.31.80.6 is davenant's tunnel endpoint address.
-172.31.80.9 is the address of chiark's Relativity tunnel endpoint.
+ * Check your firewalls, if you have them.  It's most helpful if your
+ firewall configuration arranges to log rejected packets - without
+ that, they can be a complete pain to debug.
 
->         30,120,1800                                             \
 
-These are timing parameters.  30 is the `keep alive' timeout; if
-nothing is sent for this many seconds, an empty packet is sent.  120
-is the `broken' timeout; if nothing valid is received for this many
-seconds, the tunnel is declared dead and dies (hopefully to be
-restarted); 1800 is the time in seconds between messages of the form
-  udptunnel-forwarder: chiark: tunnel still open: received 746
-  packets, 103257 bytes
-These serve as a useful diagnostic, and also prevent the controlling
-ssh connection from timing out from NAT tables.
+4. Configure the tunnel to run automatically
+
+ Now that the tunnel works if you invoke it by hand, it is time to
+ arrange to run it automatically.
+
+ If you want the tunnel to run over a dialup link only when the dialup
+ link is up, then I'm afraid you'll have to arrange to start and kill
+ it yourself, probably.  I haven't set up such a configuration.  More
+ information about this for this document, if you manage to do it,
+ would be good.
+
+ So, I shall assume that you want the tunnel to be up all of the time
+ (or at least, as much as possible).  The best way to do this is to
+ run it from `init', by setting it up in inittab.
+
+ For example, you could put something like this in your inittab:
+  t0:23:respawn:su Tbob -c ./udptunnel-invoke-bob 2>&1 | logger -p local2.info -t tunnel-bob
+ (Note that if you have more than one tunnel the `id' field, at the
+ start of the inittab line, must be different for each one.)
 
->         - 172.18.45.0/24                                        \
+ This would use `su' to become bob and run the actual tunnelling
+ software, and arrange for the diagnostic output to be sent to syslog
+ with facility `local2' and priority `info', tagged with `tunnel-bob'.
+ With an appropriate line in /etc/syslog.conf, such as
+  local2.*                              /var/log/local2-all.log
+ (remember that you have to use tabs in syslog.conf) this will
+ produce, in /var/log/local2-all.log, all the diagnostics, including
+ reassuring messages like this:
+  Sep 18 00:27:48 alice tunnel-bob: udptunnel-forwarder: alice: tunnel still open: received 5262 packets, 5262 bytes
+  Sep 18 00:28:44 alice tunnel-bob: udptunnel-forwarder: bob: tunnel still open: received 5280 packets, 5280 bytes
 
-`-' here is the remote networks which are reachable.  None are
-reachable via chiark.  172.18.45.0/24 is the Relativity house
-ethernet.
 
->         ssh     -o 'ForwardAgent no' -o 'ForwardX11 no'         \
->                 -o 'BatchMode yes'                              \
->                 -i ~ian/.ssh/identity -l ian                    \
->                 -v chiark.greenend.org.uk                       \
->                 udptunnel
+5. DNS, firewall, mail, etc.
 
-This is the ssh invocation to run udptunnel at the far end.
+ Now you have IP level connectivity between your two networks.  You
+ must now arrange for:
 
-When you have this invocation working in a shell window you need to
-make it run automatically.  Since the tunnel will die whenever your
-IP address changes, or when other troublesome events happen, you must
-arrange for it to be restarted.  At Relativity we put the udptunnel
-invocation in a file and run it out of inittab, like this:
+ * An appropriate firewall on each tunnel endpoint (to stop attacks
+ from one network to another) and also at all the borders of each
+ network (to stop traffic that is going to, or looks like it came
+ from, the private networks).
 
-t0:235:respawn:/usr/local/sbin/really -u ian /usr/local/sbin/udptunnel-invoke 2>&1 | logger -p local2.info -t tunnel-chiark
+ * DNS configuration so that hosts on both sides of the tunnel can see
+ each other's names, addresses and other information.
 
+ * Mail, news and other application protocols may need to be
+ configured to use the private tunnel connectivity, rather than
+ treating the other private network's names as being `elsewhere' and
+ using unencrypted connectivity via the global Internet.
 
-Troubleshooting:
+ How to do these things is beyond the scope of this document.
 
-Look at the error messages, they will hopefully be informative.
 
-If you see a message from `slattach' about being unable to open /dev/2
-or some such, then you need to upgrade your `slattach'.  In Debian
-GNU/Linux it's in the `netbase' package, and the fix is in 3.16-3 and
-later; however the bug has regressed, and is known to be in 3.18-4 and
-earlier.  The relevant Debian bug reports are #45515 (now closed) and
-#45944.  A patch to correct 3.18-4 is in this directory as
-`slattach.diff'.
+6. Example
+
+ This example is the tunnel between chiark and Relativity.  I'll quote
+ it and explain the details, below.  See also the comment at the top of
+ udptunnel.
+
+ authbind udptunnel                                               \
+          -m                                                      \
+          -e nonce -e timestamp/10/30 -e pkcs5/8                  \
+          -e blowfish-cbcmac/128 -e blowfish-cbc/128              \
+          davenant-external,410                                   \
+          chiark-public,Command                                   \
+          172.31.80.6,172.31.80.9,1000,cslip                      \
+          30,120,1800                                             \
+          - 172.18.45.0/24                                        \
+          ssh     -o 'ForwardAgent no' -o 'ForwardX11 no'         \
+                  -o 'BatchMode yes'                              \
+                  -i ~ian/.ssh/identity -l ian                    \
+                  -v chiark.greenend.org.uk                       \
+                  udptunnel
+
+ Because at Relativity the tunnel endpoint has to not be our firewall,
+ because the firewall is a 386SX/16 and so not powerful enough,
+ Relativity practically has to be the active partner in any tunnels it
+ is involved in.  This also necessitates the use of the `-m' option and
+ various other things.
+
+ Exposition of the example udptunnel invocation:
+
+ > authbind udptunnel                                              \
+
+ `authbind' is used because at Relativity the tunnel endpoint address
+ has to be on a fixed port because our tunnel endpoint is not on the
+ firewall system (if it's not on a fixed port we can't write a good
+ firewall rule to let it through).
+
+ The port we are using is port 410, a low port to prevent other
+ processes `stealing' it, so root privilege or authbind is needed.
+
+ >         -m                                                      \
+
+ -m tells this invocation of udptunnel that its endpoint address and
+ port (for encapsulated packets) are going to be NATted before the far
+ end sees them.  The effect is that instead of supplying this
+ information to the far end, the far end is told to `wait and see'.
+
+ This should not usually be used in other circumstances.  (For full
+ details see the comment at the top of udptunnel.)
+
+ >         -e nonce -e timestamp/10/30 -e pkcs5/8                  \
+ >         -e blowfish-cbcmac/128 -e blowfish-cbc/128              \
+
+ This is the crypto configuration.
+
+ >         davenant-external,410                                   \
+
+ This is the local physical address and port.  davenant is the tunnel
+ endpoint, and davenant-external is its public address (we run two
+ networks on the wire at Relativity, an internal one and a public
+ one).
+
+ >         chiark-public,Command                                   \
+
+ This is the physical remote address and port.  `Command' means find
+ out the remote physical address or port by having udptunnel at the
+ far end print its address and port when they have been allocated.
+
+ Another possibility here is to use a fixed remote port number.
+
+ The DNS at GR is configured so that just `chiark' means chiark via
+ the tunnel, so we have to use chiark-public which means its public
+ IP address.
+
+ >         172.31.80.6,172.31.80.9,1000,cslip                      \
+
+ 172.31.80.6 is davenant's virtual address.
+ 172.31.80.9 is chiark's virtual address for the Relativity tunnel.
+
+ >         30,130,1800                                             \
+
+ These are the timing parameters.
+
+ >         - 172.18.45.0/24                                        \
+
+ No remote virtual networks are reachable via chiark.  172.18.45.0/24
+ is the Relativity house ethernet, which is to be reachable via the
+ tunnel from chiark.
+
+ >         ssh     -o 'ForwardAgent no' -o 'ForwardX11 no'         \
+ >                 -o 'BatchMode yes'                              \
+ >                 -i ~ian/.ssh/identity -l ian                    \
+ >                 -v chiark.greenend.org.uk                       \
+ >                 udptunnel
+
+ This is the ssh invocation to run udptunnel at the far end.
+
+ At Relativity we put the udptunnel invocation in a file and run it
+ out of inittab, like this:
+
+ t0:235:respawn:/usr/local/sbin/really -u ian /usr/local/sbin/udptunnel-invoke 2>&1 | logger -p local2.info -t tunnel-chiark
+
+
+7. Copyright notice
+
+ Copyright (C) 1999-2000 Ian Jackson
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with userv-utils; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 
 $Id$
diff --git a/ipif/README b/ipif/README
new file mode 100644 (file)
index 0000000..1814fe2
--- /dev/null
@@ -0,0 +1,68 @@
+This directory contains:
+
+* userv ipif
+
+  A userv service for allowing users to create network interfaces and
+  handle the traffic for them.
+
+* udptunnel
+
+  A VPN tunnelling system based on userv ipif, which does encryption
+  and can be used to join two hosts or whole networks.  It uses its
+  own nonstandard protocols, not IPSEC.  Key setup is done via an ssh
+  connection, and actual data packets are sent (encrypted) using UDP.
+  With the appropriate configuration in userv ipif, users can be
+  allowed to create VPN connections without needing root privilege.
+
+These tools have only been tested on GNU/Linux, and userv ipif in
+particular uses the Linux-specific `slattach' utility.
+
+
+The documentation available is:
+
+INSTALL
+
+  Build and install instructions for both ipif and udptunnel, and
+  tutorial on setting up userv ipif and udptunnel in the usual way.
+
+udptunnel (head comment)
+
+  Configuration and invocation reference information for the udptunnel
+  VPN facility.
+
+service.c (head comment)
+
+  Reference information for userv ipif service, including syntax of
+  /etc/userv/ipif-networks, and command line arguments to userv ipif.
+
+mech-*.c (head comments)
+
+  Detailed specifications of encryption, padding,
+  etc. transformations.  For use by cryptographers only; otherwise,
+  follow the advice elsewhere about what transformations to use.
+
+forwarder.c (head comment)
+
+  Underlying UDP forwarding program invocation details.  This program
+  is normally invoked correctly by `udptunnel'.  You should not need
+  to read these details unless you are debugging or modifying udptunnel.
+
+
+Copyright (C) 1999-2000 Ian Jackson
+
+This is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with userv-utils; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+$Id$
index b1cb192..40d1de2 100644 (file)
@@ -1,10 +1,12 @@
 /*
  * Blowfish mechanism for udp tunnel
  *
+ * mechanisms: blowfish-cbc, blowfish-cbcmac
  * arguments: key size in bits (must be multiple of 8)
  *
  * key values: 8 byte random IV and n byte random key
  *
+ * restrictions: plaintext length must be multiple of block size (8 bytes)
  * encoding:         do CBC encryption overwriting message
  * encoding for MAC: do CBC and prepend last ciphertext block
  */
index fccb7d7..ab0f8d7 100644 (file)
@@ -1,5 +1,12 @@
 /*
  * Null mechanism for udp tunnel (for testing purposes only)
+ *
+ * mechanisms: null
+ * arguments: none
+ *
+ * key values: none
+ * restrictions: none
+ * encoding: no transformation
  */
 /*
  * Copyright (C) 2000 Ian Jackson
index f03787b..f7d0bbd 100644 (file)
@@ -1,8 +1,10 @@
 /*
  * PKCS#5 padding mechanism for udp tunnel
  *
- * arguments: block size to pad to, must be power of 2
+ * mechanism: pkcs5
+ * arguments: block size to pad to, must be power of 2 and <=128
  *
+ * restrictions: none
  * encoding: append between 1 and n bytes, all of the same value being
  *           the number of bytes appended
  */
index 76c8c83..30fab47 100644 (file)
@@ -1,10 +1,12 @@
 /*
  * Sequence number / nonce mechanism for udp tunnel
  *
+ * mechanisms: nonce, sequence
  * arguments: none
  *
+ * restrictions: none
  * encoding: prepend 4 bytes of sequence arithmetic serial number
- * decoding: check increasingness, or ignore
+ * decoding: check increasingness (sequence), or ignore (nonce)
  */
 /*
  * Copyright (C) 2000 Ian Jackson
index d1b83d5..cd31d57 100644 (file)
@@ -1,8 +1,10 @@
 /*
  * Timestamp mechanism for udp tunnel
  *
+ * mechanism: timestamp
  * arguments: <max-skew> <max-age>
  *
+ * restrictions: none
  * encoding: prepend 4 bytes of UNIX time in network byte order
  *
  * <max-age> is maximum age in seconds we will accept a packet (or 0
index 97351e6..397740c 100644 (file)
@@ -1,37 +1,87 @@
 /*
- * userv service (or standalone program)
- * for per-user IP subranges.
+ * userv service (or standalone program) for per-user IP subranges.
+ *
+ * When invoked appropriately, it creates a point-to-point network
+ * interface with specified parameters.  It arranges for packets sent out
+ * via that interface by the kernel to appear on its own stdout in SLIP or
+ * CSLIP encoding, and packets injected into its own stdin to be given to
+ * the kernel as if received on that interface.  Optionally, additional
+ * routes can be set up to arrange for traffic for other address ranges to
+ * be routed through the new interface.
+ *
+ * This is the service program, which is invoked as root from userv (or may
+ * be invoked firectly).
+ *
+ * Its arguments are supposed to be, in order, as follows:
+ *
+ *  The first two arguments are usually supplied by the userv
+ *  configuration.  See the file `ipif/ipif' in the source tree, which
+ *  is installed in /etc/userv/services.d/ipif by `make install':
  *
- * This is invoked as root, directly from userv.
- * Its arguments are supposed to be, in order:
  *  <config>
- *      Specifies address ranges and gids which own them.
- *  --  Indicates that the remaining arguments are user-supplied
- *      and therefore untrusted.
+ *
+ *      Specifies address ranges and gids which own them.  The default
+ *      configuration supplies /etc/userv/ipif-networks, which is then read
+ *      for a list of entries, one per line.
+ *
+ *  --
+ *      Serves to separate the user-supplied and therefore untrusted
+ *      arguments from the trusted first argument.
+ *
+ *  The remaining arguments are supplied by the (untrusted) caller:
+ *
  *  <local-addr>,<peer-addr>,<mtu>,<proto>
+ *
  *      As for slattach.  Supported protocols are slip, cslip, and
- *      adaptive.  Alternatively, set to `debug' to print debugging
- *      info.  <local-addr> is address of the interface on the local
- *      system; <peer-addr> is the address of the point-to-point peer.
+ *      adaptive.  Alternatively, set to `debug' to print debugging info
+ *      and exit.  <local-addr> is address of the interface to be created
+ *      on the local system; <peer-addr> is the address of the
+ *      point-to-point peer.  They must be actual addresses (not
+ *      hostnames).
+ *
  *  <prefix>/<mask>,<prefix>/<mask>,...
- *      List of additional routes to add for this interface.
- *      May be the empty argument, or `-' if this is problematic.
  *
- * <config> is either
- *    <gid>,[=]<prefix>/<len>[,<junk>]
- *      indicating that that gid may allocate addresses in
- *      the relevant subspace (<junk> is ignored)
- *      if `=' is specified then it's only allowed for the local
- *      endpoint address
- * or #...
- *      which is a comment
- * or /<config-file-name> or ./<config-file-name> or ../<config-file-name>
- *      which refers to a file which contains lines which
- *      are each <config>
- * or *
- *      which means that anything is permitted
- * 
- * Should be run from userv with no-disconnect-hup.
+ *      List of additional routes to add for this interface.  routes will
+ *      be set up on the local system arranging for packets for those
+ *      networks to be sent via the created interface.  <prefix> must be an
+ *      IPv4 address, and mask must be an integer (dotted-quad masks are
+ *      not supported).  If no additional routes are to be set up, use `-'
+ *      or supply an empty argument.
+ *
+ * Each <config> item - whether a line file such as
+ * /etc/userv/ipif-networks, or supplied on the service program
+ * command line - is one of:
+ *
+ *   /<config-file-name>
+ *   ./<config-file-name>
+ *   ../<config-file-name>
+ *
+ *      Reads a file which contains lines which are each <config>
+ *      items.
+ *
+ *   <gid>,[=]<prefix>/<len>[,<junk>]
+ *
+ *      Indicates that <gid> may allocate addresses in the relevant address
+ *      range (<junk> is ignored).  <gid> must be numeric.  To specify a
+ *      single host address, you must specify a mask of /32.  If `=' is
+ *      specified then the specific subrange is only allowed for the local
+ *      endpoint address, but not for remote addresses.
+ *
+ *   *
+ *      Means that anything is to be permitted.  This should not appear in
+ *      /etc/userv/ipif-networks, as that would permit any user on the
+ *      system to create any interfaces with any addresses and routes
+ *      attached.  It is provided so that root can usefully invoke the ipif
+ *      service program directly (not via userv), without needing to set up
+ *      permissions in /etc/userv/ipif-networks.
+ *
+ *   #...
+ *
+ *      Comment.  Blank lines are also ignored.
+ *
+ *   NB: Permission is granted if _any_ config entry matches the request.
+ *
+ * The service program should be run from userv with no-disconnect-hup.
  */
 /*
  * Copyright (C) 1999-2000 Ian Jackson
index 09595d1..963245c 100755 (executable)
 #!/usr/bin/perl
-# Simple tunnel for userv-ipif tunnels.
+# Encrypting VPN tunnel for use with userv-ipif.
 #
-# Example test invocation
-#
-#  ./udptunnel -e nonce -e timestamp/10/30 -e pkcs5/8 -e blowfish-cbcmac/128 -e blowfish-cbc/128 -m -f ./udptunnel-forwarder davenant,Any anarres,Command 172.30.206.1,172.30.206.2,1000,cslip 15,70 '' '' rsh anarres things/userv-utils/ipif/udptunnel -f things/userv-utils/ipif/udptunnel-forwarder
+# This comment is reference documentation.  See ipif/INSTALL for the
+# installation instructions and setup tutorial.
 #
 # usage:
-#  udptunnel
-#        [ -l[<local-command/arg>] ... .
+#  To make a tunnel between two machines `alice' and `bob',
+#  on `alice', the active endpoint, run:
+#
+#   udptunnel
+#        [ -l[<alice-command/arg>] ... .
 #        | -e <encryption-mech>[/<encryption-parameter>...]
-#        | -m   (`masquerade support': subcommand gets `Wait' instead of our addr/port)
-#        | -d   (`dump keys': when no subcmd, spew keys rather than reading them;
-#                we always send keys to our subcmd if there is one)
+#        | -m   (`masquerade support': bob gets `Wait' instead of our addr/port)
+#        | -d   (`dump keys': when no peer, spew keys rather than reading them;
+#                we always send keys to our peer if there is one)
 #        | -Dcrypto  (debug crypto - use with care, prints keys, packets &c on screen!)
 #        | -f<path-to-udptunnel-forwarder>
 #          ...
 #        ]
-#            <public-local-addr>,<public-local-port>
-#            <public-remote-addr>,<public-remote-port>
-#            <private-local-addr>,<private-remote-addr>,<mtu>,<proto>
+#            <alice-phys-addr>,<alice-phys-port>
+#            <bob-phys-addr>,<bob-phys-port>
+#            <alice-virt-addr>,<bob-virt-addr>,<mtu>,<proto>
 #            <keepalive>,<timeout>[,<reannounce>]
-#            <extra-nets-for-local-cmd> <extra-nets-for-remote-cmd>
-#          [ <remote-command> [<remote-args> ...] ]
+#            <alice-priv-nets> <bob-priv-nets>
+#          [ <bob-command> [<bob-args> ...] ]
+#
+# This will run udptunnel-forwarder on alice, and use <bob-command>
+# (usually an ssh invocation) to run udptunnel appropriately on bob.
+# Key material will be generated by alice and fed to udptunnel on bob
+# via <bob-command>'s stdin, and the physical address and port on bob
+# will be (if so configured) returned via <bob-command>'s stdout.
+#
+# The tunnel will stay up until one of the subprocesses involved dies,
+# or the keepalive timeout expires.  If you want the tunnel to remain
+# up permanently, you must arrange to invoke it repeatedly (eg, from
+# inittab).  See INSTALL.
 #
-# proto may be slip or cslip
+# <proto> may be slip or cslip
 #
-# Any <..-addr> may also be hostname
+# <mtu> will be the MTU of the tunnel interfaces; it is best if this
+# is enough smaller than the path MTU between the physical interfaces
+# that the encapsulated packets will fit without fragmentation.
 #
-# Local addr's and ports may also be:
+# Any <..-addr> supplied to udptunnel may also be hostname; these will
+# all be looked up on alice and IP addresses passed to bob.
+#
+# The `local' physical address and ports (ie, alice's own details),
+# may have these special values:
+#    `Any'       choose one ourselves and do not print it (the port chosen
+#                will be supplied to bob)
 #    `Print'     choose one ourselves and print both port and addr
-#    `Any'       choose one ourselves and do not print it
-# Remote addr's and ports may also be:
-#    `Wait'      wait to receive a packet before assigning address
-#    `Command'   run a subcommand and wait for it to tell us the values
-# When any addr or port is `Command' then <remote-command> must be specified.
+#                (this is not usually useful specified directly; it's
+#                used by udptunnel when it invokes itself on bob via
+#                <bob-command>, to have its other self print the
+#                relevant value.
 #
-# If <remote-command> is specified it should run udptunnel at the
-# remote end; it will be invoked as
-#    <remote-command> [ <-e arguments passed along> ]
-#                     <public-remote-addr'>,<public-remote-port'>
-#                     <public-local-addr'>,<public-local-port'>
-#                     <private-remote-addr>,<private-local-addr>,<mtu>,<proto>
-#                     <keepalive>,<timeout>[,<reannounce>]
-#                     <extra-nets-for-remote-cmd> <extra-nets-for-local-cmd>
+# The `remote' physical address and port (ie, on alice, bob's details),
+# may also have the special values:
+#    `Command'   wait for <bob-command> to tell us the values (this is
+#                usually the right choice on alice for at least the
+#                port).  <bob-command> must be specified (ie, this
+#                only makes sense on alice).
+#    `Wait'      alice will wait to receive a packet from bob and use
+#                whatever address and port it came from
 #
-
-# If it was given Print for <public-remote-foo'>, this command's first
-# stdout output should be the real
-# <public-remote-addr>,<public-remote-port> pair (and of course this
-# udptunnel's output will be).  It may then produce more stdout which,
-# if any, will be forwarded to the local end's stdout as debugging info.
+# These special values are case-sensitive.  When alice runs udptunnel
+# on bob they are automatically translated to appropriate other values
+# in the arguments to bob's udptunnel.
+#
+# If <bob-command> is specified it should run udptunnel at the
+# bob end; it will be invoked as
+#    <bob-command> [ <bob-args> ... ]
+#                  [ <-e arguments passed along> ]
+#                    <bob-phys-addr'>,<bob-phys-port'>
+#                    <alice-phys-addr'>,<alice-phys-port'>
+#                    <bob-virt-addr>,<alice-virt-addr>,<mtu>,<proto>
+#                    <keepalive>,<timeout>[,<reannounce>]
+#                    <bob-priv-nets> <alice-priv-nets>
+#
+# If it was given Print for <bob-phys-foo'>, udptunnel's first stdout
+# output will be the real <bob-phys-addr>,<bob-phys-port> pair.  It
+# may then produce more stdout which, if any, will be forwarded to the
+# local end's stdout as debugging info.
 #
-# After this, if any encryption was specified, the encryption
-# parameters will be fed into its stdin.  See the documentation in the
-# mech-*.c files for details of the parameters.  udptunnel will
-# arrange to feed the keys fd of udptunnel-forwarder into the stdin of
-# the remote command.
+# After this, if any encryption was specified, the encryption key
+# material will be fed into its stdin.  See the documentation in the
+# mech-*.c files for details of the parameters.  udptunnel on alice
+# will arrange to feed the keys fd of udptunnel-forwarder into the
+# stdin of the udptunnel on bob.
 #
-# <public-remote-foo'> is as follows:
-#   <public-remote-foo>  <public-remote-foo'>
-#   actual addr/port     that addr/port
-#   `Command'            `Print'
-#   `Wait'               `Any'
+# <bob-phys-foo'> is as follows:
+#   <bob-phys-foo>       <bob-phys-foo'>
+#    actual addr/port     that addr/port
+#    `Command'            `Print'
+#    `Wait'               `Any'
 #
-# <public-local-foo'> is as follows:
-#   <public-local-foo>   <public-local-foo'>     <public-local-foo'>
-#                        (-m not specified)      (-m specified)
+# <alice-phys-foo'> is as follows:
+#   <alice-phys-foo>    <alice-phys-foo'>       <alice-phys-foo'>
+#                       (-m not specified)      (-m specified)
 #   actual addr/port     that addr/port         `Wait'
 #   `Print'              the chosen address     `Wait'
 #   `Any'                `Wait' for addr,       `Wait'
 #                         chosen port for port
 #
-# udptunnel will userv ipif locally, as
-#    userv root ipif <private-local-addr>,<private-remote-addr>,<mtu>,<proto>
-#                    <extra-nets-for-local-cmd>
+# In each case udptunnel will run userv ipif locally, as
+#    userv root ipif <local-virt-addr>,<remote-virt-addr>,<mtu>,<proto>
+#                    <remote-priv-nets>
 # or, if -l was given, userv root ipif is replaced with the argument(s)
 # following -l option(s) until `.'.
 #
-# udptunnel will also run udptunnel-forwarder with appropriate options
+# udptunnel will also run udptunnel-forwarder with appropriate options.
 #
 # recommended encryption parameters are:
 #   -e nonce                            (prepend 32 bit counter)
 #   -e pkcs5/8                          (pad as per PKCS#5 to 8-byte boundary)
 #   -e blowfish-cbcmac/128              (prepend CBC MAC with random IV and 128 bit key)
 #   -e blowfish-cbc/128                 (encrypt with CBC, random IV and 128 bit key)
-# where <max-skew> is perhaps 10 and <max-age> perhaps 30.
+# where <max-skew> is perhaps 10 and <max-age> perhaps 30.  If your
+# clocks are not sufficiently well synchronised, you could replace
+# `-e nonce -e timestamp/...' with just `-e sequence'.  Do not just
+# remove `-e timestamp/...'.
 
 # Copyright (C) 1999-2000 Ian Jackson
 #