Using Let's Encrypt with UnrealIRCd

Introduction
Let's Encrypt is an initiative which allows you to get a 'real' certificate for your server. That is, a certificate from a real and trusted Certificate Authority. In the past you had to buy one but now you can use Let's Encrypt.

This is different than the default certificate that is created upon UnrealIRCd installation. Such certificates are "self signed" and not from a trusted Certificate Authority. Anyone can create and impersonate you with such a certificate so it's not as secure as a real one.

Before you begin
Let's Encrypt requires you to setup a number of things and will issue you 90-day certificates. You have to automate the renewal process by installating a number of scripts. This is all explained in this tutorial

Requirements
This tutorial is written for *NIX. Perhaps one day someone could expand it for Windows (if possible).

Using Let's Encrypt (effectively) requires root access to the machine. We will assume you are running UnrealIRCd on a VPS and you have root access. Be sure to do the things in this tutorial as root (use sudo -i to become root if not already so).

Installing certbot
First, you need to install the 'certbot' tool. Follow the Install instructions on EFF's certbot page. A typical choice for a Linux user would be to choose I'm using None of the above on Ubuntu/Debian/..

IMPORTANT: Follow the Install instructions only, then get back here!

Open up port 80 (firewall!)
In this tutorial we will use port 80 for let's encrypt verification mechanism. Make sure incoming port 80 is not firewalled. If you use the ufw firewall you may want to run something like ufw allow 80/tcp. If you are using Amazon EC2 then don't forget to also allow port 80 in your Security Group.

Getting your first certificate (TEST)
Run the following as root. Replace irc1.example.net with your server name: certbot certonly --test-cert --standalone --preferred-challenges http-01 -d irc1.example.net

You will be asked a few questions: Saving debug log to /var/log/letsencrypt/letsencrypt.log Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): Enter your email address here Starting new HTTPS connection (1): acme-staging.api.letsencrypt.org
 * 1) certbot certonly --test-cert --standalone --preferred-challenges http-01 -d irc1.example.net

--- Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf. You must agree in order to register with the ACME server at https://acme-staging.api.letsencrypt.org/directory --- (A)gree/(C)ancel: A

--- Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about EFF and our work to encrypt the web, protect its users and defend digital rights. --- (Y)es/(N)o: N Obtaining a new certificate Performing the following challenges: http-01 challenge for irc1.example.net Waiting for verification... Cleaning up challenges

IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/irc1.example.net/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/irc1.example.net/privkey.pem Your cert will expire on 2017-12-01. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew"

If you don't see the congratulations and instead see an error then you will have to resolve this first. Possible errors could be: a webserver running on port 80 or a firewall. The Let's Encrypt user community may be helpful.

If you have any errors, resolve them first, before proceeding!

Getting your first certificate (FOR REAL)
This assumes previous step was successful. It's now time to get the real certificate.

Get the real certificate
You will run (almost) the same command as in your test run earlier. The only thing you remove is the --test-cert parameter.

Command for single server network or network without robin DNS. Replace irc2.example.net with your server name: certbot certonly --standalone --preferred-challenges http-01 -d irc2.example.net You may have to answer a couple of questions again. Should you get a question about 'expanding or replacing' the certificate, answer E (for Expand).

Note on Round Robin DNS
Do you have a multi-server network with round-robin DNS enabled? That is, you have multiple servers (eg:  irc1 .example.net,  irc2 .example.net) and they are both also reachable by the name  irc .example.net.

In that case you will want your certificate to be valid for both names. Run the following as root. Replace irc2.example.net with your servername and irc.example.net with your "round robin DNS name": certbot certonly --standalone --preferred-challenges http-01 -d irc2.example.net -d irc.example.net As you can see you are requesting two names in the certificate here, irc2.example.net and irc.example.net.

IMPORTANT: Unfortunately Let's Encrypt is a real pain with Round Robin DNS. You will likely hit an error and have to re-try the command a number of times in order to get the certificate. This is because Let's Encrypt does not (necessarily) connect back to your host. It may connect to any other host in the round robin DNS. If you have only 2 servers then it may be doable in a couple of attempts, after all your chance is 1 out of 2 each attempt. If you have more then this may be troublesome. Let's Encrypt only permits 5 failed attempts per hour per account/host so you will quickly reach this limit (if you do, wait an hour). The solution to this problem is quite complex and involves setting up http servers/proxies on all your IRC servers (TODO: link).

Alternative: you could also consider buying a certificate for irc.example.net instead. Simple domain-only validation certificates are relatively cheap these days ($10 per year for a Comodo certificate via 3rd parties). Together with an Sni block this will be easy to setup. Basically you will use the paid irc.example.net SSL certificate in your Sni block and use the free Let's Encrypt certificate to serve the irc2.example.net one (using this tutorial as if it were a single server).

Alternative 2: if you are really lazy you could buy a wildcard domain certificate for *.example.net. These cost about $100 per year and you simply install them on as many servers as you want.

Install the certificate
Assuming previous step was successful a message was printed like: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/irc2.example.net/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/irc2.example.net/privkey.pem

Remember these paths.

Now I'm going to assume the path to your UnrealIRCd installation is /home/ircd/unrealircd and the account is called ircd. If this is not the case then change the path- and usernames in the commands below to suit your setup !

First of all, let's backup your existing SSL certificate, just to be sure.

cp /home/ircd/unrealircd/conf/ssl/server.cert.pem /home/ircd/unrealircd/conf/ssl/server.cert.pem.old cp /home/ircd/unrealircd/conf/ssl/server.key.pem /home/ircd/unrealircd/conf/ssl/server.key.pem.old

Now, let's copy the new certificate. Again, change the paths if needed: cp /etc/letsencrypt/live/irc2.example.net/fullchain.pem /home/ircd/unrealircd/conf/ssl/server.cert.pem cp /etc/letsencrypt/live/irc2.example.net/privkey.pem /home/ircd/unrealircd/conf/ssl/server.key.pem

We also need to change ownership of the files so the ircd account can read it (change ircd to your account name if it's named differently): chown ircd /home/ircd/unrealircd/conf/ssl/server.*.pem

If all of the above went well, make UnrealIRCd re-read the certificate. You should do this via /REHASH -ssl on IRC: /REHASH -ssl 18:55 [ExampleNET] !irc2.example.net *** [SSL rehash] Oper (~oper@test.net) requested a reload of all SSL related data (/rehash -ssl) You should not see any warnings or errors.

Now it's time to test your certificate! (re)connect to your server using SSL/TLS and make sure the certificate looks good (TODO: some site?)

IMPORTANT: You are NOT done yet! Certificates are only valid for 90 days so you need to setup certificate renewal

Certificate renewal
TODO: use cron script. Put it somewhere.