Elvin routers can be federated together to form wide-area event notification networks. A federated network of Elvin routers appears to provide a single space of events to clients.

Federation Classes

To federate two routers you first need to decide which events to exchange. For trusted routers this may be simply be all events, however you will usually want to be more specific as to what you want to accept and provide.

In Avis, a federation class is used to specify events to import and export using subscription expressions. For example, you might define a Public federation class that allows tickertape and presence events in and out using:

Federation.Subscribe[Public] = \
  Presence-Protocol == 1000 || string (Message)

Federation.Provide[Public] = \
   Distribution == "world" && \
   (Presence-Protocol == 1000 || string (Message))

This example class allows any tickertape or presence event into the router, but only events with a Distribution field with the value "world" to be federated outwards.

Connecting Routers

To connect two routers you need to decide which one initiates the connection and which listens for connections. The router that initiates the connection needs a line like:

Federation.Connect[Public] = ewaf://public.elvin.org

This specifies that the router should connect to public.elvin.org using the Public federation class.

Incoming Connections

To have a router listen to for incoming federation connections you might have an entry like:

Federation.Listen = ewaf://

This listens for incoming federation connections on port 2916 on all network interfaces.

The host that listens for incoming connections also needs a mapping from a remote host to a federation class to use for the connection. For example, to specify that connections from the host public.elvin.org should use the Public federation class, and that any hosts you manage called in the somewhere.org domain use the Internal class:

Federation.Apply-Class[Public] = public.elvin.org
Federation.Apply-Class[Internal] = *.somewhere.org

You can also define a default mapping for hosts that do not match any of the Apply-Class mappings:

Federation.Default-Class = Public

As a security measure, if there is no mapping for a host either via Apply-Class or Default-Class, then it will be refused federation access.

See the comments in etc/avisd.conf file for more information on setting up federation.

Using TLS Authentication

To use TLS authentication to restrict federation to routers that you have established a pre-existing trust relationship with, you first need to either exchange certificates to establish trust, or use certificates signed by the root Certification Authorities (CA's) trusted by both routers.

Once a trust relationship is established, you can set up secure federation endpoints in avisd.config. For example, the settings below create a federation link to a trusted host named hex.somewhere.org.

Federation.Listen = ewaf:/secure/

# Require that hex.somewhere.org be TLS-authenticated
Federation.Require-Authenticated = hex.somewhere.org

Federation.Apply-Class[Trusted] = hex.somewhere.org

Federation.Subscribe[Trusted] = \
  Presence-Protocol == 1000 || string (Message)

Federation.Provide[Trusted] = TRUE

This creates a secure listening endpoint on port 29160, and ensures that any host connecting to it that claims to be hex.somewhere.org is authenticated against its public key certificate in our keychain (or the root CA's chain of trust): this means that address-spoofing or other nefarious techniques cannot be used to access the trusted federation link.1

  1. If you're thinking this sort of security thing would be better handled at a lower level than Avis, you're probably right. If you're using IPv6 you could choose to deal with security at the transport layer. With IPv4 you're stuck with either TLS at the application layer, or using a proxy/firewall arrangement in front of the router.