Using LetsEncrypt for your IRCd!

Sun 05 June 2016

At the behest of @J0hnnyXm4s and because I just so happened to do this the very morning he asked for someone to write up a howto, here is a high level tutorial on using Let's Encrypt for an IRC server. The IRCD specific steps will be for UnrealIRCd 4, but in all likelihood can easily be applied to your IRCd of choice.


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)

Obtaining Certs

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 protected] and --agree-tos after the plugin part of the command (--webroot or --standalone)

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 and

certbot certonly --webroot -w /srv/www -d -d

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, the following command will run the temporary webserver on port 443 for domain verification:

certbot certonly --standalone --standalone-supported-challenges tls-sni-01 -d

If you'd prefer to use port 80, swap out tls-sni-01 for http-01

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/
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:

./unrealircd reloadtls

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/ /home/ircduser/unrealircd/conf/ssl/server.cert.pem; chown ircduser:ircduser /home/ircduser/unrealircd/conf/ssl/*; su - ircduser -c '/home/ircduser/unrealircd/unrealircd reloadtls'"

The -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 :)