IRCNow

Streamlining file management

Justification

  • Let's Encrypt certificates automatically expires every 90 days. This means you should ideally have a cron job to automatically renew the certificate(s), and it also means that you need to have them copied into respective directories.
    • If you happen to have ACOPM setup to use TLS, it too will need its certificate regenerated. This can leave quite a chore for the things to do every so often.
  • Copying ngircd.conf from /etc/ngircd into /var/ngircd/etc/ngircd whenever the configuration is updated, that it has gone through sanity checks (doas ngircd -t), and, you don't want to do repeat this copying procedure each and every time you want changes to effect a currently running ngircd instance.

Pre-requisites

  • You have a cron tab set for renewing Let's Encrypt certs following this guide.
    • Needless to say, you have either multiple cron tabs or a single cron tab pointing to a shell script for handling the propagation of renewed Let's Encrypt certificate. Automatically copying the certificates into places where it is needed, and reloading daemons that are affected by it.
  • Optionally and ideally, you have OCSP stapling setup within your cron tab.

Procedure

Move /etc/ngircd/ngircd.conf into /var/ngircd/etc/ngircd, assuming the changes you made in /etc/ngircd/ngircd.conf satisfactorily meets doas ngircd -t tests, and, you are content with any of the new changes,

$ doas mv /etc/ngircd/ngircd.conf /var/ngircd/etc/ngircd

Create a symbolic link from /var/ngircd/etc/ngircd/ngircd.conf into /etc/ngircd as /etc/ngircd/ngircd.conf,

$ doas ln -s /var/ngircd/etc/ngircd/ngircd.conf /etc/ngircd/ngircd.conf

Do the same for every file that is within /var/ngircd and that there is already an exact copy outside of the chrooted ngircd directory. The following below is for Let's Encrypt certificates,

$ doas mv /etc/ngircd/example.com.fullchain.pem /var/ngircd/etc/ngircd
$ doas ln -s /var/ngircd/etc/ngircd/example.com.fullchain.pem /etc/ngircd/example.com.fullchain.pem
$ doas mv /etc/ngircd/example.com.key /var/ngircd/etc/ngircd
$ doas ln -s /var/ngircd/etc/ngircd/example.com.key /etc/ngircd/example.com.key

man ln if in doubt.

Log redirection and rotation

Justification

  • When servers on your network have links to each other, it can quickly fill up /var/log/messages, thus increasing its overall size, for instance.
  • Sifting through /var/log/messages, which is commonly used to store logs from other daemons can be an annoyance. Especially when you are keeping an eye out on ngircd messages.
  • You are curious to know how large of a log file can get from seeing ngircd related messages, even if in compressed form.

Pre-requisites

In general

  • You are using syslogd. Other logging daemons like syslog-ng are not covered within this topic.
  • Your /etc/ngircd/ngircd.conf ServerUID and ServerGID are set as defaults; _ngircd. That, and it is not marked as a comment. If you have not properly setup your ngircd to make use of chroot, this topic on log redirection and rotation is not suitable yet for you.
  • Your SyslogFacility under /etc/ngircd/ngircd.conf is set to local1. That, and it is also not marked as a comment.

Condition specifics

These only apply when you want to retain existing ngircd logged outputs into its own file. If you do not care about historical data, you can simply skip reading this.

  • Your ngircd should be ideally turned off.
  • You bear any/all loss(es) from performing an experimental method. This is especially true if you do not wish to turn your ngircd off.

Configuration

/etc/syslog.conf

This basically more or less follows a mailing list response for ''relayd''. In your /etc/syslog.conf, you will need to have these lines at the top of the file,

#       $OpenBSD: syslog.conf,v 1.20 2016/12/27 13:38:14 jca Exp $
#

!!ngircd
local1.*                                                /var/log/ngircd
!*
...

If this wasn't at the top of the /etc/syslog.conf, messages coming from ngircd will be trapped and processed by any preceding rules before it. Therefore it must be at the top to override any other subsequent rules.

Create an empty file named ngircd inside /var/log

$ doas touch /var/log/ngircd

Change ownership of the file so that even a chrooted ngircd can still access it. Assuming defaults within /etc/ngircd/ngircd.conf,

$ doas chown _ngircd:_ngircd /var/log/ngircd

Change file permissions so that it isn't others/world readable/writable/executable,

$ doas chmod 660 /var/log/ngircd

Historical log segregation

You can skip this section if you do not wish to segregate historical ngircd log(s) from /var/log/messages. The following methods are experimental, and are considered as risky!

Extract all traces of ngircd from all of /var/log/messages* including those that has been compressed due to /etc/newsyslog.conf,

$ zgrep ngircd /var/log/messages* | doas tee -a /var/log/ngircd

Manually and optionally, remove traces of ngircd messages from within /var/log/messages,

$ doas mv /var/log/messages /var/log/messages.orig ; doas sed '/ngircd/d' /var/log/messages.orig > /var/log/messages ; doas rm /var/log/messages.orig

This does not work against already archived /var/log/messages which are gzipped in the form of /var/log/messages.0.gz for example. For those cases, they require some due ingenuity in deleting traces of it.

Here is a possible example on how to proceed with archived /var/log/messages*,

$ doas gzip -d /var/log/messages.0.gz ; doas mv /var/log/messages.0 /var/log/messages.0.orig ; doas sed '/ngircd/d' /var/log/messages.0.orig > /var/log/messages.0 ; doas rm /var/log/messages.0.orig ; doas gzip -9 /var/log/messages.0

Which might be able to be shorted into something like this,

$ doas gzcat /var/log/messages.0.gz | sed '/ngircd/d' | doas tee /var/log/messages.0 ; doas rm /var/log/messages.0.gz ; doas gzip -9 /var/log/messages.0

If you have more than one of these archived /var/log/messages.0.gz, such as /var/log/messages.1.gz, /var/log/messages.2.gz, and so on, you may want to try repeating the procedure as outlined above, but with caution. Alternatively, and again, with some intuition, it might be possible to semi-automate this without needing to repeat the same command, just with different filenames, over and over again. I will not cover this part of the topic, as I have not personally experienced dealing with it.

/etc/newsyslog.conf

If you want your ngircd logs to be rotated, thus be compressed to save space, you will need to append the following into your /etc/newsyslog.conf,

/var/log/ngircd         _ngircd:_ngircd 660  7     *    $W0   Z

Where,

# logfile_name          owner:group     mode count size when  flags

Means the following:

  • logfile_name points to the file it needs to look for and sets it as the base name,
  • owner:group sets ownership of the files,
  • mode sets the file permissions,
  • count sets to keep however many archived copies of,
  • size sets the file size logfile_name is allowed to have before compressing,
  • when sets the interval, in which this case it is weekly,
  • flags sets what to do with the logs, in this case Z means to compress (via gzip),

See the man page for more information.

Compiling ngIRCd with ident and/or other options

Justification

  • The pre-packaged ngIRCd (version 25 as of writing), does not have either ident or PAM support,
  • The pre-packaged ngIRCd, will complain about ServerUID/GID being a mismatch (recompiling only gets rid of ServerGID line),
  • There is a need to test, install new features. Compiling and installing from source is deemed unacceptable.

Pre-requisites

  • You need to understand how to make full use of OpenBSD ports system.

Procedure

Create a new directory named myports under /usr/ports,

$ mkdir /usr/ports/myports

Copy the contents of net/ngircd into myports,

$ cp -R /usr/ports/net/ngircd /usr/ports/myports

Within the contents of Makefile under /usr/ports/myports/ngircd, have the following,

# $OpenBSD: Makefile,v 1.19 2020/02/24 10:30:16 solene Exp $

COMMENT =       lightweight irc server

DISTNAME =      ngircd-25

REVISION =      2-alpha

CATEGORIES =    myports

HOMEPAGE =      https://ngircd.barton.de/

MAINTAINER =    Giannis Tsaraias <tsg@openbsd.org>

# GPLv2
PERMIT_PACKAGE =        Yes

# use pledge()
WANTLIB =       c crypto iconv ssl z

MASTER_SITES =  http://ngircd.barton.de/pub/ngircd/ \
                http://ngircd.mirror.3rz.org/pub/ngircd/

LIB_DEPENDS =   converters/libiconv security/libident

BUILD_DEPENDS = security/libident

TEST_DEPENDS =  lang/expect \
                ${BASE_PKGPATH}

SYSCONFDIR =    ${BASESYSCONFDIR}/ngircd

CONFIGURE_STYLE = gnu
CONFIGURE_ARGS += --with-iconv=${LOCALBASE} \
                  --with-openssl \
                  --enable-ipv6 \
                  --with-ident=${LOCALBASE} \
                  --sysconfdir=/etc/ngircd \
                  --mandir=/usr/local/man

.include <bsd.port.mk>

Follow the rest of the OpenBSD FAQ ports page on how to compile, install your custom package ngIRCd.

SSL migration

Justification

  • SSL enabled servers are not linked up via SSL in server-to-server (s2s) links.
    • This poses as a security issue when ngircd is deployed across WAN/internet, due to IRC communication sent over plain text, like how this article is written, instead of being encrypted.
    • There is a misconception that assumes SSL signed servers automatically grants SSL S2S.
    • Deployment of SSL S2S has overall thus been slow.

Background

Let's assume there's two ngircd servers peered with each other right now. Server A is named as irc.foo.org and Server B is named as irc.bar.org. When connected to say irc.foo.org, and one executes the following command as IRC user,

/trace

They will see something like the following,

Link ngIRCd-25 irc.foo.org irc.foo.org VFz 100101 0 0
[irc.foo.org] Serv 1 0S 0C irc.bar.org[unknown@127.0.0.2] *!*irc.foo.org VFz
[irc.foo.org] irc.foo.org ngIRCd-25. End of TRACE

The letters VFz means a lot of things. For now, we will skip over the letters V and F, as there's not enough documentation on what they are. z

Server-Server-Links koennen nun komprimiert werden, dazu wird die zlib (www.zlib.org) benoetigt. Unterstuetzt die Gegenseite die Komprimierung nicht, wird automatisch unkomprimiert kommuniziert. Das Verfahren ist kompatibel mit dem Original-ircd 2.10.3, d.h. beide Server koennen miteinander ueber komprimiert Links kommunizieren.

https://gitlab.com/ngircd/ngircd/blob/master/ChangeLog#L1849 In English, it would roughly translate as,

Server-server links can now be compressed, which requires the zlib (www.zlib.org). If the other side does not support compression, communication is automatically uncompressed. The process is compatible with the original ircd 2.10.3, i.e. both servers can communicate with each other via compressed links.

Now if it was VFsz, we know that the link between irc.foo.org and irc.bar.org has SSL,

Show connection flag “s” (SSL) in RPL_TRACE{LINK|SERVER} messages: now you can check if a server-to-server link is SSL-encrypted or not using the IRC “TRACE” command.

https://gitlab.com/ngircd/ngircd/blob/master/ChangeLog#L544

The repeat of /trace command above would have been something like the following, assuming irc.bar.org has SSL connection to irc.foo.org,

Link ngIRCd-25 irc.foo.org irc.foo.org VFz 100101 0 0
[irc.foo.org] Serv 1 0S 0C irc.bar.org[unknown@127.0.0.2] *!*irc.foo.org VFsz
[irc.foo.org] irc.foo.org ngIRCd-25. End of TRACE

In a IRC network that has multiple servers linked to each other, where some of them have SSL S2S connections, and others don't. You will see a very mixed overview with /trace command.

Pre-requisites

  • You will need to make use of Group = key inside ngircd.conf.
  • Depending on the severity or the scale on the network, you may need to also enforce Passive = yes key inside of ngircd.conf, especially on servers that does not have SSL S2S capability.

Procedure

Assuming you have five (5) servers in your network, some has SSL enabled on ngircd, the rest doesn't. Assume the following server names:

  • irc.foo.org
  • irc.bar.org
  • irc.baz.org
  • irc.blah.org
  • irc.example.org

Now, assume each of the following servers has server links to each other, irc.foo.org has the following,

[Server]
        Name = irc.bar.org
        Port = 6697
        MyPassword = OQGpksaFt4MJFVCyPAxj5xtHwSiZa
        PeerPassword = DSXv29Fpz4BuD3A7uzu8MAtKpJnBz
        SSLConnect = yes

[Server]
        Name = irc.baz.org
        Port = 6667
        MyPassword = OQGpksaFt4MJFVCyPAxj5xtHwSiZa
        PeerPassword = de290kQTlzMGwqAvH9l7Aqf6TzrsY

[Server]
        Name = irc.blah.org
        Port = 6667
        MyPassword = OQGpksaFt4MJFVCyPAxj5xtHwSiZa
        PeerPassword = 52pQawGcNOiGK1zJn46zTWSf4eTBe

[Server]
        Name = irc.example.org
        Port = 6667
        MyPassword = OQGpksaFt4MJFVCyPAxj5xtHwSiZa
        PeerPassword = CWomEefu3bHDNdfdbEbdAdPPzF7q1

Server irc.bar.org has the following,

[Server]
        Name = irc.foo.org
        Port = 6697
        MyPassword = DSXv29Fpz4BuD3A7uzu8MAtKpJnBz
        PeerPassword = OQGpksaFt4MJFVCyPAxj5xtHwSiZa
        SSLConnect = yes

[Server]
        Name = irc.baz.org
        Port = 6667
        MyPassword = DSXv29Fpz4BuD3A7uzu8MAtKpJnBz
        PeerPassword = de290kQTlzMGwqAvH9l7Aqf6TzrsY

[Server]
        Name = irc.blah.org
        Port = 6667
        MyPassword = DSXv29Fpz4BuD3A7uzu8MAtKpJnBz
        PeerPassword = 52pQawGcNOiGK1zJn46zTWSf4eTBe

[Server]
        Name = irc.example.org
        Port = 6667
        MyPassword = DSXv29Fpz4BuD3A7uzu8MAtKpJnBz
        PeerPassword = CWomEefu3bHDNdfdbEbdAdPPzF7q1

Server irc.baz.org has the following,

[Server]
        Name = irc.foo.org
        Port = 6697
        MyPassword = de290kQTlzMGwqAvH9l7Aqf6TzrsY
        PeerPassword = OQGpksaFt4MJFVCyPAxj5xtHwSiZa
        SSLConnect = yes

[Server]
        Name = irc.bar.org
        Port = 6697
        MyPassword = de290kQTlzMGwqAvH9l7Aqf6TzrsY
        PeerPassword = DSXv29Fpz4BuD3A7uzu8MAtKpJnBz
        SSLConnect = yes

[Server]
        Name = irc.blah.org
        Port = 6667
        MyPassword = de290kQTlzMGwqAvH9l7Aqf6TzrsY
        PeerPassword = 52pQawGcNOiGK1zJn46zTWSf4eTBe

[Server]
        Name = irc.example.org
        Port = 6667
        MyPassword = de290kQTlzMGwqAvH9l7Aqf6TzrsY
        PeerPassword = CWomEefu3bHDNdfdbEbdAdPPzF7q1

And so on, and so forth. Hopefully by now you should see the pattern. For those that don't,

  • irc.foo.org and irc.bar.org has SSL capabilities,
  • irc.baz.org, irc.blah.org, and irc.example.org does not have SSL capabilities,
  • Port = 6667 is used for plaintext communication, Port = 6697 is used for SSL communication,
  • SSL enabled server communications has the extra line SSLConnect = yes explicitly implied, the same likewise,
  • non-SSL capable servers has the SSLConnect = yes omitted,
  • Each of the servers uses the same MyPassword to identify and connect to each other. This is an obvious security flaw but it is illustrated for simplicity sake.

Both Group and Passive are optional keys within ngircd.conf. Without either of these set,

  • Group defaults to nothing, and server grouping features is disabled; every server is treated the same group within the server list,
  • Passive defaults to no, meaning that each of the servers within the server block will try to make an effort to link to two of them in a Spanning Tree Protocol (STP)-like layout. If set to yes to any/all of the servers in the server block(s), it will not automatically connect to those servers.

Group takes in an ID which is an integer/number, it does not accept alphabetical characters or any other characters other than digits. We want to make use of Group because ngircd will try to connect to at least two of the grouped servers that shares the same number. Servers that are grouped in with different numbers will be dealt with separately, or at least that is the hypothesis.

Meanwhile Passive is temporarily used to give precedence over those that has SSL enabled ports. It has other uses, but for this scenario, we are going to use it to force SSL servers to be connected before non-SSL servers.

Putting all these into perspective, here is how the prior example would be laid out, with both Group and Passive explicitly implied, Server irc.foo.org has the following,

[Server]
        Name = irc.bar.org
        Port = 6697
        MyPassword = OQGpksaFt4MJFVCyPAxj5xtHwSiZa
        PeerPassword = DSXv29Fpz4BuD3A7uzu8MAtKpJnBz
        SSLConnect = yes
        Group = 0
        Passive = no

[Server]
        Name = irc.baz.org
        Port = 6667
        MyPassword = OQGpksaFt4MJFVCyPAxj5xtHwSiZa
        PeerPassword = de290kQTlzMGwqAvH9l7Aqf6TzrsY
        Group = 9
        Passive = yes

[Server]
        Name = irc.blah.org
        Port = 6667
        MyPassword = OQGpksaFt4MJFVCyPAxj5xtHwSiZa
        PeerPassword = 52pQawGcNOiGK1zJn46zTWSf4eTBe
        Group = 9
        Passive = yes

[Server]
        Name = irc.example.org
        Port = 6667
        MyPassword = OQGpksaFt4MJFVCyPAxj5xtHwSiZa
        PeerPassword = CWomEefu3bHDNdfdbEbdAdPPzF7q1
        Group = 9
        Passive = yes

Server irc.bar.org has the following,

[Server]
        Name = irc.foo.org
        Port = 6697
        MyPassword = DSXv29Fpz4BuD3A7uzu8MAtKpJnBz
        PeerPassword = OQGpksaFt4MJFVCyPAxj5xtHwSiZa
        SSLConnect = yes
        Group = 0
        Passive = no

[Server]
        Name = irc.baz.org
        Port = 6667
        MyPassword = DSXv29Fpz4BuD3A7uzu8MAtKpJnBz
        PeerPassword = de290kQTlzMGwqAvH9l7Aqf6TzrsY
        Group = 9
        Passive = yes

[Server]
        Name = irc.blah.org
        Port = 6667
        MyPassword = DSXv29Fpz4BuD3A7uzu8MAtKpJnBz
        PeerPassword = 52pQawGcNOiGK1zJn46zTWSf4eTBe
        Group = 9
        Passive = yes

[Server]
        Name = irc.example.org
        Port = 6667
        MyPassword = DSXv29Fpz4BuD3A7uzu8MAtKpJnBz
        PeerPassword = CWomEefu3bHDNdfdbEbdAdPPzF7q1
        Group = 9
        Passive = yes

Server irc.baz.org has the following,

[Server]
        Name = irc.foo.org
        Port = 6697
        MyPassword = de290kQTlzMGwqAvH9l7Aqf6TzrsY
        PeerPassword = OQGpksaFt4MJFVCyPAxj5xtHwSiZa
        SSLConnect = yes
        Group = 0
        Passive = no

[Server]
        Name = irc.bar.org
        Port = 6697
        MyPassword = de290kQTlzMGwqAvH9l7Aqf6TzrsY
        PeerPassword = DSXv29Fpz4BuD3A7uzu8MAtKpJnBz
        SSLConnect = yes
        Group = 0
        Passive = no

[Server]
        Name = irc.blah.org
        Port = 6667
        MyPassword = de290kQTlzMGwqAvH9l7Aqf6TzrsY
        PeerPassword = 52pQawGcNOiGK1zJn46zTWSf4eTBe
        Group = 9
        Passive = yes

[Server]
        Name = irc.example.org
        Port = 6667
        MyPassword = de290kQTlzMGwqAvH9l7Aqf6TzrsY
        PeerPassword = CWomEefu3bHDNdfdbEbdAdPPzF7q1
        Group = 9
        Passive = yes

Once set, all of these servers needs to either be rehashed or restarted. Depending on whether or not if your ngircd has been properly configured for chroot.