Background
IRC is the chat protocol I use everyday. I’d like to do it in a secure way, but xchat is really dumb, and doesn’t allow certificate pinning. Tor hidden services are great in this, because their name is also the proof of their identity; you can’t have MITM with them.
Then we have another problem: tor on a home ADSL connection is usually slow and unreliable. It’s annoying to have a client which disconnects from time to time.
As I have a server, I’ll run tor and irc on that server, using a bouncer. Then I’ll connect to the bouncer using his own tor hidden service; this time, even if the connection is unreliable, it’s not a big deal: my bouncer will stay fine, and I will not lose messages.
So here’s the plan: a debian box with “torified” znc; it will be used to connect to networks through tor.
Systemd
About systemd: on a plain wheezy installation, just apt-get install systemd systemd-sysv.
I love it: it’s easier to see the status of your machine, easier to write advanced configurations for your daemons, and I feel much more in control when restricting capabilities of my daemons is so easy.
Having to start from a “vanilla” box, I chose to use it, because I had to manage “complex” relationships between programs that don’t like to behave as daemons.
Znc
Znc is easy to install and configure; the bad part is that it is not easy to “torify” it, so we’ll just let him connect to socat, which will do the heavy job (just use localhost:4141)
Tor
Then we need to install tor, socat, znc.
Some notes about the following services:
- socat -ly daemon is to make it use syslog
- the restartsec is because we need the address to be freed
This is tor.service:
[Unit] Description=Anonymizing Overlay Network After=network.target [Service] Type=forking GuessMainPID=yes ExecStart=/usr/bin/tor -f /etc/tor/torrc --quiet ExecReload=/bin/kill -HUP $MAINPID KillSignal=SIGINT LimitNOFILE=8192 [Install] WantedBy=multi-user.target
This is znc.service
[Unit] Description=IRC Bouncer Requires=network.target Wants=socat_torai.service [Service] Type=forking User=znc Group=znc ExecStart=/usr/bin/znc [Install] WantedBy=multi-user.target
This, instead, is socat_torai.service
[Unit] Description=Socket for a/i hidden service Requires=tor.service [Service] Type=simple User=nobody Group=nogroup ExecStart=/usr/bin/socat -lydaemon TCP4-LISTEN:4141,fork,bind=localhost SOCKS4A:localhost:wi7qkxyrdpu5cmvr.onion:6667,socksport=9050 NoNewPrivileges=true RestartSec=5 Restart=on-failure [Install] WantedBy=multi-user.target
TODO and footnotes
- If we really want to ensure that znc is totally torified, we should deny him access to net. This should be easy to do with systemd PrivateNetwork option
- A bit of security wouldn’t be bad: I’d like to deny as much as possible (/etc, /var/, …) using InaccessibleDirectories, but I still have not tested it
- We could have used another approach for “torifying” znc, that is redsocks + some iptables rule. Maybe it would have been even easier.