The [Tor network](https://www.torproject.org) 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](https://wiki.znc.in/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](https://wiki.znc.in/Introduction) of ZNC.
### Installing the required tools
```text
$ 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.
```text
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.
```text
# 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.
```text
AllowIRC = true
AllowWeb = true
Host = 127.0.0.1
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.
```text
$ 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.
```text
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.
![](/images/znc_loginscreen.png)
### Connecting to OFTC network
Now we will connect to the OFTC IRC network. [The Tor
Project](https://www.torproject.org) 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.
```text
Encoding = ^UTF-8
FloodBurst = 4
FloodRate = 1.00
IRCConnectEnabled = true
JoinDelay = 0
Nick = yournickname
Server = irc4.oftc.net +6697
Buffer = 500
```
Now let us start xchat with torify so that it can find our onion service.
```text
$ 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*.
![](/images/xchat_add_network_server.png)
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](https://freenode.net/kb/answer/chat) 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.
```text
$ 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.
```text
$ 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.
```text
/msg NickServ CERT ADD eeeee345b4d9d123456789fa365f4b4b684b6666
```
You should be able to see the details using whois.
```text
/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.
```text
$ cp user.pem ~/.znc/users//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.
```text
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
```
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](http://wiki.znc.in/Cert) and [sasl](http://wiki.znc.in/Sasl)
modules.
```text
/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](https://freenode.net/kb/answer/chat) is an old one, and we need the
current fingerprint. We also have an
[issue](https://github.com/znc/znc/issues/1507) filed on a related note.
Finally, you may want to run the ZNC as a background process on the server.
```text
$ 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.