Encrypting bitlbee traffic with stunnel
stunnel encryption with client-side certificates

Posted on 2014-04-09

While going through all my externally facing services I noticed bitlbee is not actually encrypted. This was quite a surprise for me, mainly for the fact that I did not notice it while setting bitlbee up the first time. On the other hand not much was compromised as the services I use via bitlbee are all run by untrustworthy corporations. All communication through them is as good as unencrypted anyway :). Likewise since I have setup my firewall to only accept connections from one other host, which I also control, gaining control over bitlbee itself would have been difficult for an attacker.

Regardless, I needed to reset my passwords for all accounts used and obviously make sure my communication with bitlbee was encrypted. Since bitlbee have been working so well for me I opted to use stunnel to encrypt the traffic. I was also curious to see if I could get client-side certificates to work, which is a feature stunnel provides.

I have omitted the output from most commands on this page in order reduce clutter. Only a few commands are interactive, such as openssl req.


I based my stunnel config of the sample provided in debian in /usr/share/doc/stunnel4/examples/stunnel.conf-sample. I have gathered most information from the sample, manpages and http://www.stunnel.org/static/stunnel.html.

This is my the entire contents of my config file (/etc/stunnel/stunnel.conf) excluding the service definitions:

chroot = /var/lib/stunnel4/
setuid = stunnel4
setgid = stunnel4
pid = /stunnel4.pid
cert = /etc/stunnel/stunnel.pem
verify = 3
CApath = /certs
options = NO_SSLv3
options = SINGLE_DH_USE


It is interesting to note that since we are running a chroot it is not possible to reload the config file. When stunnel first starts it reads the proper one, however if you try to reload it (sudo /etc/init.d/stunnel reload) it will not be able to find the file, as it is searching in the chroot.

The chroot itself needs to contain certain files, I simply assumed that most of the files listed in the documentation were required.

user@server $ ls /var/lib/stunnel4/
certs  nsswitch.conf  resolv.conf  timezone


We need to generate the key and certificate on the server. Remember to specify the domain name of the server correctly when creating the certificate request (openssl req) is the same that we later use to connect to via irssi. It must match the host you use when connecting from irssi, if they do not match the certificate will be invalid and irssi will refuse to connect.

user@server $ openssl genrsa 4096 > stunnel.key
user@server $ openssl req -new -key stunnel.key -x509 -days 1095 -out stunnel.crt
user@server $ cat stunnel.{key,crt} > stunnel.pem
user@server $ openssl gendh 2048 >> stunnel.pem
user@server $ sudo mv stunnel.pem /etc/stunnel/stunnel.pem
user@server $ # Let stunnel4 own it
user@server $ sudo chown stunnel4:stunnel4 /etc/stunnel/stunnel.pem
user@server $ # Make sure no-one else can read it
user@server $ sudo chmod 600 /etc/stunnel/stunnel.pem

And on the client we need a key and certificate as well:

user@client $ openssl genrsa 4096 > client.key
user@client $ openssl req -new -key client.key -x509 -days 1095 -out client.crt
user@client $ cat client.{key,crt} > client.pem
user@client $ scp client.crt server:                # Upload the client certificate
user@client $ scp server:stunnel.crt .              # Download the server certificate

Now we need to put the client certificate into the certs folder on the server

user@server $ sudo mv client.crt /var/lib/stunnel4/certs
user@server $ # Generate symlinks with checksums for the certificates, this
user@server $ # is the files that are actually read by stunnel
user@server $ sudo c_rehash /var/lib/stunnel4/certs


Setting up bitlbee is simple, we only have to listen to the port specified in the stunnel config file. I also recommend listening only to localhost: DaemonInterface =

NOTE: On debian the port from bitlbee.conf is ignored, run sudo dpkg-reconfigure bitlbee-common instead


The last step is to setup irssi, its a simple one-liner:

/server add -ssl -ssl_cert client.pem -ssl_cafile stunnel.crt -ssl_verify <host> <port>