soju(1)
πΈ NAME πΈ
soju β IRC bouncer. Yep, this is the soju(1) manual page from the General Commands Manual, and we're gonna get you comfy with it, bestie. π
π¦ SYNOPSIS π¦
soju [options...]
π DESCRIPTION π
soju is a user-friendly IRC bouncer. It connects to upstream IRC servers on behalf of the user to provide extra features. Slay. β¨
- Multiple separate users sharing the same bouncer, each with their own upstream servers. π
- Sending the backlog (messages received while the user was disconnected from the bouncer), with per-client buffers. π¨
To connect to the bouncer, use the bouncer username and password. If your client doesn't support the soju.im/bouncer-networks IRC extension, setup one connection per server configured in soju, and indicate the network name in the username: <username>/<network>. Then channels can be joined and parted as if you were directly connected to the upstream server. π«Ά
For per-client history to work on clients which don't support the IRCv3 chathistory extension, clients need to indicate their name. This can be done by adding a @<client> suffix to the username. π
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. π
If a network specified in the username doesn't exist, and the network name is a valid hostname, the network will be automatically added. π¦
When all clients are disconnected from the bouncer, the user is automatically marked as away by default. π΄
soju will reload the configuration file, the TLS certificate/key and the MOTD file when it receives the HUP signal. The configuration options listen, db and log cannot be reloaded. β οΈ
Administrators can broadcast a message to all bouncer users via /notice $<hostname> <text>, or via /notice $* <text> if the connection isn't bound to a particular network. All currently connected bouncer users will receive the message from the special BouncerServ service. π£
π OPTIONS π
-h,-helpβ Show help message and quit. The classic escape hatch, bestie. πββοΈπ¨-config <path>β Path to the config file. If unset, a default config file is used. ποΈ-debugβ Enable debug logging (this will leak sensitive information such as passwords). This can be overriden at run time with the service commandserver debug.
π¨ Heads up: -debug will leak sensitive information such as passwords β treat that as the dramatic warning it is, bestie. π
-listen <uri>β Listening URI (default:":6697"). Can be specified multiple times. π
πΈ CONFIG FILE πΈ
ok so the config file is literally one directive per line, that's the whole vibe. nothing fancy. π
Example, bestie:
listen ircs://
tls cert.pem key.pem
hostname example.org
Here's every directive it supports, no cap:
listen <uri>β the listening URI (default:":6697").
These are the URIs you can use (each one is a whole mood tbh):
[ircs://][host][:port]listens with TLS over TCP (default port if omitted: 6697)irc://localhost[:port]listens with plain-text over TCP (default port if omitted: 6667, host must be"localhost")irc+insecure://[host][:port]listens with plain-text over TCP (default port if omitted: 6667)unix://<path>listens on a Unix domain sockethttps://[host][:port]listens for HTTPS connections (default port: 443) and handles the following requests:/socketfor WebSocket/uploads(and subdirectories) for file uploads
http://localhost[:port]listens for plain-text HTTP connections (default port: 80, host must be"localhost") and handles requests likehttps://doeshttp+insecure://[host][:port]listens for plain-text HTTP connections (default port: 80) and handles requests likehttps://doeshttp+unix://<path>listens for plain-text HTTP connections on a Unix domain socket and handles requests likehttps://doeswss://[host][:port]listens for WebSocket connections over TLS (default port: 443)ws://localhost[:port]listens for plain-text WebSocket connections (default port: 80, host must be"localhost")ws+insecure://[host][:port]listens for plain-text WebSocket connections (default port: 80)ws+unix://<path>listens for plain-text WebSocket connections on a Unix domain socketident://[host][:port]listens for plain-text ident connections (default port: 113)http+prometheus://localhost:<port>listens for plain-text HTTP connections and serves Prometheus metrics (host must be"localhost")http+insecure+prometheus://[host]:<port>listens for plain-text HTTP connections and serves Prometheus metricshttp+pprof://localhost:<port>listens for plain-text HTTP connections and serves pprof runtime profiling data (host must be"localhost"). For more information, see:https://pkg.go.dev/net/http/pprof.unix+admin://[path]listens on a Unix domain socket for administrative connections, such assojuctl(default path:/run/soju/admin)
If the scheme is omitted, ircs is assumed. and if you write multiple listen directives, soju will listen on each of them β she's multitasking, she contains multitudes. β¨
hostname <name>β server hostname (default: system hostname).
fr set this to a fully qualified domain name, okay? π
title <title>β server title. This gets sent as the ISUPPORTNETWORKvalue when clients don't select a specific network.icon <url>β server icon. Can be set to either a local path (in which case an HTTP listener must be set up) or a fullhttps://URL. This gets sent as the ISUPPORTdraft/ICONvalue when clients don't select a specific network. πtls <cert> <key>β enable TLS support. The certificate and the key files must be PEM-encoded. πdb <driver> <source>β set the database location for user, network and channel storage. By default, asqlite3database is opened in"./soju.db".
Supported drivers:
sqlite3expects source to be a path to the SQLite filepostgresexpects source to be a space-separated list ofkey=valueparameters, e.g.db postgres "host=/run/postgresql dbname=soju". Note thatsslmodedefaults torequire. For more information on connection strings, see:https://pkg.go.dev/github.com/lib/pq#hdr-Connection_String_Parameters.
message-store <driver> [source]β set the database location for IRC messages. By default,dbis used.
Supported drivers:
dbstores messages in the database. A full-text search index is used to speed up search queries.fsstores messages on disk, in the same format as ZNC. source 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. πmemorystores 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 chathistory extension and search.
(log is a deprecated alias for this directive.)
file-upload <driver> [source]β set the database location for uploaded files.
File upload requires setting up an HTTP listener (see https:// and http+insecure:// URIs in the listen directive).
Supported drivers:
fsstores uploaded files on disk. source is required.httpstores uploaded files through an external HTTP service. source 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 theSoju-Usernameheader. The HTTP server must respond with an HTTP 201 on success, with theLocationheader being set to the URL of the uploaded file.
http-origin <patterns...>β list of allowed HTTP origins for WebSocket listeners. The parameters are interpreted as shell patterns, seeglob(7).
By default, only the request host is authorized. Use this directive to enable cross-origin WebSockets.
http-ingress <url>β external URL on which HTTPS listeners are exposed.
By default, this is https://<hostname>.
accept-proxy-ip <cidr...>β 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, theForwardedHTTP header field defined in RFC 7239 or theX-Forwarded-*HTTP header fields). The special name"localhost"accepts the loopback addresses127.0.0.0/8and::1/128.
By default, all IPs are rejected. π
accept-proxy-unix true|falseβ allow proxy connections over Unix domain sockets. This is useful when running soju behind a reverse proxy such as Nginx and using Unix domain sockets for the upstream connections. Note that any local user with write permissions on the soju socket will be able to forge their connection origin when this option is enabled.
By default, proxy headers received over Unix domain sockets are untrusted.
max-user-networks <limit>β maximum number of enabled networks per user. By default, there is no limit.motd <path>β 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.upstream-user-ip <cidr...>β 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.
This can be useful to avoid having the whole bouncer banned from an upstream network because of one malicious user. literally protecting the whole friend group from one person's chaos. π
disable-inactive-user <duration>β disable inactive users after the specified duration.
A user is inactive when the last downstream connection is closed.
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.
message-expiry <duration>β automatically delete messages older than the specified duration.
The duration is a positive decimal number followed by the unit "d" (days). For instance, "30d" deletes messages with timestamps older than 30 days. Messages are deleted once per day.
Note: When using db sqlite and message-store db, SQLite does not automatically reclaim disk space after deletion. Run VACUUM manually to reclaim space.
By default, messages are kept indefinitely.
enable-user-on-auth true|falseβ enable users when they successfully authenticate.
This can be used together with disable-inactive-user to seamlessly disable and re-enable users during lengthy inactivity.
When external authentication is used (e.g. auth oauth2), bouncer users are automatically created after successful authentication.
auth <driver> ...β set the authentication method. By default, internal authentication is used.
Supported drivers:
auth internalβ Use internal authentication.auth http <url>β Use external HTTP basic authentication. An HTTP POST request is made against the URL, passing the user credentials in anAuthorizationBasic header. The credentials are considered valid on HTTP 200; invalid on HTTP 403; and any other error code means an error occured.auth oauth2 <url>β 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).auth pamβ Use PAM authentication.
client-cert-auth true|falseβ enable/disable client certificate authentication. By default, client certificate authentication is disabled because it bypasses external authentication methods and because it needs additional HTTP server configuration.
When used behind a TCP reverse proxy, client certification authentication needs the PROXY protocol to be used with PP2_SUBTYPE_SSL_CLIENT_CERT support. When used behind an HTTP reverse proxy, client certificate authentication needs the Client-Cert header field to be populated (RFC 9440).
Warning, enabling this option without proper HTTP reverse proxy support can result in broken setups where users can login but cannot upload files. π like they get in but the uploads are just gone. tragic.
π IRC SERVICE π
soju exposes an IRC service called BouncerServ to manage the bouncer. Commands can be sent via regular private messages β like this, bestie:
/msg BouncerServ <command> [args...]
Commands may be written in full or abbreviated form, for instance network can be abbreviated as net or just n. ok that's lowkey iconic, she's fluent in shorthand. π«Ά
okay so first things first, bestie: commands are parsed according to the POSIX shell rules. In particular, words can be quoted (via double or single quotes) and a backslash escapes the next character. π
π¬ help [command]
Show a list of commands. If command is specified, show a help message for the command. Iconic lilβ help desk behavior, honestly. π«Ά
π network create -addr <addr> [options...]
Connect to a new network at addr. -addr is mandatory. No cap, you cannot skip it.
addr supports several connection types:
[ircs://]<host>[:port]β connects with TLS over TCPirc+insecure://<host>[:port]β connects with plain-text TCPirc+unix:///<path>β connects to a Unix socket
For example, to connect to Libera Chat:
net create -addr irc.libera.chat
Other options are:
-name <name>β short network name. This will be used instead of addr to refer to the network.-username <username>β connect with the specified username. By default, the nickname is used.-pass <pass>β connect with the specified server password.-realname <realname>β connect with the specified real name. By default, the account's realname is used if set, otherwise the network's nickname is used.-certfp <fingerprint>β 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 isSHA512. An empty string removes any previous fingerprint.
The following command can be used to fetch the certificate fingerprint of an IRC server:
openssl s_client -connect irc.example.org:6697 -verify_quiet </dev/null | openssl x509 -fingerprint -sha512 -noout -in /dev/stdin
-nick <nickname>β connect with the specified nickname. By default, the account's username is used.-auto-away true|falseβ 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.-enabled true|falseβ enable or disable the network. If the network is disabled, the bouncer won't connect to it. By default, the network is enabled.-ignore-limit true|falseβ ignore the max networks limit for this command. Only admin users can ignore the limit.-connect-command <command>β 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.
For instance, to identify with NickServ, the following command can be used:
"PRIVMSG NickServ :IDENTIFY <password>"
The flag can be specified multiple times to send multiple IRC messages. To clear all commands, set it to the empty string.
π network update [name] [options...]
Update an existing network. The options are the same as the network create command. π
When this command is executed, soju will disconnect and re-connect to the network. Dramatic? Yes. Necessary? Also yes.
If name is not specified, the current network is updated.
ποΈ network delete [name]
Disconnect and delete a network. Bye bestie, we hardly knew ye. π
If name is not specified, the current network is deleted.
π¨ network quote [name] <command>
Send a raw IRC line as-is to a network. No editorializing, no rewriting, just vibes and bytes. π
If name is not specified, the command is sent to the current network.
π network status
Show a list of saved networks and their current status. Sneak peek energy. π
πΊ channel status [options...]
Show a list of saved channels and their current status.
Options:
-network <name>β only show channels for the specified network. By default, only the channels in the current network are displayed.
β¨ channel create <name> [options...]
Join a new channel.
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 user run. iykyk.
Options are:
-detached true|falseβ attach or detach this channel.
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.
-relay-detached <mode>β set when to relay messages from detached channels to the user with a BouncerServNOTICE.
Modes are:
messageβ relay any message from this channel when detached.highlightβ relay only messages mentioning you when detached.noneβ don't relay any messages from this channel when detached.defaultβ currently same ashighlight. This is the default behaviour.
-reattach-on <mode>β set when to automatically reattach to detached channels.
Modes are:
messageβ reattach to this channel when any message is received.highlightβ reattach to this channel when any message mentioning you is received.noneβ never automatically reattach to this channel.defaultβ currently same asnone. This is the default behaviour.
-detach-after <duration>β automatically detach this channel after the specified duration has elapsed without receving any message corresponding to-detach-on.
Example duration values: 1h30m, 30s, 2.5h.
Setting this value to 0 will disable this behaviour, i.e. this channel will never be automatically detached. This is the default behaviour.
-detach-on <mode>β set when to reset the auto-detach timer used by-detach-after, 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.
Modes are:
messageβ receiving any message from this channel will reset the auto-detach timer.highlightβ receiving any message mentioning you from this channel will reset the auto-detach timer.noneβ receiving messages from this channel will not reset the auto-detach timer. Sending messages or joining the channel will still reset the timer.defaultβ currently same asmessage. This is the default behaviour.
π οΈ channel update <name> [options...]
Update the options of an existing channel. The options are the same as the channel create command. Glow-up arc, but for channel settings. π
πͺ channel delete <name>
Leave and forget a channel. It's giving closure. π¦
πͺͺ device-certificate status
Show a list of saved device certificates. Cute lilβ certificate inventory. π
πͺͺ device-certificate create [options...]
Create a new device certificate.
Options are:
-fingerprint <fingerprint>β the device certificate fingerprint, as a hex-encodedSHA-512hash of the certificate. Optional, defaults to the current TLS client certificate, if any.-label <label>β a short name for the device certificate, used for display.
ποΈ device-certificate delete <fingerprint>
Delete a device certificate. RIP to that fingerprint. π
π certfp generate [options...]
Generate self-signed certificate and use it for authentication (via SASL EXTERNAL).
Generates a 3072-bit RSA private key by default.
Note, reconnection to the upstream network is required to use the newly generated certificate. Important bestie info, do not skip. β οΈ
Options are:
-network <name>β select a network. By default, the current network is selected, if any.-key-type <type>β private key algorithm to use. Valid values are:rsa,ecdsaanded25519.ecdsauses the NIST P-521 curve.-bits <bits>β size of RSA key to generate. Ignored for other key types.
π certfp fingerprint [options...]
Show SHA-1 and SHA-256 fingerprints for the certificate currently used with the network.
Options are:
-network <name>β select a network. By default, the current network is selected, if any.
π§ sasl status [options...]
Show current SASL status.
Options are:
-network <name>β select a network. By default, the current network is selected, if any.
π sasl set-plain [options...] <username> <password>
Set SASL PLAIN credentials.
Note, reconnection to the upstream network is required to apply the new settings.
Options are:
-network <name>β select a network. By default, the current network is selected, if any.
β»οΈ sasl reset [options...]
Disable SASL authentication and remove stored credentials.
Note, reconnection to the upstream network is required to apply the new settings.
Options are:
-network <name>β select a network. By default, the current network is selected, if any.
π₯ user status [username]
Show a list of users on this server. Only admins can query this information.
If username is specified, statistics are only displayed for this user. Main character filtering, honestly. β¨
π user create -username <username> -password <password> [options...]
Create a new soju user. Only admin users can create new accounts. The -username and -password flags are mandatory.
Options are:
-username <username>β the bouncer username. This cannot be changed after the user has been created.-password <password>β the bouncer password.-disable-passwordβ disable password authentication. The user will be unable to login.-admin true|falseβ make the new user an administrator.-nick <nick>β set the user's nickname. This is used as a fallback if there is no nickname set for a network.-realname <realname>β set the user's realname. This is used as a fallback if there is no realname set for a network.-enabled true|falseβ 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.-max-networks <max-networks>β caps how many enabled networks this user gets to have. set it to0and they get no networks at all (harsh but valid π), and-1means "just use the globalmax-user-networksconfig value, bestie".
user update [username] [options...]
Updates a user. the options are literally the same ones as the user create command, no new lore.
if you leave username out, the current user gets updated. and only admins can update other users, obvs.
okay so not every flag is valid in every context β read the vibe check below:
- The
-usernameflag is never valid, because usernames are immutable. they're frozen. carved in stone. periodt. πͺ¨ - The
-nickand-realnameflags are only valid when you're updating the current user. - The
-admin,-enabledand-max_networksflags are only valid when you're updating another user.
user delete <username> [confirmation token]
Deletes a soju user. poof, gone π«§
only admins can delete other users.
user run <username> <command...>
Executes a command as another user. main character energy, but for someone else β¨
only admins can use this command, sorry bestie.
server status
Shows some bouncer statistics. ngl it's the dashboard moment. only admins can query this information.
server notice <message>
Broadcasts a notice. every single currently connected bouncer user will get the message from the special BouncerServ service π’ only admins can broadcast a notice.
server debug <true|false>
Enables/disables debug logging. this overrides any value passed to soju in -debug.
β οΈ okay so real talk: this will leak sensitive information. it's giving "don't do this in prod with people around". you've been warned, bestie π¨
π AUTHORS π
Maintained by Simon Ser <contact@emersion.fr>, who is assisted by other open-source contributors. for more info about soju development, see <https://soju.im>. iconic behavior honestly π«Ά
π¦ SEE ALSO π¦
sojuctl(1)β go read it, iykyk π
and that's a wrap on the whole page, bestie!! πΈ this is the 2026-09-25 edition of the soju(1) manual page β go forth and bounce responsibly πβ¨π
π¦ where this page comes from
- arch rolling: soju 0.11.1-1 Β· AGPL-3.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms