My IRC bouncer: systemd, znc, tor, socat

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.

Nerd, server e documentazione

Le premesse:

  • La documentazione e’ bella (da leggere)
  • La documentazione e’ brutta (da scrivere)
  • I browser sono bruttissimi
  • Gli Hidden Service sono lentissimi
  • Le cose importanti non sono poi tanto importanti
  • Le cose pulite sono noiose

In genere risolvevo questo insieme di dubbi mettendo dei file in /etc/doc, e uno cosi’ risolve. Ma:

  • Devo loggarmi per aggiornare la documentazione
  • Se uso ssh su hidden service, usare un editor e’ dolorosissimo

E quindi la soluzione “browser” torna in vantaggio. Ma hidden service web e’ ancora piu’ frustrante che web normale.

Ci vorrebbe una cosa web che:

  • Puoi comunque modificare anche da terminale senza sbattimenti
  • Richiede il caricamento di 0 risorse esterne (tor ha alta latenza, ma banda piu’ che accettabile sugli hidden service); anche le richieste AJAX andrebbero centellinate

Per farlo siamo disposti a rinunciare a:

  • Pulizia
  • Sistema di controllo versioni integrato (in realta’ questa e’ pigrizia di implementazione, non un limite di design; incron + git risolverebbe egregiamente)
  • Gestione del locking: per richiedere il lock dovremmo fare una richiesta e attendere la risposta, ma noi non vogliamo
  • Scalabilita’: assumiamo che il contenuto sia “piccolo”

La risposta e’ nowiki, un wiki che viola qualsiasi “best practice”: carica tutti i css, i javascript, le immagini (con base64encode) e tutte le pagine in un’unica pagina html. La navigazione quindi non richiede nessun altro caricamento. L’edit e’ gestito con javascript e, fino alla PUT per aggiornare i dati, non avviene nessuna richiesta.

Infine, dopo il connubio nerd-documentazione, eccovi un video di altre accoppiate improbabili: