The Pidgin developers apparently haven’t thought things through very well when it comes to TLS/SSL support because, if you want to connect to a network which uses a self-signed cert, they’ll present you with a permission dialog every time you connect (no “remember” option) and, last time I reported this, they considered it “WONTFIX: self-signed certs are a bug”.
They seem to think that it will force network operators to get proper certificates but, in reality, they don’t have that kind of leverage when every other IRC client allows you to ignore cert errors, so it just forces people to either turn off SSL or desensitizes them to the warning dialogs.
This is especially problematic for me because one of the networks I connect to is encrypted-only, managed by someone who doesn’t trust Let’s Encrypt and, if the Pidgin SSL handshake times out, it remembers the failure rather than re-displaying the prompt on reconnect. Because I have no idea how long the timeout is but it always seems too short, that trained me to punch “allow” on the annoying dialog as quickly as possible without wasting time reading the prompt… never a good sign.
So, today, I’m going to teach you how to get the best of both worlds: How to use stunnel to trick Pidgin into using self-signed SSL without complaining. (And, as a bonus, stunnel makes it easy to verify a self-signed cert without adding it to the system-wide cert store, so it can actually be more secure than the certs the Pidgin developers want you to use.)
First, install stunnel and set it to run on startup. On Debian-based distros like Ubuntu and Mint, this is as simple as running
sudo apt-get install stunnel and then setting
Next, we need to write a config file so that, when your client connects to a stunnel server on localhost without encryption, it will make an encrypted connection to the IRC server in question.
The key lines are as follows:
; Maximize security ; NOTE: See the manpage or sample config file for implications chroot = /var/lib/stunnel4/ setuid = stunnel4 setgid = stunnel4 ; Needed for stunnel to work properly ; (Prefix the contents of the chroot line if not using chroot) pid = /stunnel4.pid ; Disable support for insecure SSLv2 protocol options = NO_SSLv2 ; Define the actual proxy service [irc-your-network] client = yes accept = 127.0.0.1:6612 connect = irc.your-network.com:6697
Now, at this point, you’ve matched what you got from putting up with Pidgin’s security dialog:
- Put those lines into
- Start stunnel (
sudo /etc/init.d/stunnel4 startif you’re on Ubuntu 14.04 LTS or older)
- Set Pidgin to connect to the address in the
Pidgin will think it’s connecting to an un-encrypted IRC server and the connection will be encrypted between stunnel and the server.
However, we can do one better. If we can get the server certificate in PEM format, we can have stunnel verify it, preventing man-in-the-middle attacks.
The ideal solution would be to download the PEM file through a trusted channel but, as a stop-gap, let’s replicate the “trust whatever we see first” behaviour that SSH uses. Fill in your IRC server’s details in the following command and run it to dump the server cert:
openssl s_client -showcerts -connect irc.your-network.com:6697 </dev/null 2>/dev/null|openssl x509 -outform PEM >your-irc-network.pem
Now, copy the resulting
your-irc-network.pem file into
/etc/stunnel/ and add the following lines to your
verify=3 CAfile = /etc/stunnel/your-irc-network.pem
You’ll probably also want to add these lines temporarily so you can see what’s going wrong if the verification fails:
debug = 7 output = /stunnel.log
…and, that’s it. Just restart stunnel, reconnect with your IRC client, and, barring verification errors, you should have an encrypted connection which verifies the self-signed certificate.
(I say “should” because, as of this writing, the self-signed cert I’m testing against is expired, so I can’t get all the way through the verification process to confirm.)