Kushal Das

FOSS and life. Kushal Das talks here.


Using ZNC on Tor Network for Freenode and OFTC

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
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 =
        IPv4 = true
        IPv6 = false
        Port = 8001
        SSL = false
        URIPrefix = /

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

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/'

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>

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

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
  • 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.