Programming, philosophy, pedaling.

Proxying ZNC Without a Subdomain

Apr 24, 2017

Tags: irc, workflow

Preword: I'm putting this out here because I had trouble figuring out how to do this, despite being explicitly supported by ZNC. Hopefully people will be able to find this and avoid a prolonged search.

If you're like me, then IRC is one of your primary mechanisms for talking to other programmers (and, more generally, interesting folks all around the world). Despite prettier alternatives being available, I still default to IRC for three main reasons:

To minimize the amount of configuration syncing I need to do across my different machines, I use the excellent ZNC to manage and persist my IRC connections. ZNC also has a web interface, making it easy to toggle and tweak my networks from within the browser.

For a long time, the only ways to expose ZNC's web interface was to either reverse proxy over a subdomain (e.g., znc.example.com) or to expose ZNC's HTTPd directly. This was because ZNC's webadmin HTML was littered with absolute paths, breaking the site's CSS and login process.

Neither of these really appealed to me: proxying over a subdomain requires me to do extra housework with a Let's Encrypt certificate and nginx, while exposing ZNC's internal HTTPd involves trusting an IRC project to do HTTP correctly (and running an additional exposed service).

Fortunately, this has changed as of ZNC 1.6 with the URIPrefix setting for Listeners.

To reverse proxy ZNC without a subdomain, first kill ZNC off:

$ killall znc

Then, edit your znc.conf (normally ~/.znc/configs/znc.conf):

TrustedProxy =

// ...snip...

<Listener listener0>
    AllowIRC = false
    AllowWeb = true
    IPv4 = true
    IPv6 = true
    Port = 1337
    SSL = true
    URIPrefix = /znc/

(I set it to /znc/ instead of /, but your URIPrefix can be anything that would legally fit into a URI).

This makes the reverse proxy rule in nginx a piece of cake:

location /znc/ {
    proxy_set_header    Host              $host;
    proxy_set_header    X-Real-IP         $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

And reload nginx and restart znc, of course:

$ sudo service nginx reload # or systemctl, or init, or whatever
$ znc

If you don't like editing znc.conf by hand, you can do the same thing through the "Global settings" page in webadmin (assuming you have local access):

Once that's configured, you only need to follow the nginx step above.

Happy hacking!

- William