POUNCE(1) FreeBSD General Commands Manual POUNCE(1)

IRC bouncer

pounce [-LNTev] [-A cert] [-C cert] [-H host] [-K priv] [-P port] [-Q time] [-R caps] [-S bind] [-U unix] [-W pass] [-a auth] [-c cert] [-f save] [-h host] [-j join] [-k priv] [-n nick] [-p port] [-q quit] [-r real] [-s size] [-u user] [-w pass] [-y away] [config ...]

pounce [-A ca] -g cert

pounce -x

The pounce daemon is a multi-client, TLS-only IRC bouncer. It maintains a persistent connection to an IRC server while allowing clients to connect and disconnect, receiving messages that were missed upon reconnection. The IRCv3.2 server-time extension is used to indicate when messages were originally received.

One instance of pounce must be configured for each IRC network. Instances of pounce must either use different local ports with -P or different local hosts with -H and -U to be dispatched from the same port by calico(1).

TLS certificates can be automatically loaded from /usr/local/etc/letsencrypt (or equivalent) based on the local host set by -H. These certificates can be obtained using certbot(8).

Clients must uniquely identify themselves to pounce by their IRC username. See Client Configuration for details.

Options can be loaded from files listed on the command line. Files are searched for in $XDG_CONFIG_DIRS/pounce unless the path starts with ‘/’ or ‘.’. Certificate and private key paths are searched for in the same manner. Each option is placed on a line, and lines beginning with ‘#’ are ignored. The options are listed below following their corresponding flags.

The arguments are as follows:

path, local-ca = path
Require clients to authenticate using a TLS client certificate signed by the certificate authority loaded from path. See Generating Client Certificates. If -W is also set, clients may instead authenticate with a server password.
path, local-cert = path
Load TLS certificate from path. The default path is the certbot(8) path for the host set by -H.
host, local-host = host
Bind to host. The default host is localhost.
path, local-priv = path
Load TLS private key from path. The default path is the certbot(8) path for the host set by -H.
, palaver
Advertise the palaverapp.com IRCv3 vendor-specific capability to clients. This option only enables the capability; push notifications must be provided by the pounce-palaver(1) special-purpose client.
, no-names
Do not request ‘NAMES’ for each channel when a client connects. This avoids already connected clients receiving unsolicited responses but prevents new clients from populating user lists.
port, local-port = port
Bind to port. The default port is 6697.
ms, queue-interval = ms
Set the server send queue interval in milliseconds. The queue is only used for automated messages sent by pounce. Messages from clients are sent to the server immediately. The default interval is 200 milliseconds.
caps, blind-req = caps
Blindly request the IRCv3 capabilities caps. This can be used to enable hidden capabilities, such as userhost-in-names on freenode.
host, bind = host
Bind to source address host when connecting to the server.
, no-sts
Do not advertise a strict transport security (STS) policy to clients.
path, local-path = path
Bind to a UNIX-domain socket at path. Clients are only accepted as dispatched by calico(1). If path is a directory, the host set by -H is appended to it. This option takes precedence over -H and -P.
pass, local-pass = pass
Require the server password pass for clients to connect. The pass string must be hashed using -x. If -A is also set, clients may instead authenticate using a TLS client certificate.
user:pass, sasl-plain = user:pass
Authenticate as user with pass using SASL PLAIN. Since this method requires the account password in plaintext, it is recommended to use SASL EXTERNAL instead with -e.
path, client-cert = path
Load the TLS client certificate from path. If the private key is in a separate file, it is loaded with -k. With -e, authenticate using SASL EXTERNAL. Certificates can be generated with -g.
, sasl-external
Authenticate using SASL EXTERNAL, also known as CertFP. The TLS client certificate is loaded with -c. See Configuring CertFP.
path, save = path
Load and save the contents of the buffer from path in $XDG_DATA_DIRS/pounce, or an absolute or relative path if path starts with ‘/’ or ‘.’. The file is truncated after loading.
Generate a TLS client certificate using openssl(1) and write it to path. The certificate is signed by the certificate authority if -A is set, otherwise it is self-signed.
host, host = host
Connect to host.
chan, join = chan
Join the comma-separated list of chan.
path, client-priv = path
Load the TLS client private key from path.
nick, nick = nick
Set nickname to nick. The default nickname is the user's name.
port, port = port
Connect to port. The default port is 6697.
mesg, quit = mesg
Quit with message mesg when shutting down.
real, real = real
Set realname to real. The default realname is the same as the nickname.
size, size = size
Set the number of messages contained in the buffer to size. The size must be a power of two. The default size is 4096.
user, user = user
Set username to user. The default username is the same as the nickname.
, verbose
Write IRC messages to standard error in the following colors:

from pounce to the server
from the server to pounce
from clients to pounce
from pounce to clients
pass, pass = pass
Log in with the server password pass.
Prompt for a password and output a hash for use with -W.
mesg, away = mesg
Set away status to mesg when no clients are connected.

Client connections are not accepted until successful login to the server. If the server connection is lost, the pounce daemon exits.

Upon receiving the SIGUSR1 signal, the certificate, private key and local CA will be reloaded from the paths specified by -C, -K and -A.

Clients should be configured to connect to the host and port set by -H and -P, with TLS or SSL enabled. If -W is used, clients must send a server password. If -A is used, clients must connect with a client certificate and may request SASL EXTERNAL. If both are used, clients may authenticate with either method.

Clients must register with unique usernames, for example the name of the client software or location from which it is connecting. New clients with the same username are assumed to be reconnections and will cause previous connections to stop receiving messages. The nickname and real name sent by clients are ignored.

Clients which request the causal.agency/passive capability or with usernames beginning with hyphen ‘-’ are considered passive and do not affect automatic away status.

Pass-through of the following IRCv3 capabilities is supported: account-notify, account-tag, away-notify, batch, cap-notify, chghost, extended-join, invite-notify, labeled-response, message-tags, multi-prefix, server-time, setname, userhost-in-names.

Private messages and notices sent to the user's own nickname are relayed only to other clients, not to the server.

  1. Generate self-signed client certificates and private keys:
    pounce -g client1.pem
    pounce -g client2.pem
  2. Concatenate the certificate public keys into a CA file:
    openssl x509 -subject -in client1.pem >> ~/.config/pounce/auth.pem
    openssl x509 -subject -in client2.pem >> ~/.config/pounce/auth.pem
  3. Configure pounce to verify client certificates against the CA file:
    local-ca = auth.pem
    # or: pounce -A auth.pem

Alternatively, client certificates can be signed by a generated certificate authority:

  1. Generate a self-signed certificate authority:
    pounce -g auth.pem
  2. Generate and sign client certificates using the CA:
    pounce -A auth.pem -g client1.pem
    pounce -A auth.pem -g client2.pem
  3. Since only the public key is needed for certificate verification, extract it from the CA:
    openssl x509 -in auth.pem -out ~/.config/pounce/auth.crt
  4. Configure pounce to verify client certificates against the CA:
    local-ca = auth.crt
    # or: pounce -A auth.crt

  1. Generate a new TLS client certificate:
    pounce -g ~/.config/pounce/example.pem
  2. Connect to the server using the certificate:
    client-cert = example.pem
    # or: pounce -c example.pem
  3. Identify with services or use sasl-plain, then add the certificate fingerprint to your account:
    /msg NickServ CERT ADD
  4. Enable SASL EXTERNAL to require successful authentication when connecting:
    client-cert = example.pem
    # or: pounce -e -c example.pem

The default nickname.

Configuration files, certificates and private keys are searched for first in $XDG_CONFIG_HOME, usually ~/.config, followed by the colon-separated list of paths $XDG_CONFIG_DIRS, usually /etc/xdg.
The most likely location of configuration files.
Save files are searched for first in $XDG_DATA_HOME, usually ~/.local/share, followed by the colon-separated list of paths $XDG_DATA_DIRS, usually /usr/local/share:/usr/share. New save files are created in $XDG_DATA_HOME.
The most likely location of save files.

Obtain a certificate and make its private key available to pounce:
sudo certbot certonly -d irc.example.org
sudo chown :$USER /etc/letsencrypt/live/irc.example.org/privkey.pem
sudo chmod g+r /etc/letsencrypt/live/irc.example.org/privkey.pem

Start pounce:

pounce -H irc.example.org -h chat.freenode.net -j '#ascii.town'

Equivalent configuration file:

local-host = irc.example.org
host = chat.freenode.net
join = #ascii.town


The causal.agency/consumer vendor-specific IRCv3 capability enables the causal.agency/pos message tag. The value of this tag is a 64-bit unsigned integer indicating the consumer position of the client after receiving each message, e.g. ‘@causal.agency/pos=42069’. This capability may be requested with the value of the last causal.agency/pos tag received by the client, e.g. ‘CAP REQ causal.agency/consumer=42069’, setting its consumer position. By persisting this value across connections, a client can ensure no messages are missed, even in case of network issues or application crashes.

IRCv3 Client Capability Negotiation specifies that capabilities MAY have values in ‘CAP LS’ or ‘CAP NEW’ responses. It does not, however, indicate if ‘CAP REQ’ capabilities MUST NOT have values. The pounce daemon parses ‘CAP REQ’ values in the same way as ‘CAP LS’ values.

The causal.agency/passive vendor-specific IRCv3 capability indicates that a client should not affect the automatic away status.

June Bug <june@causal.agency>

One instance of pounce is required for each server connection. The pounce daemon must be restarted if the server connection is lost.

The pounce daemon makes no distinction between channels. Elevated activity in one channel may push messages from a quieter channel out of the buffer.

Send mail to <list+pounce@causal.agency> or join #ascii.town on chat.freenode.net.

A client will sometimes receive its own message, causing it to be displayed twice. This happens when a message is sent while responses are not yet consumed.

August 28, 2020 FreeBSD 12.1-RELEASE-p10