From: ian Date: Mon, 18 Sep 2000 00:31:11 +0000 (+0000) Subject: @@ -1,8 +1,11 @@ X-Git-Tag: rel-uservutils-0-2-0~2 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=userv-utils.git;a=commitdiff_plain;h=5124214b2f9f6c40ac43ca9044a6b82eedd48b71;ds=sidebyside @@ -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 Mon, 18 Sep 2000 01:31:01 +0100 userv-utils (0.1.90) unstable; urgency=low --- diff --git a/README b/README index dfe735b..4dca21a 100644 --- 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 diff --git a/changelog b/changelog index b2bb618..1ced792 100644 --- 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 Mon, 18 Sep 2000 01:31:01 +0100 userv-utils (0.1.90) unstable; urgency=low diff --git a/debian/changelog b/debian/changelog index b2bb618..1ced792 100644 --- a/debian/changelog +++ b/debian/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 Mon, 18 Sep 2000 01:31:01 +0100 userv-utils (0.1.90) unstable; urgency=low diff --git a/ipif/INSTALL b/ipif/INSTALL index 6f23ec6..841ff22 100644 --- a/ipif/INSTALL +++ b/ipif/INSTALL @@ -1,210 +1,621 @@ -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: - -,[=]/, , - -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: -,172.31.80.6/32, , Relativity tunnel endpoint -,172.18.45.0/24, , Relativity house ethernet -as well as the local tunnel endpoint address, for example: -,=192.168.160.124/32, , 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 , 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 + ,=/32, , + ,/32, , + and for each of bob's private networks + ,/, , + You can leave out the /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 + ,=/32, , + ,/32, , + and for each of alice's private networks + ,/, , + Again, you can leave out 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 \ + ,Any \ + ,Command \ + ,,1000,cslip \ + 30,130,1800 \ + \ + ssh -o 'BatchMode yes' \ + -v @ \ + 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 and + + These arguments to udptunnel are the network address ranges at each + end which are to be connected via the tunnel. Let us consider just + ; is just the same, but for + bob's end. + + is a comma-separated list of networks specified + as /. 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 . + +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 + ,Any \ + to + , \ + + 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 + ,Command \ + with + , \ + +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' for some . + + * Use `tcpdump -n -i ' 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 index 0000000..1814fe2 --- /dev/null +++ b/ipif/README @@ -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$ diff --git a/ipif/mech-blowfish.c b/ipif/mech-blowfish.c index b1cb192..40d1de2 100644 --- a/ipif/mech-blowfish.c +++ b/ipif/mech-blowfish.c @@ -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 */ diff --git a/ipif/mech-null.c b/ipif/mech-null.c index fccb7d7..ab0f8d7 100644 --- a/ipif/mech-null.c +++ b/ipif/mech-null.c @@ -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 diff --git a/ipif/mech-pkcs5.c b/ipif/mech-pkcs5.c index f03787b..f7d0bbd 100644 --- a/ipif/mech-pkcs5.c +++ b/ipif/mech-pkcs5.c @@ -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 */ diff --git a/ipif/mech-sequence.c b/ipif/mech-sequence.c index 76c8c83..30fab47 100644 --- a/ipif/mech-sequence.c +++ b/ipif/mech-sequence.c @@ -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 diff --git a/ipif/mech-timestamp.c b/ipif/mech-timestamp.c index d1b83d5..cd31d57 100644 --- a/ipif/mech-timestamp.c +++ b/ipif/mech-timestamp.c @@ -1,8 +1,10 @@ /* * Timestamp mechanism for udp tunnel * + * mechanism: timestamp * arguments: * + * restrictions: none * encoding: prepend 4 bytes of UNIX time in network byte order * * is maximum age in seconds we will accept a packet (or 0 diff --git a/ipif/service.c b/ipif/service.c index 97351e6..397740c 100644 --- a/ipif/service.c +++ b/ipif/service.c @@ -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: * - * 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: + * * ,,, + * * As for slattach. Supported protocols are slip, cslip, and - * adaptive. Alternatively, set to `debug' to print debugging - * info. is address of the interface on the local - * system; is the address of the point-to-point peer. + * adaptive. Alternatively, set to `debug' to print debugging info + * and exit. is address of the interface to be created + * on the local system; is the address of the + * point-to-point peer. They must be actual addresses (not + * hostnames). + * * /,/,... - * List of additional routes to add for this interface. - * May be the empty argument, or `-' if this is problematic. * - * is either - * ,[=]/[,] - * indicating that that gid may allocate addresses in - * the relevant subspace ( is ignored) - * if `=' is specified then it's only allowed for the local - * endpoint address - * or #... - * which is a comment - * or / or ./ or ../ - * which refers to a file which contains lines which - * are each - * 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. 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 item - whether a line file such as + * /etc/userv/ipif-networks, or supplied on the service program + * command line - is one of: + * + * / + * ./ + * ../ + * + * Reads a file which contains lines which are each + * items. + * + * ,[=]/[,] + * + * Indicates that may allocate addresses in the relevant address + * range ( is ignored). 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 diff --git a/ipif/udptunnel b/ipif/udptunnel index 09595d1..963245c 100755 --- a/ipif/udptunnel +++ b/ipif/udptunnel @@ -1,83 +1,115 @@ #!/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[] ... . +# To make a tunnel between two machines `alice' and `bob', +# on `alice', the active endpoint, run: +# +# udptunnel +# [ -l[] ... . # | -e [/...] -# | -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 # ... # ] -# , -# , -# ,,, +# , +# , +# ,,, # ,[,] -# -# [ [ ...] ] +# +# [ [ ...] ] +# +# This will run udptunnel-forwarder on alice, and use +# (usually an ssh invocation) to run udptunnel appropriately on bob. +# Key material will be generated by alice and fed to udptunnel on bob +# via 's stdin, and the physical address and port on bob +# will be (if so configured) returned via '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 +# may be slip or cslip # -# Any <..-addr> may also be hostname +# 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 must be specified. +# (this is not usually useful specified directly; it's +# used by udptunnel when it invokes itself on bob via +# , to have its other self print the +# relevant value. # -# If is specified it should run udptunnel at the -# remote end; it will be invoked as -# [ <-e arguments passed along> ] -# , -# , -# ,,, -# ,[,] -# +# The `remote' physical address and port (ie, on alice, bob's details), +# may also have the special values: +# `Command' wait for to tell us the values (this is +# usually the right choice on alice for at least the +# port). 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 , this command's first -# stdout output should be the real -# , 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 is specified it should run udptunnel at the +# bob end; it will be invoked as +# [ ... ] +# [ <-e arguments passed along> ] +# , +# , +# ,,, +# ,[,] +# +# +# If it was given Print for , udptunnel's first stdout +# output will be the real , 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. # -# is as follows: -# -# actual addr/port that addr/port -# `Command' `Print' -# `Wait' `Any' +# is as follows: +# +# actual addr/port that addr/port +# `Command' `Print' +# `Wait' `Any' # -# is as follows: -# -# (-m not specified) (-m specified) +# is as follows: +# +# (-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 ,,, -# +# In each case udptunnel will run userv ipif locally, as +# userv root ipif ,,, +# # 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) @@ -85,7 +117,10 @@ # -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 is perhaps 10 and perhaps 30. +# where is perhaps 10 and 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 #