             HOW TO DEPLOY A POOR MAN'S IPv6-over-IPv4 VPN


Not too many of the planned features are implemented so far.  The fedaserv
instances can not find each other, can not exchange broadcast announces,
can not act as a rendes-vous assistant for others, there's no database of
known nodes' locations... well, there's almost nothing.  However, primarily
to convince ourselves we can do it, since the version 0.0.30 the running
instances of fedaserv are capable of transferring IPv6 packets to each
other, using IPv4/UDP datagrams as the underlying media.

Well, ... _somehow_.



*********************
* WHAT WORKS, AND HOW

Depending on the point number, fedaserv instances consider themselves
either as serving a single point (all point numbers from 1 to 253), or
as speaking on behalf of the node (the "magic" point number 254, a.k.a.
0xFE).  When a running fedaserv sees an IPv6 packet, the following decision
making process is performed.

  1. All packets with either SRC or DST address outside of the FEDA::0/16
     block are dropped immediately.

  2. The node ID and the point number are extracted from the DST address:
     the node ID is bytes from 2nd to 11th of the address (counting from
     zero), and the point number is the 12th byte.  E.g., for the address

        FEDA:49FE:B618:794A:8E1E:4439:8B00:1EE7

     the node ID is 49feb618794a8e1e4439 and the point number is 0x8B
     (a.k.a. decimal 139).

  3. Existing established cryptographic associations with peers are
     considered for being suitable to be the next hop.  There are three
     possibilities:

        a) if there's a peer with exactly these ID and the number (the
           target point), the packet is sent there;

        b) if there's no such peer, but there's a peer with the same
           node ID and with the peer number 0xFE (that is, the target
           node), the packet is sent there in the hope the node knows
           better where its peers are;

        c) as the very last resort, if our point number is NOT 0xFE, but
           among our active peers there's one with the same node ID as
           we use and with the point number 0xFE (that is, OUR node),
           we sent the packet there hoping the node will serve.

     If neither of those is found, the packet is dropped.


In the present version, all associations between fedaserv instances must be
configured manually, AT LEAST ON ONE OF THE ENDS of the association, and
both ends must know each other's nodes. This may need some further
explanation.

Each instance happily accepts association requests from any other instance
PROVIDED THAT (! this is very important) the accepting instance knows the
public node key of the requesting instance.  It could look more natural to
accept unknown nodes too, provided that they have an appropriate rank, but
this would involve computing yespower hashes each time an unknown node's
point approaches us.  Not every machine is able to do that at all, and even
powerful computers may be easily DoSed if they try doing so.  We're going
to have dedicated servers which check node credentials, collect known nodes
and share this information upon requests, but this infrastructure is yet to
be developed; now that we don't have it, the only option left is to update
every running fedaserv instance's node collection manually.

Having said all this, let's admit in the present version we can only run
nodes on public (permanent) addresses, as the address (the ip:port pair) is
to be set manually for each party who wants to communicate -- both for our
own peers and for other nodes.  Even worse, each point can only communicate
its own node, other points of the same node and points of other nodes, but
only provided that their nodes have established direct cryptographic
association with our node.  Let's admit this is not very useful.  Yet it is
far better than nothing.



***************
* PREREQUISITES

In order to run a node, you (as of now) need two things: a suitable node
master key (rank 20 or higher is strongly recommended), and a permanent
pair of IP address + UDP port on a Linux machine (well... BSD systems will
likely serve as well, but I never tested this).

To run a point, you need a point key provided by the node master.  Well,
yes, you need to have a node master among your friends and relatives.
Besides that, you need a computer running Linux (or may be BSD... no
promises here, sorry).  And one more little thing: actualy you need root
access to the machine if you want FEDAnet IPv6 packets to be originated
from it and targeted to it: without root access, you can't set up the
appropriate virtual network interface and routes.

If the machine where you're going to run a node is yours in the sense you
have root access to it, you can run some servers on your node's addresses,
that is, addresses of the form FEDA:(node-id):PPxx:xxxx, where PP is one of
00, FE and FF, and xx:xxxx are any hexadecimal digits; in particular, the
address FEDA:(node-id):FEDA:FEDA is strongly recommended.  However, this is
not necessary; if you only have non-privileged access to the server, your
node will still be able to forward packets back and forth, between your
points and from/to other nodes; only you'll be unable to use the "node"
address space, only addresses of the points other than 00, FE and FF.



****************
* PREPARING KEYS

So you have a node master key of a desired rank (again, 20 is the
recommended minimum).  In this example we'll assume your node ID is
49feb618794a8e1e4439; this means the file created by the feda-ng program is
named the same.

The first step is to prepare the node master workplace.  If you absolutely
can't have a dedicated machine for that, which never ever connects to
networks, at least do it on a removable media, or, as the VERY minimum,
have a dedicated directory for this job, and once you're done, copy it to
some removable media and delete from your working machine.  We'll assume
the directory for this purpose is named MASTERDIR.  The first step is to
deploy the node master workplace using the master key file:

    fedakeys -c MASTERDIR mdeploy 49feb618794a8e1e4439

If you have to do this on a low-end machine, and you're confident that the
file 49feb618794a8e1e4439 is not corrupt anyhow, you might want to add the
-p flag to avoid recomputing the hash, which is resource-demanding:

    fedakeys -p -c MASTERDIR mdeploy 49feb618794a8e1e4439

You might want to specify the minumum rank at which your node is going to
recognize other nodes.  By default, it is set to the same value as your
node's own rank.  It is impractical to recognize nodes with ranks lower
than 16, so if your own master key has this rank, leave the things as they
are; if, however, you use a node key with a rank higher than that, you
might want to allow other people to use lower ranked node keys for the
period FEDAnet is not used for any real work.  Use a command like this:

    fedakeys -p -c MASTERDIR mdeploy 49feb618794a8e1e4439 20

After that you'll have two files inside MASTERDIR, named feda.conf and
master.key.  The feda.conf file contains nothing secret, so don't worry too
much about it; but the file master.key is THE place where your node's
secret key is stored (and the other such place is the original file,
49feb618794a8e1e4439 in our example).  Keep these files away from
networking as carefully as you can.  As of now, just create the key for
your ZeroPoint, and you can move the master secret key somewhere else and
wipe it off your workstation, which is presumably connected to the
Internet.  Do this:

    fedakeys -p -c MASTERDIR mzero

From now on, you don't need the MASTERDIR any longer, until you decide
to replace your ZeroPoint key.  Once again: move your master credentials
as far away from any computer networks as you can.  Be sure to keep several
copies in different places so that you don't loose your node.

In the current directory you now have a file named

    49feb618794a8e1e4439_p0.key

-- which contains all information needed to deploy your ZeroPoint,
including the secret key for it.  If you work on a machine dedicated as the
node master workplace, take this file to a removable media and transfer to
the machine where you plan to deploy your zero point; if you don't have a
dedicated machine, you can continue right here (but you DID remove the
master credentials, didn't you?).  There's not much sense in placing the
deployed ZeroPoint anywhere else than the default $HOME/.fedanet/keys, so
from now on we won't specify the directory (but, well, YOU can continue
doing it).  So, deploy your ZeroPoint:

    fedakeys -p deploy 49feb618794a8e1e4439_p0.key

While at it, create and add right here your point number 1, which is for
you as the node master, personally -- unlike the ZeroPoint, which
represents your node, not you as a person.  Make a key for it and deploy
the key right at the same place, and then remove the file:

    fedakeys -p zcrpoint 1
    fedakeys -p deploy 49feb618794a8e1e4439_p1.key
    rm 49feb618794a8e1e4439_p1.key


What you need in order to continue with deploying your node, is, first, a
key for the fedaserv instance which will run on behalf of the node (that
point 254 a.k.a. 0xFE); and, second, perhaps a public node credentials'
file, which you'll share with other nodemasters whenever you decide to peer
with them.  The command

    fedakeys -p zcrpoint 254

will do the first thing (creating a file named 49feb618794a8e1e4439_p254.key),
and the command

    fedakeys -p nodecert

will create a file named 49feb618794a8e1e4439.pub, containing the public
information of your node.  The nodecert command can be run in any location
where a point of your node (ANY point of YOUR node) is deployed, as the
necessary information is always available along with any point's keys.



*****************************
* FEDASERV CONFIGURATION FILE

By default, fedaserv tries to load its configuration from the file named
$HOME/.fedanet/serv.conf -- but, as usual, you can supply any other path
using the -c option.

There's a sample configuration file doc/serv.conf, which is
self-documented.  It is safe to leave everything at default values; you
need to configure your peers (usually the node at points' configuration,
other nodes at the node's configuration), enable the packet forwarding,
and (optionally) specify the tun interface.

Peers are configured like this:

peer venus
type persist
ip 198.51.100.12
port 65242

The peer name, which is set at the 'peer' line, must be distinct, but is
not used by the server in any other way.  The port 65242 is the default one
for public servers of FEDAnet (well, decimal 65242 is the same as
hexadecimal 0xFEDA), but you can use any other port as well.  As of the
type, it is a space-separated list of tokens, and as of present, the
software recognizes 'default', 'mynode', 'natcheck' and 'persist'; of
these, 'mynode', 'natcheck' and 'persist' cause the running server to try
connecting the configured peer.  You can replace the 'persist' token with
'mynode' if the peer is the node (a.k.a. point 254) for your point, or with
'natcheck' if you're going to use both running instances as parts of a
server system for NAT type checking (see the file NC_SERVERS for more info
on this), and you can even use them both if appropriate; in most cases,
however, the 'persist' token is exactly what you need.  So, to configure a
peer, just copy this example to your configuration file, replace the IP
address with the address of your peer, then pick a random distinct name and
replace 'venus' with that name; optionally also change the port number.

It may be a good idea to specify explicitly where the server should look
for cryptographic keys, like this:

keys_dir    /home/lizzie/.fedanet/keys 

Enable the packet exchange as such, adding a line like this:

forwarding yes

In case you have the appropriately configured tun interface (e.g. feda0,
see the next section), add the following line as well:

tun_iface feda0

-- this will let the fedaserv instance to deliver locally the packets
destined to it (DST addresses FEDA:(node-id):PPxx:xxxx for all points
except the FE, DST addresses FEDA:(node-id):NNxx:xxxx where NN is 00, FE or
FF, for the node which is effectively a fedaserv running with 254 as the
point number).



****************************
* SETTING UP A TUN INTERFACE

You need to be root to do this.  DON'T RUN fedaserv AS ROOT!!!  The feda-if
command is primitive so we can hope it won't compromise your machine's
security, and the other two commands are shipped with your system.  Even if
you don't have root access to the machine (which is highly likely if you
decide to run your node on someone else's server machine), you may try
asking your good host to execute the commands for you.  This is not
desirable however if the machine runs other instances of FEDA as well,
because there can only be one route for the FEDA::0/16 block.

The four things you need to do are, first, to create the interface (we
prefer the name feda0, but you can use whatever you like), making it
persistent until the machine is rebooted, and granting access to it to the
user who runs the fedaserv instance; second, to bring the interface up;
third, to add an appropriate IPv6 address to the interface; and the last,
to add the FEDA::0/16 route.  For the first task, the command feda-if is
used.  We assume you copied it to your /usr/local/sbin directory, and
you've created a dummy user named fedanet (and a user group of the same
name) to run the fedaserv instance.  Suppose, besides that, that uid/gid
for the dummy user are 2575/2575.  Then, the command

   /usr/local/sbin/feda-if -p -u 2575 -g 2575 feda0

will do the thing.  Now, pick the IPv6 address you'll use as the ``main''
address for this particular instance.  For a node, address
FEDA:(node-id):FEDA:FEDA is recommended; for a point, e.g., 2C (a.k.a. 44
in decimal), use smth. like FEDA:(node-id):2C00:FEDA.  The following
commands will do the rest of what you need (assuming, just like before,
that your node is 49feb618794a8e1e4439): 

    /sbin/ifconfig feda0 up
    /sbin/ifconfig feda0 add feda:49fe:b618:794a:8e1e:4439:2c00:feda/16
    /sbin/route -6 add feda::0/16 dev feda0

It might be not a bad idea to add these four commands somewhere so that
they are executed on each reboot, e.g., to your /etc/rc.local (if you have
it; refer to the documentation on your OS or the distro).        



********************
* LAUNCHING FEDASERV

During the period of debugging, it is recommended to run servers in
foreground, directing all logging to their stderr streams, and making the
diagnostics reasonably verbose.  All this is achieved with a command
line like

    /path/to/fedaserv -v -E -f -c /path/to/your/config/file

You can add another -v or even two of them, but don't leave fedaserv
running with that level of logging verbosity if you're going to do
something "real" through your tunnels.  With more than one "-v", it will
produce a lot of messages on every handled IPv6 packet, and, well, it's a
lot of junk in your logs.

It is better to launch this command inside a virtual terminal created by
the well-known ``screen'' program, so that if you loose your connection to
the server machine, your fedaserv will not get killed by SIGHUP.  The
screen program is available out of package repositories on all Linux
distros I have ever seen.

Once you're confident everything works as desired, you might want to put
the configuration file to its default location ($HOME/.fedanet/serv.conf)
and let your system launch your fedaserv without any extra parameters at
the command line.  Make sure you DON'T RUN THE SERVER AS ROOT!!!



**************************
* PEERING WITH OTHER NODES

First, publish somewhere your nodecert file (that 49feb618794a8e1e4439.pub
thing, where 49feb618794a8e1e4439 is your node ID) together with
the address:port of your running node.  Or, just exchange this information
with someone else who runs a node.

Once you've got someone else's node's information, first check the file for
correctness.  This must be done on a reasonably powerful machine, as it
requires taking the yespower hash.  The command is like this:

   fedakeys nverify f22ff5448c951bb33897.pub

Once the check is passed, you now sure the file is correct.
Copy the file to the location where your node runs, and do the following:

   fedakeys -p nodeimport f22ff5448c951bb33897.pub

After that, add the remote node as a peer to your node's serv.conf and
restart your fedaserv instance.

Once all this is done, all your points should "see" (e.g. should be able to
ping) IPv6 addresses belonging to the remote node's point, and vice versa.




********************************
* CONTROLLING THE RUNNING SERVER

Being signaled with SIGUSR1, the server writes to the logs its list of
active peers.

Since 0.0.35, there's also the local socket which allows to control the
server with the ``fedactl'' program.  Make sure you enabled the socket in
your configuration file with

control_socket		yes

The fedactl program in the present version accepts exactly one optional
parameter, which is the path to the socket.  If you didn't set the path
explicitly, then the socket is created as ~/.fedanet/servctl where the
fedactl program will find it by default.

To have logging messages delivered to you trough the fedactl program, use
commands like ``log info'' or ``log debug''.  Type ``help'' to know what
else you can do.

