Note that I've given this post a quick update to reflect the changed command syntax for the supported challenges.
This is not intended to be a tutorial for setting up an IRCd with SSL/TLS in general so I'm going to assume a few things here:
You've already got your IRCd up and running with SSL/TLS
You've installed the Let's Encrypt certbot client (Check out the getting started page for more info)
The method you use to actually generate the certificates is going to depend on whether you have a webserver running on the same box as the IRCd or not. If you do not have a webserver running on the box, you need to be able to listen on port 80 or 443 for the domain validation and incoming traffic must be allowed on whichever port you choose.
One note about all the certbot commands that will follow. If it is your first time using Let's Encrypt, you will need to make an account including email and agree to the Let's Encrypt Subscriber Agreement. You can do this automagically from the command line by adding
--email email@example.com and
--agree-tos after the plugin part of the command (
Webserver on the same box
If you have a webserver on the same box as the IRCd, you can use the webroot plugin for the certbot client. As a note, your webserver must be accepting connections on the IRC subdomain if you use one, as certbot will verify each domain independently. The following command will get a certificate valid for example.com and irc.example.com:
certbot certonly --webroot -w /srv/www -d example.com -d irc.example.com
The above command using the webroot plugin will create a temporary acme-challenge file inside
/srv/www/.well-known/ for verification of domain ownership. Assuming Let's Encrypt could access the challenge files properly, you will now have your cert!
No webserver on the box
If there is no webserver on the IRCd box, we will need to use the standalone plugin. Assuming the domain for the IRCd is irc.example.com, the following command will run the temporary webserver on port 443 for domain verification:
certbot certonly --standalone --preferred-challenges tls-sni -d irc.example.com
If you'd prefer to use port 80, swap out
Got certs... now what?
This lovely certificate is now sitting somewhere in
/etc/letsencrypt/live. Inside this directory will be subdirectories for each domain you've requested certificates for through Let's Encrypt. Now, if you're doing things correctly with your IRCd, you will be running it as a separate non-root user. However, permissions on the crucial directories inside
/etc/letsencrypt are root only so I personally have opted to copy the private key and certificate to my IRCd directory as opposed to mucking with permissions and symlinking.
The following is what I wound up doing for UnrealIRCd 4:
cd /etc/letsencrypt/live/irc.example.com cp fullchain.pem /home/ircduser/unrealircd/conf/ssl/server.cert.pem cp privkey.pem /home/ircduser/unrealircd/conf/ssl/server.key.pem chown ircduser:ircduser /home/ircduser/unrealircd/conf/ssl/*
By default UnrealIRCd 4 looks for the certificate at
<install dir>/conf/ssl/server.cert.pem and the private key for the certificate at
<install dir>/conf/ssl/server.key.pem. Now we just need to get the IRCd to reload the certs. Thankfully UnrealIRCd does not require a full restart thanks to the
reloadtls command. As your IRCd user run the following:
Now you have your lovely new Let's Encrypt certificate on your IRC server :)
Automating the Renewal
This part is really quite important. Let's Encrypt certificates are only valid for 90 days, and this is not something we want to have to remember to manually perform. Thankfully, certbot is built with renewal automation in mind. How you automate it is somewhat up to you but I have simply created a cron job that runs the following command every day:
certbot renew -q -n --webroot --post-hook "cp /etc/letsencrypt/live/irc.example.com/fullchain.pem /home/ircduser/unrealircd/conf/ssl/server.cert.pem; chown ircduser:ircduser /home/ircduser/unrealircd/conf/ssl/*; su - ircduser -c '/home/ircduser/unrealircd/unrealircd reloadtls'"
-q flag means certbot will run in quiet mode and only provide output on actual errors and
-n means it won't block if user input is required.
Now you're all set. Holler at me on Twitter, @thracky, if I've mucked anything up or you have any questions :)