How to link UnrealIRC servers

November 8, 2017

This page explains how to link two (or more) UnrealIRCd servers securely so you have a multi-server network.

IMPORTANT: This page assumes both servers run UnrealIRCd 4.0.16 or newer.

Step 1: open up a dedicated server port

You probably have opened up port 6667 for clients on your server already. You should open up a dedicated servers-only SSL port as well.

This can be as simple as:

listen *:6900 { options { ssl; serversonly; }; };

Or, if you use a shell provider then you may have to specify the IP that got assigned to you:

listen 1.2.3.4:6900 { options { ssl; serversonly; }; };

If you use the example configuration file then you should already have this.

IMPORTANT: If you have a firewall then be sure to open up this port 6900 as well, just like you did with 6667!

Step 2: set up a special server class

If you haven’t done already then set up a class { } block for your servers now, like:

class servers
{
    pingfreq 60;
    connfreq 30;
    maxclients 10;
    sendq 5M;
};

Note that the example configuration file already contains this.

Step 3: grab the SPKI fingerprint of your servers

The SPKI fingerprint is an unique hash of the SSL/TLS key of your server. We need this in step 4, so do this on both servers and write them down.

Run the following command on the shell. In UnrealIRCd 4 you run this from the ~/unrealircd directory (or wherever you installed UnrealIRCd to):

./unrealircd spkifp

This will output something like:

The SPKI fingerprint for certificate /home/irc/unrealircd/conf/ssl/server.cert.pem is:
AHMYBevUxXKU/S3pdBSjXP4zi4VOetYQQVJXoNYiBR0=

You normally add this password on the other side of the link as:
password "AHMYBevUxXKU/S3pdBSjXP4zi4VOetYQQVJXoNYiBR0=" { spkifp; };

If instead you see an error like this:

Usage: unrealircd start|stop|rehash|restart|mkpasswd|version|croncheck|gencloak|reloadtls|upgrade-conf

Then you are not using UnrealIRCd 4.0.16 or newer.

Step 4: setting up link blocks

In the example below we assume you have two servers. One is named alpha.test.net and the other one is called beta.test.net. Simply replace the names with the actual names of your server.

UnrealIRCd 4

In the unrealircd.conf on alpha.test.net you add a link block to link with beta.test.net:

link beta.test.net {
    incoming {
        mask *;
    };
    outgoing {
        bind-ip *; /* or explicitly an IP if you have a shell provider, as mentioned in step 2 */
        hostname beta.test.net; /* or if 'beta.test.net' does not exist then you can use an IP or something like 'beta.dyndns.org' */
        port 6900; /* the special SSL server port we opened up earlier */
        options { ssl; };
    };
    password "AHMYBevUxXKU/S3pdBSjXP4zi4VOetYQQVJXoNYiBR0=" { spkifp; }; /* put the SPKI fingerprint of beta.test.net here (see step 3) */
    hub *;
    class servers;
};

Similarly, on beta.test.net configure the block to link with alpha.test.net:

link alpha.test.net {
    incoming {
        mask *;
    };
    outgoing {
        bind-ip *; /* or explicitly an IP if you have a shell provider, as mentioned in step 2 */
        hostname alpha.test.net; /* or if 'alpha.test.net' does not exist then you can use an IP or something like 'alpha.dyndns.org' */
        port 6900; /* the special SSL server port we opened up earlier */
        options { ssl; autoconnect; };
    };
    password "12355894363289463286489263984632896432643=" { spkifp; }; /* put the SPKI fingerprint of alpha.test.net here (see step 3) */
    hub *;
    class servers;
};

[!] Note that it is a common mistake to put the wrong password (wrong fingerprint) in the link block. If you SSH to alpha.test.net and are editing the unrealircd.conf, more precisely the link beta.test.net { block, then you should put the spkifp password of beta.test.net in there and not the one of alpha.test.net.

Autoconnect

In the example of above we added autoconnect (in link::outgoing::options) in beta.test.net’s config. This means beta will automatically try to link to alpha every class::connfreq seconds (configured in step 3: every 30 seconds). You can also choose to autoconnect the other way around or not to autoconnect at all. While it’s also possible to autoconnect from both sides (especially in UnrealIRCd 4) we generally don’t recommend it.

Step 5: Rehash

Rehash both servers (or restart them if you are lazy and you have no users on them). We recommend to rehash a server as IRCOp by executing ‘/REHASH’ on IRC.

If you restarted or did the ‘/REHASH’ as an IRCOp you should see directly if there are any warnings or errors in your configuration. If so, fix them now.

Step 6: Link!

In step 4 we added ‘autoconnect’. If everything works well then you should see the servers automatically linking (they will try every 30 seconds, based on class::connfreq).

You can see if the other server is linked by executing the IRC command ‘/MAP’ to see the network map.

As an IRCOp you will be informed when servers try to link and if there are any errors.

You can always tell UnrealIRCd to try to link the servers right now by executing (as IRCOp) /CONNECT name.of.other.server. This can be used if you disabled autoconnect, or simply if you don’t want to wait 😉

Step 7: Restricting by IP (optional)

What if someone manages to read all contents of your unrealircd/conf directory? Your configuration file would be exposed, your SSL private key, etc. Or maybe you made a backup (good!) and forgot to restrict access to it (bad!). Such a breach of security would be a real problem. Among other things, it would allow the hacker / stealer to link up a server to your network and acquire all sensitive information and become IRCOp.. etc…

To help prevent against such a malicious linked server UnrealIRCd allows you to add another restriction to link blocks, namely to restrict by IP.

Earlier we configured the link block like this:

link alpha.test.net {
    incoming {
        mask *;
    };

The mask * here specifies that any IP is permitted. You can restrict to mask 1.2.3.4 or a range like mask 1.2.*.

We consider this step optional as it’s basically security-in-depth. If your SSL private key really gets stolen it means an attacker can decode all client and server SSL traffic (but only IF he has access to all such network traffic) so you’re in a very bad situation already.

Step 8: Impose topology restrictions (optional)

In our examples we permit any server to introduce other servers. If this is not what you want, for example if you want to be absolutely sure that a remote link is always ‘alone’ and has no servers behind it (this is called a leaf) then you can impose this restriction.

If you have a small standard network with just two servers plus a services server and trust each other then this isn’t terribly important.

TODO: explain how

Step 9: Advanced toplogy restrictions (optional)

deny link { } allow you to enforce some rather advanced topology restrictions. This is generally only used on medium- and large networks.

Example link blocks

The SPKI fingerprint is an unique hash of the SSL/TLS key of your server. We need this in step 4, so do this on both servers and write them down.

Run the following command on the shell. In UnrealIRCd 4 you run this from the ~/unrealircd directory (or wherever you installed UnrealIRCd to):

./unrealircd spkifp

This will output something like:

The SPKI fingerprint for certificate /home/sisrv/unrealircd/conf/ssl/server.cert.pem is:
AHMYBevUxXKU/S3pdBSjXP4zi4VOetYQQVJXoNYiBR0=

You normally add this password on the other side of the link as:
password "AHMYBevUxXKU/S3pdBSjXP4zi4VOetYQQVJXoNYiBR0=" { spkifp; };

The link block below is the hub linking to your leaf server

link irc.sisrv.net {
incoming {
mask *;
};
outgoing {
bind-ip *;
hostname irc.ip.here;
port 8080;
options { autoconnect; };
};
password "AHMYBevUxXKU/S3pdBSjXP4zi4VOetYQQVJXoNYiBR0=" { spkifp; }; /* put the SPKI fingerprint of irc.sisrv.net here
hub *;
class servers;
};

The link block below is the leaf linking to your hub server

link hub.sisrv.net {
incoming {
mask *;
};
outgoing {
bind-ip *;
hostname hub.ip.here;
port 8080;
options { autoconnect; };
};
password "12355894363289463286489263984632896432643=" { spkifp; }; /* put the SPKI fingerprint of hub.sisrv.net here
hub *;
class servers;
};