The Tor network provides a safer way to access
the Internet, without local ISP and government recording your every step on the
Internet. We can use the same network to chat over IRC. For many FOSS
contributors and activists across the world, IRC is a very common medium for a
chat. In this blog post, we will learn about how to use ZNC with Tor for IRC.
Introducing ZNC
ZNC is an IRC bouncer program, which will allow your
IRC client to stay detached from the server, but still receive and log the
messages, so that when you connect a client later on, you will receive all the
messages.
In this tutorial, we will use znc-1.6.6 (packaged in Fedora and EPEL). I am
also going to guess that you already figured out the basic
usage of ZNC.
Installing the required tools
$ sudo dnf install znc tor torsocks
Tor provides a SOCKS proxy at port 9050
(default value), but, ZNC cannot use
a SOCKS proxy easily. We will use torify
command from torsocks package to use
the SOCKS proxy.
ZNC service over Tor network
As a first step, we will make sure that we have the listener at the ZNC service
listening as an Onion service. First, we will edit our /etc/tor/torrc
file
and add the following.
HiddenServiceDir /var/lib/tor/hidden_service/
HiddenSeriveVersion 2
HiddenServicePort 8001 127.0.0.1:8001
HiddenServiceAuthorizeClient stealth hidden_service
After this, when we start the tor
service, we will be able to find the
.onion address and the HidServAuth value from the
/var/lib/tor/hidden_service/hostname
file.
# cat /var/lib/tor/hidden_service/hostname
34aaaiwlmrandom8.onion SomeO/+yOOPjvaluetext # client: hidden_service
Now, I will be using a user account ftor
in the server to run ZNC. The
configuration files for ZNC is at /home/ftor/.znc
directory.
I have the following values in the ~/.znc/configs/znc.conf
file for the
listener.
<Listener listener0>
AllowIRC = true
AllowWeb = true
Host = 127.0.0.1
IPv4 = true
IPv6 = false
Port = 8001
SSL = false
URIPrefix = /
</Listener>
Here, I am making sure that the listener only listens to the localhost. We
already mapped the port 8001
of localhost to our Onion service. This way the
web frontend of ZNC is only available over Tor.
Now you can start service, I will keep it running in the foreground along with
debugging messages to make sure that things are working.
$ torify znc --debug
Connecting from web client
I am using xchat as the IRC client. I also have Tor installed on my local
computer and added the following line the /etc/tor/torrc
file so that my
system can find and connect to the Onion service.
HidServAuth 34aaaiwlmrandom8.onion SomeO/+yOOPjvaluetext
If you just want to connect to the ZNC web frontend using the Tor Browser, then
you will have to add the same line the Browser/TorBrowser/Data/Tor/torrc
inside of the Tor Browser.

Connecting to OFTC network
Now we will connect to the OFTC IRC network. The Tor
Project itself has all the IRC channels on this
network. Make sure that you have a registered IRC nickname on this network.
Add the following configuration in the ZNC configuration file.
<Network oftc>
Encoding = ^UTF-8
FloodBurst = 4
FloodRate = 1.00
IRCConnectEnabled = true
JoinDelay = 0
Nick = yournickname
Server = irc4.oftc.net +6697
<Chan #tor>
Buffer = 500
</Chan>
</Network>
Now let us start xchat with torify so that it can find our onion service.
$ torify xchat
Next, we will add our new ZNC service address as a new server, remember to have
the password as zncusername/networkname:password
. In the above case, the
network name is oftc.

After adding the new server as mentioned above, you should be able to connect
to it using xchat.
Connecting to Freenode network
Freenode provides an Onion service to
it’s IRC network. This means your connection from the client (ZNC in this case)
to the server is end-to-end encrypted and staying inside of the Onion network
itself. But, using this will require some extra work.
Creating SSL certificate for Freenode
On the server, we will have to create an SSL certificate.
$ openssl req -x509 -sha256 -nodes -days 1200 -newkey rsa:4096 -out user.pem -keyout user.pem
Remember to keep the name of the output file as user.pem, I had to spend a
few hours debugging thanks to a wrong filename.
We will have to find the fingerprint of the certificate by using the following
command.
$ openssl x509 -sha1 -noout -fingerprint -in user.pem | sed -e 's/^.*=//;s/://g;y/ABCDEF/abcdef/'
eeeee345b4d9d123456789fa365f4b4b684b6666
Now connect to Freenode normally using your regular client (xchat in my case),
and add this fingerprint to your nickname.
/msg NickServ CERT ADD eeeee345b4d9d123456789fa365f4b4b684b6666
You should be able to see the details using whois.
/whois yournick
Enable SASL and Cert module in ZNC
Next, we will move the certificate file to the right location so that ZNC can
use it.
$ cp user.pem ~/.znc/users/<yourzncuser>/networks/freenode/moddata/cert/user.pem
Remember to put the right ZNC username in the above command.
Add the following configuration for freenode network in the ZNC configuration
file and restart ZNC.
<Network freenode>
FloodBurst = 4
FloodRate = 1.00
IRCConnectEnabled = true
JoinDelay = 0
LoadModule = simple_away
LoadModule = cert
LoadModule = sasl
Nick = yourusername
Server = freenodeok2gncmy.onion +6697
TrustedServerFingerprint = 57:2d:6f:dc:90:27:0e:17:b6:89:46:4f:6a:a4:37:6e:e9:20:e1:cd:ee:f5:42:cd:3c:5a:a8:6d:17:16:f8:71
<Chan #znc>
</Chan>
</Network>
Remember to update the nickname. At the end of the blog post, I will explain
more about the server fingerprint.
Next, go to the *status
tab in your client, and give the following commands
to load cert and sasl
modules.
/query *status
loadmod cert
loadmod sasl
/msg *sasl Mechanism EXTERNAL
/query *status
Jump
The Jump
command will try to reconnect to the Freenode IRC server. You should
be able to see the debug output in the server for any error.
The story of the server fingerprint for Freenode
Because Freenode’s SSL certificate is not an EV certificate for the .onion
address, ZNC will fail to connect normally. We will have to add the server
fingerprint to the configuration so that we can connect. But, this step was
failing for a long time, and the excellent folks in #znc helped me to debug the
issue step by step. It seems the fingerprint given on the Freenode
site is an old one, and we need the
current fingerprint. We also have an
issue filed on a related note.
Finally, you may want to run the ZNC as a background process on the server.
$ torify znc
Tools versions
- ZNC 1.7.3
- tor 0.4.0.5
- torsocks 2.2.0
If you have queries, feel free to join #znc on Freenode and #tor on OFTC
network and ask for help.
Updated post
I have updated the post to use torify command. This will make running znc much
simpler than the tool mentioned previously.