             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, and since 0.0.50
there's no need to exchange nodes' public keys manually.

Well, something even works, err... _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.  All those "autoconfiguration" and/or
     "broadcast" packets designed for IPv6 thus won't work with FEDAnet.
     And, honestly, this is not planned because we don't know why all
     the crap of this kind exists at all.

  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. The packet is considered to be delivered locally, if our node is the
     packet's destination node AND one of the following conditions is met:

        a) we run as a non-node point (that is, any point in the range
           [1..253], inclusively) and the point from the DST address is
           the same;

        b) the daemon has the configuration option ``nodenets'' set to
           ``some'', and the point number from the DST address is 0x00 or
           0xFF, *OR* the ``nodenets'' is set to ``all'' and and the DST
           point number is 0x00, 0xFE or 0xFF (decimal 0, 254 or 255);

        c) we run as a node (peer number 0xFE a.k.a. decimal 254), the
           DST point is the same AND the tunnel interface is configured;

        d) we run as a node (peer number 0xFE a.k.a. decimal 254), the DST
           point is 0x00 or 0xFF (0 or 255) and we don't have an active
           peer of the ``nodenets'' type (see peer_types.txt for details).

     For each packet to be locally delivered, if the tunnel interface is
     configured in the daemon's serv.conf file, the packet is passed there,
     otherwise it is silently dropped.

  4. Existing established cryptographic associations with peers are
     considered for being suitable to be the next hop.  There are the
     following 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) if we have an active peer of the ``nodenets'' type and the
           packet's destination is either 0x00 or 0xFF point of our node,
           the packet is sent there regardless of our own point;

        d) if we have an active peer of the ``nodenets'' type, the
           packet's destination is the 0xFE point of our node (that is,
           the node itself), we run as the node (!), that is, with the
           0xFE a.k.a. 254 peer number, so the packet is actually
           addressed to us directly, *BUT* we don't have the tunnel
           interface, the packet is sent to the ``nodenets'' peer;
 
        e) 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 packet is neither to be delivered locally, nor there's a next hop for
it, the packet is dropped.


A running instance of fedaserv (presumably, one running on a machine with
a permanent routable IP address) may act as a proxy (FEDAproxy) for other
instances.  This must be configured explicitly on both instances -- on the
one working as a proxy server and on the one acting as the client (proxy
user).  The fedaserv instance providing proxying for others opens and binds
additional UDP ports right on the start, one such port for each proxy user.
The port numbers are set explicitly in the configuration file.  Until the
desired peer establishes its cryptographic association with the proxying
instance, all dgrams sent to the respective port are silently dropped; once
the association is established, all incoming dgrams are sent to the peer;
the peer sends all its dgrams to the proxy and the proxy forwards them to
the outer world.  For all other parties this technically looks exactly if
the proxy user was running right on the proxying machine, using the port on
its own.  See the file fedaproxy.txt for details.

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 OR have capabilities to know them.
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 in response to
requests from the wild space of the Internet.  That's why FEDAnet software
implements the possibility to use dedicated machines for all tasks that
involve hash computations; we'll discuss this in the section headed
"MACHINES THAT TAKE HASHES".

Alas, 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 points 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.  It is planned to make
the FEDAnet software work on BSD systems as well, but as of now, it
doesn't.

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.  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,  As of the "node" address space, you can
let any of the points serve them.  For example, you can run a fedaserv
instance on yor home machine, and tell both this instance and your node
instance that packets addressed to FEDA:(node-id):PPxx:xxxx where PP is 00,
FE and FF are to be sent to that home instance and treated there as
delivered to their final destination.



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

So you have a node master key of a desired rank (once 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 the following types: 'default', 'mynode', 'natcheck',
'persist', 'nodenets', 'trustncc', 'certhub', 'introducer', 'proxy',
'proxyuser' and 'direct'.  Some of the flags, namely 'mynode', 'natcheck',
'persist' and 'proxy' cause the running fedaserv 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.txt 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 (although is not necessary in most cases) 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, that is, 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, or a fedaserv that has the parameter ``nodenets'' set
as desired in its configutation file.



****************************
* 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!!!



***************************
* MACHINES THAT TAKE HASHES

A node master may run the node on a low-end VPS, where it is impossible (or
at least dangerous) to compute the hashes, but there's a permanent
globally-routable IP address, which is, as of now, necessary to run a node,
and even when the FEDAnet software gets all planned features, running a
node on a machine with a routable IP address will remain the most
convenient option.  Likely the same node master has a more powerful
computer at home, for which it's not a problem to compute hashes, and even
if the machine gets DoSed, it won't cause serious problems; but there (at
home) there's typically no routable IP address, it is too usual for a home
network to live behind a NAT, or two of them, or three, and one of them may
even be that terrible "symmetric" one.  But this isn't any problematic
here!  It is always possible to run a fedaserv instance as a point of the
same node (e.g., point number 177... why 177? why no :-), allow it in its
configuration file to take hashes and also let it act as the local
introducer; the following two lines are to be placed in the serv.conf:

   allow_nodehash yes
   intro_issue yes

A fedaserv instance configured like this will happily serve two types of
requests coming from any point OF THE SAME NODE: "please check this set of
an (unknown) node credentials" and "please go to this addr/port, which is a
"cert hub", and introduce our node there".  The instance running on behalf
of the node (point 254) must be told explicitly it can use the "introducer"
point (be it 177 or any other) for these purposes.  This is done with the
appropriate peer section in the configuration file; e.g. if our node ID is
49feb618794a8e1e4439, then the following four lines will do the thing:

   peer my_belowed_177
   type introducer trustncc
   node_id 49feb618794a8e1e4439
   point 177

We might also want other points of our node use this machine's service,
and/or let the machine accept node introductions from other nodes.  To
achieve any of the two things, we need the point 177 instance to be
accessible from the Internet, and the simplest and most straightforward way
to achieve this is to use the node instance as a proxy for the point 177.
FEDAproxy function is explained in detail in the file fedaproxy.txt, but in
short, the peer entry now should look like this:

   peer my_belowed_177
   type proxyuser introducer trustncc
   node_id 49feb618794a8e1e4439
   point 177
   proxyport 45678

where 45678 is the UDP port number on which our point 177 will become
visible for the outer Internet.  In the point's serv.conf, the entry for
the node fedaserv instance should look like this (be sure to replace the IP
address with your node's one):

   peer the_node
   type mynode proxy
   ip 198.51.100.173
   port 65242

Other points of our node should then specify in their serv.conf:

   peer the_node
   type mynode
   ip 198.51.100.173
   port 65242

   peer our_belowed_177
   type persist introducer trustncc
   ip 198.51.100.173
   port 45678
   node_id 49feb618794a8e1e4439
   point 177

We're ALMOST ready to let the machine running the point 177 also accept
introductions from other nodes, so that all our points will see those
nodes' creds when they ask the point 177 as a trustncc peer if it knows
this or that node.  To let this happen, we need yet another line in the
point 177's serv.conf:

   intro_accept yes

For this to work, we need a challenge-response table generated with the
feda-ng program (it is typically done at the same time when the node secret
key is generated), prepared with the feda-ct program; see its help output
and the file node_gen.txt for details.  Be sure to check the file with 

   feda-ct scan my_table_file
   feda-ct poscheck my_table_file

(it must be fully filled and fully correct; if it still has unfilled
records, use ``feda-ct cannibal'' and ``feda-ct fill'' commands).
Then place the file in your .fedanet directory and rename it to ``crtbl'',
that is, its full path must be "$HOME/.fedanet/crtbl".

Now the thing which is perhaps the most hard to understand here.  In the
serv.conf file OF THE NODE INSTANCE (!) we need YET ANOTHER peer section,
which specifies the same old good point 177 as the possible location of a
certhub.  This should look like this:

   peer our_certhub
   type certhub
   ip 198.51.100.173
   port 45678

The node instance will never try connecting such a peer (unless, of course,
we add more flags to the type).  Instead, in case someone tries to
associate with the instance, but the instance doesn't know its node, it
sends such a client a hint where to introduce its node; IP addresses and
ports of all peers marked as the 'certhub' type are included into such a
hint.



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

First, publish somewhere the address:port of your running node.  Or, just
exchange this information with someone else who runs a node.  Add the
remote node as a peer to your node's serv.conf and restart your fedaserv
instance.

If both nodes have properly configured introducer/certhub machines as
explained in the previous section, they SHOULD exchange all the necessary
information automatically and establish a cryptographic association.
However, the implementation is, as of present, buggy enough to not let this
happen.

If you know the other node's certhub address (IP+port), you can use any of
your point fedaserv instances to introduce your node to that certhub,
provided that the point runs on a machine capable of computing hashes.
First make sure your serv.conf contains the lines

   allow_nodehash yes
   intro_issue yes

-- otherwise it won't perform the introduction.  Then, launch the
``fedactl'' program and issue the command like

   intro 198.51.100.173 45678

(replace the IP address and the port number with those of the certhub
you'd like to introduce to).  If you successfully introduce your node to
the other node's certhub and vice versa, the nodes should successfully
bring up the cryptograpic association.  Actually, the state we're trying to
achieve here is each of the connecting nodes either has the other node's
public keys in its local database ($HOME/.fedanet/keys/ directory), OR has
an active peer of the ``trustncc'' type which knows the keys.

Certainly it is always possible to exchange the node public keys
"manually", sending each other the appropriate files.  To create a file of
this kind, use

   fedakeys nodecert

at an account where any point of your node is deployed.  It will create a
file named like 49feb618794a8e1e4439.pub; send the file to the node master
of the other node.  It is safe to publish this file online, openly.

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
(the ``-p'' option suppresses the hash test and hence avoids its
computation):

   fedakeys -p nodeimport f22ff5448c951bb33897.pub


Once everything is done right, 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.

