.\" Generated by scdoc 1.11.4 .\" Complete documentation for this program is not available as a GNU info page .ie \n(.g .ds Aq \(aq .el .ds Aq ' .nh .ad l .\" Begin generated content: .TH "soju" "1" "2025-11-13" .PP .SH NAME .PP soju - IRC bouncer .PP .SH SYNOPSIS .PP \fBsoju\fR [options.\&.\&.\&] .PP .SH DESCRIPTION .PP soju is a user-friendly IRC bouncer.\& It connects to upstream IRC servers on behalf of the user to provide extra features.\& .PP .PD 0 .IP \(bu 4 Multiple separate users sharing the same bouncer, each with their own upstream servers .IP \(bu 4 Sending the backlog (messages received while the user was disconnected from the bouncer), with per-client buffers .PD .PP To connect to the bouncer, use the bouncer username and password.\& To use a client which doesn'\&t support the \fIsoju.\&im/bouncer-networks\fR IRC extension, setup one connection per server configured in soju, and indicate the network name in the username: "/".\& Then channels can be joined and parted as if you were directly connected to the upstream server.\& .PP For per-client history to work on clients which don'\&t support the IRCv3 \fIchathistory\fR extension, clients need to indicate their name.\& This can be done by adding a "@" suffix to the username.\& .PP When joining a channel, the channel will be saved and automatically joined on the next connection.\& When registering or authenticating with NickServ, the credentials will be saved and automatically used on the next connection if the server supports SASL.\& When parting a channel with the reason "detach", the channel will be detached instead of being left.\& .PP If a network specified in the username doesn'\&t exist, and the network name is a valid hostname, the network will be automatically added.\& .PP When all clients are disconnected from the bouncer, the user is automatically marked as away by default.\& .PP soju will reload the configuration file, the TLS certificate/key and the MOTD file when it receives the HUP signal.\& The configuration options \fIlisten\fR, \fIdb\fR and \fIlog\fR cannot be reloaded.\& .PP Administrators can broadcast a message to all bouncer users via \fI/notice $ \fR, or via \fI/notice $* \fR if the connection isn'\&t bound to a particular network.\& All currently connected bouncer users will receive the message from the special \fIBouncerServ\fR service.\& .PP .SH OPTIONS .PP \fB-h, -help\fR .RS 4 Show help message and quit.\& .PP .RE \fB-config\fR .RS 4 Path to the config file.\& If unset, a default config file is used.\& .PP .RE \fB-debug\fR .RS 4 Enable debug logging (this will leak sensitive information such as passwords).\& This can be overriden at run time with the service command \fIserver debug\fR.\& .PP .RE \fB-listen\fR .RS 4 Listening URI (default: ":6697").\& Can be specified multiple times.\& .PP .RE .SH CONFIG FILE .PP The config file has one directive per line.\& .PP Example: .PP .nf .RS 4 listen ircs:// tls cert\&.pem key\&.pem hostname example\&.org .fi .RE .PP The following directives are supported: .PP \fBlisten\fR .RS 4 Listening URI (default: ":6697").\& .PP The following URIs are supported: .PP .PD 0 .IP \(bu 4 \fI[ircs://][host][:port]\fR listens with TLS over TCP (default port if omitted: 6697) .IP \(bu 4 \fIirc://localhost[:port]\fR listens with plain-text over TCP (default port if omitted: 6667, host must be "localhost") .IP \(bu 4 \fIirc+insecure://[host][:port]\fR listens with plain-text over TCP (default port if omitted: 6667) .IP \(bu 4 \fIunix://\fR listens on a Unix domain socket .IP \(bu 4 \fIhttps://[host][:port]\fR listens for HTTPS connections (default port: 443) and handles the following requests: .RS 4 .IP \(bu 4 \fI/socket\fR for WebSocket .IP \(bu 4 \fI/uploads\fR (and subdirectories) for file uploads .RE .IP \(bu 4 \fIhttp://localhost[:port]\fR listens for plain-text HTTP connections (default port: 80, host must be "localhost") and handles requests like \fIhttps://\fR does .IP \(bu 4 \fIhttp+insecure://[host][:port]\fR listens for plain-text HTTP connections (default port: 80) and handles requests like \fIhttps://\fR does .IP \(bu 4 \fIhttp+unix://\fR listens for plain-text HTTP connections on a Unix domain socket and handles requests like \fIhttps://\fR does .IP \(bu 4 \fIwss://[host][:port]\fR listens for WebSocket connections over TLS (default port: 443) .IP \(bu 4 \fIws://localhost[:port]\fR listens for plain-text WebSocket connections (default port: 80, host must be "localhost") .IP \(bu 4 \fIws+insecure://[host][:port]\fR listens for plain-text WebSocket connections (default port: 80) .IP \(bu 4 \fIws+unix://\fR listens for plain-text WebSocket connections on a Unix domain socket .IP \(bu 4 \fIident://[host][:port]\fR listens for plain-text ident connections (default port: 113) .IP \(bu 4 \fIhttp+prometheus://localhost:\fR listens for plain-text HTTP connections and serves Prometheus metrics (host must be "localhost") .IP \(bu 4 \fIhttp+pprof://localhost:\fR listens for plain-text HTTP connections and serves pprof runtime profiling data (host must be "localhost").\& For more information, see: .\& .IP \(bu 4 \fIunix+admin://[path]\fR listens on a Unix domain socket for administrative connections, such as sojuctl (default path: /run/soju/admin) .PD .PP If the scheme is omitted, "ircs" is assumed.\& If multiple \fBlisten\fR directives are specified, soju will listen on each of them.\& .PP .RE \fBhostname\fR .RS 4 Server hostname (default: system hostname).\& .PP This should be set to a fully qualified domain name.\& .PP .RE \fBtitle\fR .RS 4 Server title.\& This will be sent as the \fIISUPPORT NETWORK\fR value when clients don'\&t select a specific network.\& .PP .RE \fBtls\fR <cert> <key> .RS 4 Enable TLS support.\& The certificate and the key files must be PEM-encoded.\& .PP .RE \fBdb\fR <driver> <source> .RS 4 Set the database location for user, network and channel storage.\& By default, a \fIsqlite3\fR database is opened in ".\&/soju.\&db".\& .PP Supported drivers: .PP .PD 0 .IP \(bu 4 \fIsqlite3\fR expects \fIsource\fR to be a path to the SQLite file .IP \(bu 4 \fIpostgres\fR expects \fIsource\fR to be a space-separated list of \fIkey=value\fR parameters, e.\&g.\& \fIdb postgres "host=/run/postgresql dbname=soju"\fR.\& Note that \fIsslmode\fR defaults to \fIrequire\fR.\& For more information on connection strings, see: <https://pkg.\&go.\&dev/github.\&com/lib/pq#hdr-Connection_String_Parameters>.\& .PD .PP .RE \fBmessage-store\fR <driver> [source] .RS 4 Set the database location for IRC messages.\& By default, \fIdb\fR is used.\& .PP Supported drivers: .PP .PD 0 .IP \(bu 4 \fIdb\fR stores messages in the database.\& A full-text search index is used to speed up search queries.\& .IP \(bu 4 \fIfs\fR stores messages on disk, in the same format as ZNC.\& \fIsource\fR is required and is the root directory path for the database.\& This on-disk format is lossy: some IRCv3 messages (e.\&g.\& TAGMSG) and all message tags are discarded.\& .IP \(bu 4 \fImemory\fR stores messages in memory.\& For each channel/user, only the latest 4K messages are kept in memory, older messages are discarded.\& This driver is very basic and doesn'\&t support features such as the \fIchathistory\fR extension and search.\& .PD .PP (\fIlog\fR is a deprecated alias for this directive.\&) .PP .RE \fBfile-upload\fR <driver> [source] .RS 4 Set the database location for uploaded files.\& .PP File upload requires setting up an HTTP listener (see \fIhttps://\fR and \fIhttp+insecure://\fR URIs in the \fIlisten\fR directive).\& .PP Supported drivers: .PP .PD 0 .IP \(bu 4 \fIfs\fR stores uploaded files on disk.\& \fIsource\fR is required.\& .IP \(bu 4 \fIhttp\fR stores uploaded files through an external HTTP service.\& \fIsource\fR is required and must be an HTTP URL.\& When receiving a file, soju will send an HTTP POST request to that URL, sending the file as is in the HTTP request body; additionally sending the uploader soju username in the \fISoju-Username\fR header.\& The HTTP server must respond with an HTTP 201 on success, with the \fILocation\fR header being set to the URL of the uploaded file.\& .PD .PP .RE \fBhttp-origin\fR <patterns.\&.\&.\&> .RS 4 List of allowed HTTP origins for WebSocket listeners.\& The parameters are interpreted as shell patterns, see \fBglob\fR(7).\& .PP By default, only the request host is authorized.\& Use this directive to enable cross-origin WebSockets.\& .PP .RE \fBhttp-ingress\fR <url> .RS 4 External URL on which HTTPS listeners are exposed.\& .PP By default, this is \fIhttps://<hostname>\fR.\& .PP .RE \fBaccept-proxy-ip\fR <cidr.\&.\&.\&> .RS 4 Allow the specified IPs to act as a proxy.\& Proxys have the ability to overwrite the remote and local connection addresses (via the PROXY protocol, the Forwarded HTTP header field defined in RFC 7239 or the X-Forwarded-* HTTP header fields).\& The special name "localhost" accepts the loopback addresses 127.\&0.\&0.\&0/8 and ::1/128.\& .PP By default, all IPs are rejected.\& .PP .RE \fBmax-user-networks\fR <limit> .RS 4 Maximum number of enabled networks per user.\& By default, there is no limit.\& .PP .RE \fBmotd\fR <path> .RS 4 Path to the MOTD file.\& The bouncer MOTD is sent to clients which aren'\&t bound to a specific network.\& By default, no MOTD is sent.\& .PP .RE \fBupstream-user-ip\fR <cidr.\&.\&.\&> .RS 4 Enable per-user IP addresses.\& One IPv4 range and/or one IPv6 range can be specified in CIDR notation.\& One IP address per range will be assigned to each user and will be used as the source address when connecting to an upstream network.\& .PP This can be useful to avoid having the whole bouncer banned from an upstream network because of one malicious user.\& .PP .RE \fBdisable-inactive-user\fR <duration> .RS 4 Disable inactive users after the specified duration.\& .PP A user is inactive when the last downstream connection is closed.\& .PP The duration is a positive decimal number followed by the unit "d" (days).\& For instance, "30d" disables users 30 days after they last disconnect from the bouncer.\& .PP .RE \fBenable-user-on-auth\fR true|false .RS 4 Enable users when they successfully authenticate.\& .PP This can be used together with \fIdisable-inactive-user\fR to seamlessly disable and re-enable users during lengthy inactivity.\& .PP When external authentication is used (e.\&g.\& \fIauth oauth2\fR), bouncer users are automatically created after successful authentication.\& .PP .RE \fBauth\fR <driver> .\&.\&.\& .RS 4 Set the authentication method.\& By default, internal authentication is used.\& .PP Supported drivers: .PP \fBauth internal\fR .RS 4 Use internal authentication.\& .RE \fBauth http\fR <url> .RS 4 Use external HTTP basic authentication.\& An HTTP request is made against the URL, passing the user credentials in an Authorization Basic header.\& The credentials are considered valid on HTTP 200; invalid on HTTP 403; and any other error code means an error occured.\& .RE \fBauth oauth2\fR <url> .RS 4 Use external OAuth 2.\&0 authentication.\& The authorization server URL must be provided.\& The client ID and client secret can be provided as username and password in the URL.\& The authorization server must support OAuth 2.\&0 Authorization Server Metadata (RFC 8414) and OAuth 2.\&0 Token Introspection (RFC 7662).\& .RE \fBauth pam\fR .RS 4 Use PAM authentication.\& .PP .RE .RE .SH IRC SERVICE .PP soju exposes an IRC service called \fBBouncerServ\fR to manage the bouncer.\& Commands can be sent via regular private messages (\fI/msg BouncerServ <command> [args.\&.\&.\&]\fR).\& Commands may be written in full or abbreviated form, for instance \fBnetwork\fR can be abbreviated as \fBnet\fR or just \fBn\fR.\& .PP Commands are parsed according the POSIX shell rules.\& In particular, words can be quoted (via double or single quotes) and a backslash escapes the next character.\& .PP \fBhelp\fR [command] .RS 4 Show a list of commands.\& If \fIcommand\fR is specified, show a help message for the command.\& .PP .RE \fBnetwork create\fR \fB-addr\fR <addr> [options.\&.\&.\&] .RS 4 Connect to a new network at \fIaddr\fR.\& \fI-addr\fR is mandatory.\& .PP \fIaddr\fR supports several connection types: .PP .PD 0 .IP \(bu 4 \fI[ircs://]<host>[:port]\fR connects with TLS over TCP .IP \(bu 4 \fIirc+insecure://<host>[:port]\fR connects with plain-text TCP .IP \(bu 4 \fIirc+unix:///<path>\fR connects to a Unix socket .PD .PP For example, to connect to Libera Chat: .PP .nf .RS 4 net create -addr irc\&.libera\&.chat .fi .RE .PP Other options are: .PP \fB-name\fR <name> .RS 4 Short network name.\& This will be used instead of \fIaddr\fR to refer to the network.\& .PP .RE \fB-username\fR <username> .RS 4 Connect with the specified username.\& By default, the nickname is used.\& .PP .RE \fB-pass\fR <pass> .RS 4 Connect with the specified server password.\& .PP .RE \fB-realname\fR <realname> .RS 4 Connect with the specified real name.\& By default, the account'\&s realname is used if set, otherwise the network'\&s nickname is used.\& .PP .RE \fB-certfp\fR <fingerprint> .RS 4 Instead of using certificate authorities to check the server'\&s TLS certificate, check whether the server certificate matches the provided fingerprint.\& This can be used to connect to servers using self-signed certificates.\& The fingerprint format is SHA512.\& An empty string removes any previous fingerprint.\& .PP The following command can be used to fetch the certificate fingerprint of an IRC server: .PP .nf .RS 4 openssl s_client -connect irc\&.example\&.org:6697 -verify_quiet </dev/null | openssl x509 -fingerprint -sha512 -noout -in /dev/stdin .fi .RE .PP .RE \fB-nick\fR <nickname> .RS 4 Connect with the specified nickname.\& By default, the account'\&s username is used.\& .PP .RE \fB-auto-away\fR true|false .RS 4 Enable or disable the auto-away feature.\& If the feature is enabled, the user will be marked as away when all clients are disconnected from the bouncer.\& By default, auto-away is enabled.\& .PP .RE \fB-enabled\fR true|false .RS 4 Enable or disable the network.\& If the network is disabled, the bouncer won'\&t connect to it.\& By default, the network is enabled.\& .PP .RE \fB-ignore-limit\fR true|false .RS 4 Ignore the max networks limit for this command.\& Only admin users can ignore the limit.\& .PP .RE \fB-connect-command\fR <command> .RS 4 Send the specified quoted string as a raw IRC command right after connecting to the server.\& This can be used to identify to an account when the server doesn'\&t support SASL.\& .PP For instance, to identify with \fINickServ\fR, the following command can be used: .PP .nf .RS 4 "PRIVMSG NickServ :IDENTIFY <password>" .fi .RE .PP The flag can be specified multiple times to send multiple IRC messages.\& To clear all commands, set it to the empty string.\& .PP .RE .RE \fBnetwork update\fR [name] [options.\&.\&.\&] .RS 4 Update an existing network.\& The options are the same as the \fInetwork create\fR command.\& .PP When this command is executed, soju will disconnect and re-connect to the network.\& .PP If \fIname\fR is not specified, the current network is updated.\& .PP .RE \fBnetwork delete\fR [name] .RS 4 Disconnect and delete a network.\& .PP If \fIname\fR is not specified, the current network is deleted.\& .PP .RE \fBnetwork quote\fR [name] <command> .RS 4 Send a raw IRC line as-is to a network.\& .PP If \fIname\fR is not specified, the command is sent to the current network.\& .PP .RE \fBnetwork status\fR .RS 4 Show a list of saved networks and their current status.\& .PP .RE \fBchannel status\fR [options.\&.\&.\&] .RS 4 Show a list of saved channels and their current status.\& .PP Options: .PP \fB-network\fR <name> .RS 4 Only show channels for the specified network.\& By default, only the channels in the current network are displayed.\& .PP .RE .RE \fBchannel create\fR <name> [options.\&.\&.\&] .RS 4 Join a new channel.\& .PP Joining a channel should usually be done with a simple join from the client, but this command can be used to join another user to a channel when used with \fIuser run\fR.\& .PP Options are: .PP \fB-detached\fR true|false .RS 4 Attach or detach this channel.\& .PP A detached channel is joined but is hidden by the bouncer.\& This is useful to e.\&g.\& collect logs and highlights in low-interest or high-traffic channels.\& .PP .RE \fB-relay-detached\fR <mode> .RS 4 Set when to relay messages from detached channels to the user with a BouncerServ NOTICE.\& .PP Modes are: .PP \fBmessage\fR .RS 4 Relay any message from this channel when detached.\& .PP .RE \fBhighlight\fR .RS 4 Relay only messages mentioning you when detached.\& .PP .RE \fBnone\fR .RS 4 Don'\&t relay any messages from this channel when detached.\& .PP .RE \fBdefault\fR .RS 4 Currently same as \fBhighlight\fR.\& This is the default behaviour.\& .PP .RE .RE \fB-reattach-on\fR <mode> .RS 4 Set when to automatically reattach to detached channels.\& .PP Modes are: .PP \fBmessage\fR .RS 4 Reattach to this channel when any message is received.\& .PP .RE \fBhighlight\fR .RS 4 Reattach to this channel when any message mentioning you is received.\& .PP .RE \fBnone\fR .RS 4 Never automatically reattach to this channel.\& .PP .RE \fBdefault\fR .RS 4 Currently same as \fBnone\fR.\& This is the default behaviour.\& .PP .RE .RE \fB-detach-after\fR <duration> .RS 4 Automatically detach this channel after the specified duration has elapsed without receving any message corresponding to \fB-detach-on\fR.\& .PP Example duration values: \fB1h30m\fR, \fB30s\fR, \fB2.\&5h\fR.\& .PP Setting this value to 0 will disable this behaviour, i.\&e.\& this channel will never be automatically detached.\& This is the default behaviour.\& .PP .RE \fB-detach-on\fR <mode> .RS 4 Set when to reset the auto-detach timer used by \fB-detach-after\fR, causing it to wait again for the auto-detach duration timer before detaching.\& Joining, reattaching, sending a message, or changing any channel option will reset the timer, in addition to the messages specified by the mode.\& .PP Modes are: .PP \fBmessage\fR .RS 4 Receiving any message from this channel will reset the auto-detach timer.\& .PP .RE \fBhighlight\fR .RS 4 Receiving any message mentioning you from this channel will reset the auto-detach timer.\& .PP .RE \fBnone\fR .RS 4 Receiving messages from this channel will not reset the auto-detach timer.\& Sending messages or joining the channel will still reset the timer.\& .PP .RE \fBdefault\fR .RS 4 Currently same as \fBmessage\fR.\& This is the default behaviour.\& .PP .RE .RE .RE \fBchannel update\fR <name> [options.\&.\&.\&] .RS 4 Update the options of an existing channel.\& The options are the same as the \fInetwork create\fR command.\& .PP .RE \fBchannel delete\fR <name> .RS 4 Leave and forget a channel.\& .PP .RE \fBcertfp generate\fR [options.\&.\&.\&] .RS 4 Generate self-signed certificate and use it for authentication (via SASL EXTERNAL).\& .PP Generates a 3072-bit RSA private key by default.\& .PP Note, reconnection to the upstream network is required to use the newly generated certificate.\& .PP Options are: .PP \fB-network\fR <name> .RS 4 Select a network.\& By default, the current network is selected, if any.\& .PP .RE \fB-key-type\fR <type> .RS 4 Private key algorithm to use.\& Valid values are: \fIrsa\fR, \fIecdsa\fR and \fIed25519\fR.\& \fIecdsa\fR uses the NIST P-521 curve.\& .PP .RE \fB-bits\fR <bits> .RS 4 Size of RSA key to generate.\& Ignored for other key types.\& .PP .RE .RE \fBcertfp fingerprint\fR [options.\&.\&.\&] .RS 4 Show SHA-1 and SHA-256 fingerprints for the certificate currently used with the network.\& .PP Options are: .PP \fB-network\fR <name> .RS 4 Select a network.\& By default, the current network is selected, if any.\& .PP .RE .RE \fBsasl status\fR [options.\&.\&.\&] .RS 4 Show current SASL status.\& .PP Options are: .PP \fB-network\fR <name> .RS 4 Select a network.\& By default, the current network is selected, if any.\& .PP .RE .RE \fBsasl set-plain\fR [options.\&.\&.\&] <username> <password> .RS 4 Set SASL PLAIN credentials.\& .PP Note, reconnection to the upstream network is required to apply the new settings.\& .PP Options are: .PP \fB-network\fR <name> .RS 4 Select a network.\& By default, the current network is selected, if any.\& .PP .RE .RE \fBsasl reset\fR [options.\&.\&.\&] .RS 4 Disable SASL authentication and remove stored credentials.\& .PP Note, reconnection to the upstream network is required to apply the new settings.\& .PP Options are: .PP \fB-network\fR <name> .RS 4 Select a network.\& By default, the current network is selected, if any.\& .PP .RE .RE \fBuser status\fR [username] .RS 4 Show a list of users on this server.\& Only admins can query this information.\& .PP If \fIusername\fR is specified, statistics are only displayed for this user.\& .PP .RE \fBuser create\fR -username <username> -password <password> [options.\&.\&.\&] .RS 4 Create a new soju user.\& Only admin users can create new accounts.\& The \fI-username\fR and \fI-password\fR flags are mandatory.\& .PP Options are: .PP \fB-username\fR <username> .RS 4 The bouncer username.\& This cannot be changed after the user has been created.\& .PP .RE \fB-password\fR <password> .RS 4 The bouncer password.\& .PP .RE \fB-disable-password\fR .RS 4 Disable password authentication.\& The user will be unable to login.\& .PP .RE \fB-admin\fR true|false .RS 4 Make the new user an administrator.\& .PP .RE \fB-nick\fR <nick> .RS 4 Set the user'\&s nickname.\& This is used as a fallback if there is no nickname set for a network.\& .PP .RE \fB-realname\fR <realname> .RS 4 Set the user'\&s realname.\& This is used as a fallback if there is no realname set for a network.\& .PP .RE \fB-enabled\fR true|false .RS 4 Enable or disable the user.\& If the user is disabled, the bouncer will not connect to any of their networks, and downstream connections will be immediately closed.\& By default, users are enabled.\& .PP .RE \fB-max-networks\fR <max-networks> .RS 4 Set a limit on the number of enabled networks this user can use.\& A limit of 0 means no network, and -1 means to default to the global \fImax-user-networks\fR configuration value.\& .PP .RE .RE \fBuser update\fR [username] [options.\&.\&.\&] .RS 4 Update a user.\& The options are the same as the \fIuser create\fR command.\& .PP If \fIusername\fR is omitted, the current user is updated.\& Only admins can update other users.\& .PP Not all flags are valid in all contexts: .PP .PD 0 .IP \(bu 4 The \fI-username\fR flag is never valid, usernames are immutable.\& .IP \(bu 4 The \fI-nick\fR and \fI-realname\fR flag are only valid when updating the current user.\& .IP \(bu 4 The \fI-admin\fR, \fI-enabled\fR and \fI-max_networks\fR flags are only valid when updating another user.\& .PD .PP .RE \fBuser delete\fR <username> [confirmation token] .RS 4 Delete a soju user.\& .PP Only admins can delete other users.\& .PP .RE \fBuser run\fR <username> <command.\&.\&.\&> .RS 4 Execute a command as another user.\& .PP Only admins can use this command.\& .PP .RE \fBserver status\fR .RS 4 Show some bouncer statistics.\& Only admins can query this information.\& .PP .RE \fBserver notice\fR <message> .RS 4 Broadcast a notice.\& All currently connected bouncer users will receive the message from the special \fIBouncerServ\fR service.\& Only admins can broadcast a notice.\& .PP .RE \fBserver debug\fR <true|false> .RS 4 Enable/disable debug logging (this will leak sensitive information).\& This overrides any value passed to soju in \fI-debug\fR.\& .PP .RE .SH AUTHORS .PP Maintained by Simon Ser <contact@emersion.\&fr>, who is assisted by other open-source contributors.\& For more information about soju development, see <https://soju.\&im>.\& .PP .SH SEE ALSO .PP \fBsojuctl\fR(1)