Znc /

Install ZNC from Source

Overview

ZNC is an IRC bouncer. It runs on a server and stays connected after you turn off your computer or phone. It saves chat messages and replays them when you reconnect, and also helps to hide your IP address. If you are running it on IRCNow, your server may also offer DDoS protection to keep you online.

Compiling from Source

Patched Source

Due to a bug in OpenBSD 6.9, we have applied a custom patch to ZNC to avoid segfaults on multicore servers:

diff -ru znc-1.8.2-old/src/main.cpp znc-1.8.2-new/src/main.cpp
--- znc-1.8.2-old/src/main.cpp	Mon Sep  7 18:57:50 2020
+++ znc-1.8.2-new/src/main.cpp	Thu Dec 24 17:04:37 2020
@@ -292,6 +292,7 @@
 }

 int main(int argc, char** argv) {
+    pthread_attr_t a; pthread_attr_init(&a);
     CString sConfig;
     CString sDataDir = "";

The schat module also needs patching for libreSSL?:

--- modules/schat.cpp.orig
+++ modules/schat.cpp
@@ -25,8 +25,8 @@
 #include <znc/User.h>
 #include <znc/IRCNetwork.h>

-#if !defined(OPENSSL_VERSION_NUMBER) || defined(LIBRESSL_VERSION_NUMBER) || \
-    OPENSSL_VERSION_NUMBER < 0x10100007
+#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100007 || \
+    (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3040000fL)
 /* SSL_SESSION was made opaque in OpenSSL 1.1.0, cipher accessor was added 2
 weeks before the public release.
 See openssl/openssl@e92813234318635639dba0168c7ef5568757449b.
 */

IRCNow provides a patched version of ZNC:

$ cd ~
$ ftp https://ircnow.org/software/znc-1.8.2a.tar.gz

On OpenBSD, ftp? can also be used to download files from the web.

For tar?, the options xvzf stand for e(x)tract, (v)erbose, un(z)ip, and (f)ile.

$ tar xvzf znc-1.8.2a.tar.gz

Upstream Source

You can choose to use the upstream source code, but you must apply patches to get it to build properly.

WARNING: If you are on OpenBSD 7.0, you must patch znc-1.8.2 to avoid a threading bug that causes segfaults and to fix a bug in the schat module.

First, download the latest stable release:

$ cd ~
$ ftp https://znc.in/releases/znc-1.8.2.tar.gz

We recommend you verify the gpg signature:

$ doas pkg_add gnupg
$ ftp https://znc.in/releases/znc-1.8.2.tar.gz.sig
$ gpg2 --recv-key D5823CACB477191CAC0075555AE420CC0209989E
$ gpg2 --verify znc-1.8.2.tar.gz.sig znc-1.8.2.tar.gz

Next, extract and unzip? the files:

$ tar xvzf znc-1.8.2.tar.gz 

Building ZNC

Next, we build ZNC:

$ cd znc-1.8.2
$ mkdir build
$ cd build

We then use cmake to configure the files to install to ~/.local, then make and make install:

$ cmake .. -DCMAKE_INSTALL_PREFIX="$HOME/.local"
$ make
$ make install

You should see this message:

 ZNC was successfully installed.
 You can use '/home/username/.local/bin/znc --makeconf'
 to generate a config file.

 If you need help with using ZNC, please visit our wiki at:
   http://znc.in

Creating znc.conf

Follow the instructions to generate the config file:

$ ~/.local/bin/znc --makeconf
[ .. ] Checking for list of available modules...
[ ** ] 
[ ** ] -- Global settings --
[ ** ] 
[ ?? ] Listen on port (1025 to 65534): 

If you are on a shell account, you must use the ports? that were reserved for your username.

WARNING: Shell accounts users must not randomly choose ports. Shell accounts servers often have firewalls in place that will block ports not reserved to you. If you are unable to connect to ZNC, double check to see if the firewall is blocking the connection.

[ ?? ] Listen using SSL (yes/no) [no]: yes
[ ?? ] Listen using both IPv4 and IPv6 (yes/no) [yes]: no

SSL? helps to encrypt messages sent between client and server. In other words, if you turn it on, messages sent from your IRC program to ZNC are kept secure. It's more trouble to set up, and some older IRC programs don't support it, so some users prefer to turn off SSL.

WARNING: Do not listen to both IPv4 and IPv6. There appears to be a bug in ZNC v1.8.2 on OpenBSD 6.9 where selecting 'yes' will cause IPv4 to stop working. Instead, as shown later in the guide, you can create separate listeners to allow listening to both IPv4 and IPv6.

IPv4 is the default networking protocol. IPv6 is becoming more popular now, especially for mobile devices.

[ .. ] Verifying the listener...
[ ** ] Unable to locate pem file: [/home/username/.znc/znc.pem], creating it
[ .. ] Writing Pem file [/home/username/.znc/znc.pem]...
[ ** ] Enabled global modules [webadmin]

ZNC will automatically create its own SSL certificate. This certificate, however, will be self-signed and hence will show up as invalid or untrusted by your IRC client. If you'd like a properly signed SSL certificate, ask your sysadmin or request one yourself using acme-client.

[ ** ] 
[ ** ] -- Admin user settings --
[ ** ] 
[ ?? ] Username (alphanumeric): username
[ ?? ] Enter password: 
[ ?? ] Confirm password: 
[ ?? ] Nick [username]: 
[ ?? ] Alternate nick [username_]: 
[ ?? ] Ident [username]: 
[ ?? ] Real name (optional): username

Bindhosts

Next, you'll be asked to specify an optional bindhost. The bindhost will give you a nice-looking vhost, like username@username.example.com.

WARNING: You cannot pick any arbitrary bindhost that you want. If you bindhost does not work, your vhost will not show up properly, and you may not be able to connect at all!

A vhost must have proper forward and reverse DNS records to work. If you're using an IRCNow shell account, you should have been provided with one at registration. You can also ask your sysadmin to change it for you, or leave it blank.

To test if your bindhost works properly, check the host guide. You will want to run host on your bindhost:

$ host username.example.com
username.example.com has address 192.168.1.1
username.example.com has IPv6 address 2001:bd8::

Your bindhost should show both an IPv4 and IPv6 address. If it's missing an IPv4 address, it can only connect by IPv6 to an IRC network. If it's missing an IPv6 address, then it can only connect by IPv4 to an IRC network. If it's missing both, it cannot connect to any network.

For this reason, you don't want to put an IPv6 address directly into the bindhost. This prevents ZNC from being able to connect to an IPv4 only network. Instead, you want to use a hostname that has both A and AAAA records defined in DNS.

[ ?? ] Bind host (optional): username.example.com

User Modules

You'll want to enable all the user modules:

[ ** ] Enabled user modules [chansaver, controlpanel]
[ ** ]                                 

Set Up a Network

You can optionally set up a network at this stage:

[ ?? ] Set up a network? (yes/no) [yes]: yes                            
[ ** ]                                 
[ ** ] -- Network settings --
[ ** ]                                                                        
[ ?? ] Name [freenode]: ircnow
[ ?? ] Server host (host only): irc6.ircnow.org
[ ?? ] Server uses SSL? (yes/no) [no]: yes
[ ?? ] Server port (1 to 65535) [6697]:  
[ ?? ] Server password (probably empty): 
[ ?? ] Initial channels: #ircnow
[ ** ] Enabled network modules [simple_away]
[ ** ] 
[ .. ] Writing config [/home/username/.znc/configs/znc.conf]...

This will cause ZNC to automatically connect to your favorite network (IRCNow).

Next, I recommend *not* launching ZNC. There are still some settings you will want to add and configure:

[ ** ] To connect to this ZNC you need to connect to it as your IRC server
[ ** ] using the port that you supplied.  You have to supply your login info
[ ** ] as the IRC server password like this: user/network:pass.
[ ** ] 
[ ** ] Try something like this in your IRC client...
[ ** ] /server <znc_server_ip> +12345 username:<pass>
[ ** ] 
[ ** ] To manage settings, users and networks, point your web browser to
[ ** ] https://<znc_server_ip>:12345/
[ ** ] 
[ ?? ] Launch ZNC now? (yes/no) [yes]: no

Stop ZNC

If you accidentally launch ZNC, you will see:

[ .. ] Opening config [/home/username/.znc/configs/znc.conf]...
[ .. ] Loading global module [webadmin]...
[ .. ] Binding to port [+12345]...
[ ** ] Loading user [username]
[ ** ] Loading network [ircnow]
[ .. ] Loading network module [simple_away]...
[ >> ] [/home/username/.local/lib/znc/simple_away.so]
[ .. ] Adding 1 servers...
[ .. ] Loading user module [chansaver]...
[ .. ] Loading user module [controlpanel]...
[ .. ] Forking into the background...
[ >> ] [pid: 86542]
[ ** ] ZNC 1.8.2 - https://znc.in

To stop ZNC once it is launched, you can kill it:

$ kill -TERM <pid>

You will want to replace <pid> with the process ID you see above (86542):

$ kill -TERM 86542

This will send a (TERM)ination signal to ZNC so that it dies.

NOTE: You will need to replace 8542 with your process ID.

If you don't know the process ID, you can type:

$ ps -U <username> | grep znc

Replace <username> with your username.

Recreate znc.conf

If at any time you mess up the configuration, you can delete your znc.conf and rerun the makeconf command again:

$ rm ~/.znc/configs/znc.conf
$ ~/.local/bin/znc --makeconf

Changing Password

If you forget the password you set during the --makeconf, you can generate a new one like this:

# /usr/sbin/chroot -u znc -g znc /home/znc znc --makepass                                    
[ ** ] Type your new password.
[ ?? ] Enter password: 
[ ?? ] Confirm password: 
[ ** ] Kill ZNC process, if it's running.
[ ** ] Then replace password in the <User> section of your config with this:
<Pass password>
                Method = sha256
                Hash = 49396054dc8263b573d11c9c01e43f89ee772f6dc89b3c630e6dffa9acea4a3e
                Salt = ovexwSL50cC?jE2eCM?x
        </Pass>
[ ** ] After that start ZNC again, and you should be able to login with the new password.

The example output above shows the hash generated for a password of "password". This gives you the password block you need to add to your /home/znc/home/znc/.znc/configs/znc.conf file. NOTE: You'll need to replace the original generated Pass = line. The new user section of your config will look something like this:

<User username>
        <Pass password>
                Method = sha256
                Hash = 49396054dc8263b573d11c9c01e43f89ee772f6dc89b3c630e6dffa9acea4a3e
                Salt = ovexwSL50cC?jE2eCM?x
        </Pass>
	Admin      = true
	Nick       = username
	AltNick    = username_
	Ident      = username
	LoadModule = chansaver
	LoadModule = controlpanel

	<Network example>
		LoadModule = simple_away
		Server     = irc.example.com +6697 
		<Chan #channel>
		</Chan>
	</Network>
</User>

Copying SSL certs (optional)

If you want to have properly validating SSL certs, your sysadmin can provide them for you in your ~/ssl/ folder. We will need to create a symbolic link for them to your znc folder:

$ ln -s ~/ssl/username.example.com.crt ~/.znc/username.example.com.crt
$ ln -s ~/ssl/username.example.com.key ~/.znc/username.example.com.key

You must replace username.example.com with your actual hostname.

Afterwards, we can create a dhparam file:

$ openssl dhparam -out ~/.znc/dhparam.pem 2048

Configuration

Here are some recommended changes to make to the default znc.conf so that it works nicely. Replace the top portion of znc.conf with these settings:

AnonIPLimit = 10000
AuthOnlyViaModule = false
ConfigWriteDelay = 60
ConnectDelay = 1
HideVersion = false
MaxBufferSize = 10000
ProtectWebSessions = true
ServerThrottle = 1
Version = 1.8.2

WARNING: Do not duplicate listeners or settings, or else ZNC will fail.

For a full explanation of these settings, please consult the ZNC wiki.

Next, we load the following modules:

LoadModule = chansaver
LoadModule = adminlog
LoadModule = certauth
PidFile = /home/znc/.znc/znc.pid

If you want to store logs on the shell account, you can add this line:

LoadModule = log

NOTE: sysadmins can read logs stored on the server. Also, in the event of a security breach, an attacker can also read these logs.

SSL certs (Optional)

If you want properly validating SSL certs, you can add these lines to set the paths for the SSL files and process ID (pid) files:

SSLCertFile = /home/znc/.znc/username.example.com.crt
SSLKeyFile = /home/znc/.znc/username.example.com.key
SSLDHParamFile = /home/znc/.znc/dhparam.pem

NOTE: For the SSL certs, you will need to ask the admin. You will need to replace username.example.com with the unique hostname that your admin provides.

WARNING: You must not''' use username.example.com or else your SSL certificates will not load properly and your ZNC will not be able to offer SSL encryption. If you do not have your own SSL certs, then don't add these lines!

Listeners

Next, you'll want to create listeners. Each listener specifies a unique combination of IP address and port (a TCP socket?):

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

<Listener listener1>
        AllowIRC = true
        AllowWeb = false
        Host = 192.168.1.1
        IPv4 = true
        IPv6 = false
        Port = 31337
        SSL = true
        URIPrefix = /
</Listener>

<Listener listener2>
        AllowIRC = true
        AllowWeb = false
        Host = 2001:db8::
        IPv4 = false
        IPv6 = true
        Port = 1337
        SSL = false
        URIPrefix = /
</Listener>

<Listener listener3>
        AllowIRC = true
        AllowWeb = false
        Host = 2001:db8::
        IPv4 = false
        IPv6 = true
        Port = 31337
        SSL = true
        URIPrefix = /
</Listener>

Host = 192.168.1.1 and Port = 1337 tells ZNC to listen? on that IP address. You must replace 192.168.1.1 and 2001:db8:: with your real IP addresses and you must replace 1337 and 31337 with the ports you were given during account registration. If you don't use the correct IP address and port, ZNC may refuse to launch, or you may be unable to connect.

You can find your IP addresses by running host on your unique hostname:

$ host username.example.com
username.example.com has address 198.51.100.1
username.example.com has IPv6 address fe80:c001:d00d::

WARNING: You must replace 192.168.1.1 and 2001:db8:: with your real IP address, or znc will fail to launch.

Run ZNC

To start ZNC right away:

$ ~/.local/bin/znc >> ~/.znc/znc.log 2>&1 &

This will store all znc log messages to ~/.znc/znc.log. If ZNC fails to start or crashes, you can consult this file for the full error log.

Connecting to ZNC

From here, you will want to consult the ZNC client guides to see how to connect to ZNC.

Creating a cronjob

You will want to create a cronjob which will restart znc every 5 minutes in case it ever crashes.

Then, type:

$ crontab -e
*/5     *       *       *       *       ~/.local/bin/znc >> ~/.znc/znc.log 2>&1 &

NOTE: znc checks its own pid to see if it is running and quits if it is. Keep in mind this in mind when using cron to restart processes like this.

Troubleshooting

If you run into errors, check the error log in ~/.znc/znc.log, or turn on debugging:

~/.local/bin/znc -D