Providing TLS for Ngircd

Before You Begin

To enable TLS for ngircd, you must first have a properly-signed SSL cert.

Check to make sure you have the following two files:

/etc/ssl/example.com.crt
/etc/ssl/private/example.com.key

NOTE: In all examples in this guide, make sure to replace example.com with your actual hostname.

If the SSL certs do not exist, you can use acme-client to request the certs.

Copying the cert and key

Copy the cert and key into /etc/ngircd/:

$ doas cp /etc/ssl/example.com.crt /etc/ssl/private/example.com.key /etc/ngircd/
$ doas chown _ngircd:_ngircd /etc/ngircd/example.com.{crt,key}

In /etc/ngircd/ngircd.conf, you will need the following lines in the [SSL] block:

        # SSL Server Key Certificate
        CertFile = /etc/ngircd/example.com.crt
...
        # SSL Server Key
        KeyFile = /etc/ngircd/example.com.key
...
        # Additional Listen Ports that expect SSL/TLS encrypted connections
        Ports = 6697, 9999, 16697

NOTE: If the [SSL] block is commented out, it needs to be uncommented.

Optional: If you want to have a DHFile:

$ openssl dhparam -out ~/dhparams.pem 2048
$ doas cp ~/dhparams.pem /etc/ngircd/
$ doas chown _ngircd:_ngircd /etc/ngircd/dhparams.pem

Then, uncomment this line in /etc/ngircd/ngircd.conf:

DHFile = /etc/ngircd/dhparams.pem

Reloading Certs

In ngircd, it is not necessary to restart the IRCd (which would result in downtime) in order to reload certs. Simply send the daemon a HUP signal:

$ doas pkill -HUP ngircd

That will cause ngircd to reread its conf file and reload its TLS certs.

Automation

Let's Encrypt TLS certs expire after 90 days. As a result, you are highly encouraged to automate the renewal of TLS certs. Otherwise, once a cert expires, your users may no longer be able to visit your site.

We can automate the request process using crontab.

$ doas crontab -e

Add this line at the bottom:

~       ~       *       *       *       acme-client irc.example.com >> /var/log/acme-client.log 2>&1 && sleep 300 && cp /etc/ssl/irc.example.com.crt /etc/ssl/private/irc.example.com.key /etc/ngircd/ && chown _ngircd:_ngircd /etc/ngircd/irc.example.com.{crt,key} && pkill -HUP ngircd

NOTE: Replace irc.example.com with your actual IRC server name.

This cronjob will check the certificate once each day at a random time to see if it needs to be renewed. If it does, it will renew the cert, wait 300 seconds, then reload openhttpd to use it.

Troubleshooting

If you were unable to establish the connection above, it may be because your firewall is blocking the necessary ports.

You can ensure pf allows incoming IRC connections by putting this line into /etc/pf.conf:

pass in quick proto tcp to port { 6660:6669 6697 6997 7000 9999 16667 16697 } #irc

Then, reload the pf rulesets:

$ doas pfctl -f /etc/pf.conf