--- /dev/null
+NB that this is a very bare set of installation instructions ! It
+describes a `default' configuration; you can do more esoteric things
+if you wish.
+
+
+In any case, on each tunnel endpoint system (not the eventual
+end-system, but the point where the packets are `detunnelled'):
+
+* Install userv, 0.95.0 or later. This should be in Debian.
+* Get userv-utils 0.1.9 from the location above, unpack it, cd to the
+ `ipif' subdirectory, and say `make' then `really make install'.
+
+
+The tunnel is always set up by one of its endpoints, using ssh. 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 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.
+
+
+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.
+
+
+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 an 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 firewall
+rule to let it through).
+
+The port is port 410, so root privilege or authbind is needed.
+authbind is in Debian GNU/Linux.
+
+> -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. 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.)
+
+> 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.
+
+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.
+
+> 172.31.80.6,172.31.80.9,1000,cslip \
+
+172.31.80.6 is davenant's tunnel endpoint address.
+172.31.80.9 is the address of chiark's Relativity tunnel endpoint.
+
+> 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.
+
+> - 172.18.45.0/24 \
+
+`-' 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
+
+This is the ssh invocation to run udptunnel at the far end.
+
+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:
+
+t0:235:respawn:/usr/local/sbin/really -u ian /usr/local/sbin/udptunnel-invoke 2>&1 | logger -p local2.info -t tunnel-chiark
+
+
+Troubleshooting:
+
+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. The relevant Debian bug reports are #45515 and #45944, and Ian
+Jackson can supply the patch to slattach or a working binary.
+
+
+$Id$
* <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 chiark;
- * <peer-addr> is the address of the point-to-point peer.
+ * info. <local-addr> is address of the interface on the local
+ * system; <peer-addr> is the address of the point-to-point peer.
* <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>]
+ * <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>
}
-static void permit(unsigned long pprefix, unsigned long pmask) {
+static void permit(unsigned long pprefix, unsigned long pmask, int localonly) {
int i, any;
assert(!(pprefix & ~pmask));
any= 0;
- if (!proto) fputs("permits",stdout);
+ if (!proto) fputs(localonly ? "permits-l" : "permits",stdout);
if (addrnet_isin(localaddr,~0UL, pprefix,pmask)) {
if (!proto) fputs(" local-addr",stdout);
any= localallow= 1;
}
- if (addrnet_isin(peeraddr,~0UL, pprefix,pmask)) {
- if (!proto) fputs(" peer-addr",stdout);
- any= peerallow= 1;
- }
- for (i=0; i<nexroutes; i++) {
- if (addrnet_isin(exroutes[i].prefix,exroutes[i].mask, pprefix,pmask)) {
- if (!proto) printf(" route#%d",i);
- any= exroutes[i].allow= 1;
+ if (!localonly) {
+ if (addrnet_isin(peeraddr,~0UL, pprefix,pmask)) {
+ if (!proto) fputs(" peer-addr",stdout);
+ any= peerallow= 1;
+ }
+ for (i=0; i<nexroutes; i++) {
+ if (addrnet_isin(exroutes[i].prefix,exroutes[i].mask, pprefix,pmask)) {
+ if (!proto) printf(" route#%d",i);
+ any= exroutes[i].allow= 1;
+ }
}
}
if (!proto) {
static void pconfig(const char *configstr, int truncated) {
unsigned long fgid, tgid, pprefix, pmask;
- int plen;
+ int plen, localonly;
char ptxt[ATXTLEN];
const char *gidlist;
switch (configstr[0]) {
case '*':
if (strcmp(configstr,"*")) badusage("`*' directive must be only thing on line");
- permit(0UL,0UL);
+ permit(0UL,0UL,0);
return;
case '#':
badusage("unknown configuration directive");
fgid= eat_number(&configstr,"gid", 0,gidmaxval, ",",0);
+ if (configstr[0] == '=') {
+ localonly= 1;
+ configstr++;
+ } else {
+ localonly= 0;
+ }
eat_prefixmask(&configstr,"permitted-prefix", ",",0, &pprefix,&pmask,&plen);
if (!configstr && truncated) badusage("gid,prefix/len,... spec too long");
tgid= eat_number(&gidlist,"userv-gid", 0,gidmaxval, " ",0);
if (tgid == fgid) break;
}
- permit(pprefix,pmask);
+ permit(pprefix,pmask,localonly);
return;
}
}