.Dd July 6, 2020 .Dt POUNCE 1 .Os . .Sh NAME .Nm pounce .Nd IRC bouncer . .Sh SYNOPSIS .Nm .Op Fl NTev .Op Fl A Ar cert .Op Fl C Ar cert .Op Fl H Ar host .Op Fl K Ar priv .Op Fl P Ar port .Op Fl Q Ar time .Op Fl R Ar caps .Op Fl S Ar bind .Op Fl U Ar unix .Op Fl W Ar pass .Op Fl a Ar auth .Op Fl c Ar cert .Op Fl f Ar save .Op Fl h Ar host .Op Fl j Ar join .Op Fl k Ar priv .Op Fl n Ar nick .Op Fl p Ar port .Op Fl q Ar quit .Op Fl r Ar real .Op Fl s Ar size .Op Fl u Ar user .Op Fl w Ar pass .Op Fl y Ar away .Op Ar config ... . .Nm .Op Fl A Ar ca .Fl g Ar cert . .Nm .Fl x . .Sh DESCRIPTION The .Nm 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 .Sy server-time extension is used to indicate when messages were originally received. . .Pp One instance of .Nm must be configured for each IRC network. Instances of .Nm must either use different local ports with .Fl P or different local hosts with .Fl H and .Fl U to be dispatched from the same port by .Xr calico 1 . . .Pp TLS certificates can be automatically loaded from .Pa /usr/local/etc/letsencrypt (or equivalent) based on the local host set by .Fl H . These certificates can be obtained using .Xr certbot 8 . . .Pp Clients must uniquely identify themselves to .Nm by their IRC username. See .Sx Client Configuration for details. . .Pp Options can be loaded from files listed on the command line. Each option is placed on a line, and lines beginning with .Ql # are ignored. The options are listed below following their corresponding flags. . .Pp The arguments are as follows: . .Bl -tag -width Ds .It Fl A Ar path , Cm local-ca = Ar path Require clients to authenticate using a TLS client certificate signed by the certificate authority loaded from .Ar path . See .Sx Generating Client Certificates . If .Fl W is also set, clients may instead authenticate with a server password. . .It Fl C Ar path , Cm local-cert = Ar path Load TLS certificate from .Ar path . The default path is the .Xr certbot 8 path for the .Ar host set by .Fl H . . .It Fl H Ar host , Cm local-host = Ar host Bind to .Ar host . The default host is localhost. . .It Fl K Ar path , Cm local-priv = Ar path Load TLS private key from .Ar path . The default path is the .Xr certbot 8 path for the .Ar host set by .Fl H . . .It Fl N , Cm no-names Do not request .Ql NAMES for each channel when a client connects. This avoids already connected clients receiving unsolicited responses but prevents new clients from populating user lists. . .It Fl P Ar port , Cm local-port = Ar port Bind to .Ar port . The default port is 6697. . .It Fl Q Ar ms , Cm queue-interval = Ar ms Set the server send queue interval in milliseconds. The queue is only used for automated messages sent by .Nm . Messages from clients are sent to the server immediately. The default interval is 200 milliseconds. . .It Fl R Ar caps , Cm blind-req = Ar caps Blindly request the IRCv3 capabilities .Ar caps . This can be used to enable hidden capabilities, such as .Sy userhost-in-names on freenode. . .It Fl S Ar host , Cm bind = Ar host Bind to source address .Ar host when connecting to the server. . .It Fl T Do not advertise a strict transport security (STS) policy to clients. . .It Fl U Ar path , Cm local-path = Ar path Bind to a UNIX-domain socket at .Ar path . Clients are only accepted as dispatched by .Xr calico 1 . If .Ar path is a directory, the .Ar host set by .Fl H is appended to it. This option takes precedence over .Fl H and .Fl P . . .It Fl W Ar pass , Cm local-pass = Ar pass Require the server password .Ar pass for clients to connect. The .Ar pass string must be hashed using .Fl x . If .Fl A is also set, clients may instead authenticate using a TLS client certificate. . .It Fl a Ar user : Ns Ar pass , Cm sasl-plain = Ar user : Ns Ar pass Authenticate as .Ar user with .Ar pass using SASL PLAIN. Since this method requires the account password in plaintext, it is recommended to use SASL EXTERNAL instead with .Fl e . . .It Fl c Ar path , Cm client-cert = Ar path Load the TLS client certificate from .Ar path . If the private key is in a separate file, it is loaded with .Fl k . With .Fl e , authenticate using SASL EXTERNAL. Certificates can be generated with .Fl g . . .It Fl e , Cm sasl-external Authenticate using SASL EXTERNAL, also known as CertFP. The TLS client certificate is loaded with .Fl c . See .Sx Configuring CertFP . . .It Fl f Ar path , Cm save = Ar path Load the contents of the buffer from .Ar path , if it exists, and truncate it. On shutdown, save the contents of the buffer to .Ar path . . .It Fl g Ar path Generate a TLS client certificate using .Xr openssl 1 and write it to .Ar path . The certificate is signed by the certificate authority if .Fl A is set, otherwise it is self-signed. . .It Fl h Ar host , Cm host = Ar host Connect to .Ar host . . .It Fl j Ar chan , Cm join = Ar chan Join the comma-separated list of .Ar chan . . .It Fl k Ar path , Cm client-priv = Ar path Load the TLS client private key from .Ar path . . .It Fl n Ar nick , Cm nick = Ar nick Set nickname to .Ar nick . The default nickname is the user's name. . .It Fl p Ar port , Cm port = Ar port Connect to .Ar port . The default port is 6697. . .It Fl q Ar mesg , Cm quit = Ar mesg Quit with message .Ar mesg when shutting down. . .It Fl r Ar real , Cm real = Ar real Set realname to .Ar real . The default realname is the same as the nickname. . .It Fl s Ar size , Cm size = Ar size Set the number of messages contained in the buffer to .Ar size . The size must be a power of two. The default size is 4096. . .It Fl u Ar user , Cm user = Ar user Set username to .Ar user . The default username is the same as the nickname. . .It Fl v , Cm verbose Write IRC messages to standard error in the following colors: .Pp .Bl -tag -width Ds -compact .It red from .Nm to the server .It green from the server to .Nm .It yellow from clients to .Nm .It blue from .Nm to clients .El . .It Fl w Ar pass , Cm pass = Ar pass Log in with the server password .Ar pass . . .It Fl x Prompt for a password and output a hash for use with .Fl W . . .It Fl y Ar mesg , Cm away = Ar mesg Set away status to .Ar mesg when no clients are connected. .El . .Pp Client connections are not accepted until successful login to the server. If the server connection is lost, the .Nm daemon exits. . .Pp Upon receiving the .Dv SIGUSR1 signal, the certificate and private key will be reloaded from the paths specified by .Fl C and .Fl K . . .Ss Client Configuration Clients should be configured to connect to the host and port set by .Fl H and .Fl P , with TLS or SSL enabled. If .Fl W is used, clients must send a server password. If .Fl 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. . .Pp 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. . .Pp Clients which request the .Sy causal.agency/passive capability or with usernames beginning with hyphen .Ql - are considered passive and do not affect automatic away status. . .Pp Pass-through of the following IRCv3 capabilities is supported: .Sy account-notify , .Sy account-tag , .Sy away-notify , .Sy batch , .Sy cap-notify , .Sy chghost , .Sy extended-join , .Sy invite-notify , .Sy labeled-response , .Sy message-tags , .Sy multi-prefix , .Sy server-time , .Sy setname , .Sy userhost-in-names . . .Pp Private messages and notices sent to the user's own nickname are relayed only to other clients, not to the server. . .Ss Generating Client Certificates .Bl -enum .It Generate a self-signed certificate authority (CA): .Bd -literal -offset indent pounce -g auth.pem .Ed .It Generate and sign client certificates using the CA: .Bd -literal -offset indent pounce -A auth.pem -g client1.pem pounce -A auth.pem -g client2.pem .Ed .It Since only the public key is needed for certificate verification, extract it from the CA: .Bd -literal -offset indent openssl x509 -in auth.pem -out auth.crt .Ed .It Configure .Nm to verify client certificates against the CA: .Bd -literal -offset indent local-ca = auth.crt # or: pounce -A auth.crt .Ed .El . .Ss Configuring CertFP .Bl -enum .It Generate a new TLS client certificate: .Bd -literal -offset indent pounce -g example.pem .Ed .It Connect to the server using the certificate: .Bd -literal -offset indent client-cert = example.pem # or: pounce -c example.pem .Ed .It Identify with services or use .Cm sasl-plain , then add the certificate fingerprint to your account: .Bd -literal -offset indent /msg NickServ CERT ADD .Ed .It Enable SASL EXTERNAL to require successful authentication when connecting: .Bd -literal -offset indent client-cert = example.pem sasl-external # or: pounce -e -c example.pem .Ed .El . .Ss Service Configuration Add the following to .Pa /etc/rc.conf to enable the .Nm daemon: .Bd -literal -offset indent pounce_enable="YES" .Ed . .Pp By default, the .Nm daemon is started in the .Pa /usr/local/etc/pounce directory. Configuration files in that location can be loaded by setting .Va pounce_flags : .Bd -literal -offset indent pounce_flags="example.conf" .Ed . .Pp The .Nm service supports profiles for running multiple instances. Set .Va pounce_profiles to a space-separated list of names. Flags for each profile will be set from .Va pounce_${profile}_flags . For example: .Bd -literal -offset indent pounce_profiles="example1 example2" pounce_example1_flags="example1.conf" pounce_example2_flags="example2.conf" .Ed . .Pp The commands .Cm start , stop , etc.\& will operate on the profile given as an additional argument, or on all profiles without an additional argument. . .Pp The .Cm reload command will cause the .Nm daemon to reload certificate files. To reload other configuration, use the .Cm restart command. . .Sh ENVIRONMENT .Bl -tag -width Ds .It Ev USER The default nickname. .El . .Sh EXAMPLES Obtain a certificate and start .Nm : .Bd -literal -offset indent certbot certonly -d pounce.example.org pounce -H pounce.example.org -h chat.freenode.net -j '#ascii.town' .Ed . .Pp Equivalent configuration file: .Bd -literal -offset indent local-host = pounce.example.org host = chat.freenode.net join = #ascii.town .Ed . .Sh SEE ALSO .Xr calico 1 . .Sh STANDARDS .Bl -item .It .Rs .%R RFC 2812 .%A C. Kalt .%T Internet Relay Chat: Client Protocol .%I IETF .%D April 2000 .%U https://tools.ietf.org/html/rfc2812 .Re . .It .Rs .%R RFC 4616 .%A K. Zeilenga, Ed. .%T The PLAIN Simple Authentication and Security Layer (SASL) Mechanism .%I IETF .%D August 2006 .%U https://tools.ietf.org/html/rfc4616 .Re . .It .Rs .%A S. Josefsson .%T The Base16, Base32, and Base64 Data Encodings .%I IETF .%R RFC 4648 .%D October 2006 .%U https://tools.ietf.org/html/rfc4648 .Re . .It .Rs .%A Attila Molnar .%A James Wheare .%T IRCv3 Strict Transport Security .%I IRCv3 Working Group .%U https://ircv3.net/specs/extensions/sts .Re . .It .Rs .%A Attila Molnar .%A William Pitcock .%T IRCv3.2 SASL Authentication .%I IRCv3 Working Group .%U https://ircv3.net/specs/extensions/sasl-3.2 .Re . .It .Rs .%A Kevin L. Mitchell .%A Perry Lorier .%A Lee Hardy .%A William Pitcock .%A Attila Molnar .%A Daniel Oakley .%A James Wheare .%T IRCv3 Client Capability Negotiation .%I IRCv3 Working Group .%U https://ircv3.net/specs/core/capability-negotiation .Re . .It .Rs .%A St\('ephan Kochen .%A Alexey Sokolov .%A Kyle Fuller .%A James Wheare .%T IRCv3.2 server-time Extension .%I IRCv3 Working Group .%U https://ircv3.net/specs/extensions/server-time-3.2 .Re .El . .Ss Extensions The .Sy causal.agency/consumer vendor-specific IRCv3 capability enables the .Sy 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.\& .Ql @causal.agency/pos=42069 . This capability may be requested with the value of the last .Sy causal.agency/pos tag received by the client, e.g.\& .Ql 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. . .Pp .%T IRCv3 Client Capability Negotiation specifies that capabilities MAY have values in .Ql CAP LS or .Ql CAP NEW responses. It does not, however, indicate if .Ql CAP REQ capabilities MUST NOT have values. The .Nm daemon parses .Ql CAP REQ values in the same way as .Ql CAP LS values. . .Pp The .Sy causal.agency/passive vendor-specific IRCv3 capability indicates that a client should not affect the automatic away status. . .Sh AUTHORS .An June Bug Aq Mt june@causal.agency . .Sh CAVEATS One instance of .Nm is required for each server connection. The .Nm daemon must be restarted if the server connection is lost. . .Pp The .Nm daemon makes no distinction between channels. Elevated activity in one channel may push messages from a quieter channel out of the buffer. . .Sh BUGS Send mail to .Aq Mt list+pounce@causal.agency or join .Li #ascii.town on .Li chat.freenode.net . . .Pp 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.