Tutorial: Linking servers

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

NOTE: If you are linking two UnrealIRCd 6 servers and they are both on *NIX (not Windows), then you can follow the much easier guide at Linking servers (genlinkblock).

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 20M; };

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.

*NIX
On *NIX, run the following command on the shell. 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; };

You will need this information for step 4.

UnrealIRCd 6
Are you running Windows with UnrealIRCd 6.0.2 or later? Then you can use the unrealircdctl CLI tool. Open a cmd.exe window and then run: cd C:\Program Files\UnrealIRCd 6\bin unrealircdctl spkifp

It will show you a string like  that you will need in step 4.

UnrealIRCd 5
If you are using UnrealIRCd 5 on Windows then open a cmd.exe window and then run: cd C:\Program Files\UnrealIRCd 5\bin openssl x509 -noout -in ..\conf\tls\server.cert.pem -pubkey|openssl asn1parse -noout -inform pem -out public.key openssl dgst -sha256 -binary public.key | openssl enc -base64 (don't worry about any WARNINGs you may see)

This will output something like: WARNING: can't open config file: C:/Windows/libressl/ssl/openssl.cnf WARNING: can't open config file: C:/Windows/libressl/ssl/openssl.cnf AHMYBevUxXKU/S3pdBSjXP4zi4VOetYQQVJXoNYiBR0=

That last line,  in this example, is the spkifp (spki fingerprint) you will need in step 4.

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.

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 1 */ 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 1 */ 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 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. '''Do you see any errors? Check out Troubleshooting: linking servers'''

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 ;)

Now that you have a multi-server network, you may want to read about Distributing user load and doing server maintenance in a multi-server network. But before you do, perhaps first secure/tighten your link block a bit more. See Step 7: Restricting by IP (optional) below.

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...

It's possible to enhance security by restricting from which IP the server may link in.

Earlier we configured the link block like this: link alpha.test.net { incoming { mask *; };

The  here specifies that any IP is permitted. You can change this to an IP like  or an IP range like

We consider this step optional as it's basically security-in-depth.

Simple restrictions
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 important. In fact, most people don't bother to do this.

TODO: explain how

Advanced restrictions
The deny link { } allows you to enforce some rather advanced topology restrictions. This is generally only used on large networks. 99% of the admins don't use this.