Self-signed certificates in irssi

Point irssi at your own ZNC, or at any service using a certificate it generated itself, and sooner or later you get this:

-!- Irssi: (default) warning Could not verify TLS servers certificate:
                             self-signed certificate
-!- Irssi: Connection lost to yourhost

irssi is not refusing self-signed certificates as such, and there is no "accept this one anyway" prompt — deliberately, because a prompt that appears every time is a prompt everybody clicks through. What it wants instead is to be told which certificate to expect. Three supported ways to do that, below, all of them tested on this box.

The short answer

Trust the certificate once, then verify against it forever after:

ss-tls-trust                        # your own ZNC (~/.znc/znc.pem)
ss-tls-trust irc.example.org 6697   # or whatever a service is presenting

That copies the certificate into ~/.irssi/tls-trusted.pem, a file only you can read, and prints the command to use:

/connect -tls -tls_verify -tls_cafile /home/yourname/.irssi/tls-trusted.pem yourhost 6697

Verification is fully on; it is just checking against a certificate you decided to trust rather than against the public authorities, which is exactly what a self-signed certificate needs. ss-tls-trust --list shows what you have trusted and when. Everything below is the longer version, including how to do it without the helper.

Getting the fingerprint yourself

Every method needs the certificate's fingerprint, and prising that out of openssl is a pipeline nobody remembers. There is a command for it:

ss-tls-fingerprint                    # your own ZNC (~/.znc/znc.pem)
ss-tls-fingerprint /path/to/cert.pem  # a certificate file
ss-tls-fingerprint irc.example.org 6697   # whatever a live service presents

It prints the certificate fingerprint, the public key fingerprint, and the irssi command for each.

Option 1: pin the certificate

The straightforward answer for a bouncer you run yourself. You are saying "I know this certificate; accept exactly it and nothing else".

/connect -tls -tls_pinned_cert BA:F6:73:...:BC yourhost 6697

To keep it, save it as a network rather than retyping it:

/network add myznc
/server add -tls -notls_verify -tls_pinned_cert BA:F6:73:...:BC -network myznc yourhost 6697
/save

Then /connect myznc from now on.

Do not leave out -notls_verify. Adding a pin with /server add switches ordinary verification on as a side effect, and the pin does not rescue the connection when it fails — you get the same "could not verify" error as before, now with a pin configured, which is a thoroughly confusing place to end up. With -notls_verify the pin is doing the authenticating instead of the certificate chain, which is exactly what you want for a certificate that has no chain.

Option 2: pin the public key

/connect -tls -tls_pinned_pubkey D8:BE:83:...:6E yourhost 6697

Same idea, one level down: it pins the key inside the certificate rather than the certificate itself. The practical difference is that reissuing the certificate from the same key — a renewal, or a longer expiry — does not break your pin. Use this one if you expect to regenerate certificates.

Option 3: trust the certificate as its own authority

If the certificate file is on the same machine you are running irssi on — your own ZNC, for instance — you can simply point irssi at it and let normal verification run against it:

/connect -tls -tls_verify -tls_cafile ~/.znc/znc.pem yourhost 6697

Saved as a network:

/network add myznc
/server add -tls -tls_verify -tls_cafile /home/yourname/.znc/znc.pem -network myznc yourhost 6697
/save

Use the full path, not ~. This is the tidiest option when the file is right there; it is no use for a remote server whose certificate you would have to copy over first.

The option you should not reach for first

/connect -tls yourhost 6697

Plain -tls with no verification connects to anything. It is worth understanding what it does and does not buy you: your traffic is encrypted, and you have no idea who you are talking to. For a bouncer that holds your NickServ password and replays your private messages, that is the wrong trade — anyone able to redirect your connection can present their own certificate and you will not be told. Pinning takes one extra command.

When the fingerprint changes

Regenerating your ZNC certificate (znc --makepem) produces a new one, and your pin will stop matching:

-!- Irssi: (default) warning   Pinned certificate mismatch

Re-run ss-tls-fingerprint and update the pin, or re-run ss-tls-trust to add the new certificate to your trust file. The old entry stays in the file; remove it by editing ~/.irssi/tls-trusted.pem if you want it gone.

If the fingerprint changes when you did not change anything, do not update the pin to make the error go away. That is precisely the case pinning exists to catch. Tell staff.

Looking at a certificate directly

openssl s_client -connect yourhost:6697 </dev/null | openssl x509 -noout -text | head -20

Useful when you want the whole picture — issuer, validity dates, subject alternative names — rather than just the fingerprint.

See also the ZNC guide, which covers getting the bouncer running in the first place.

« All guides