Files
bouncer/docs/USAGE.md
user a58848395c docs: rewrite all documentation for stealth connect and current state
Update README, PROJECT, ROADMAP, TASKS, TODO, USAGE, CHEATSHEET,
INSTALL, and DEBUG to reflect stealth connect, probation window,
markov nick generation, local DNS resolution, and multi-IP failover.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 18:31:20 +01:00

4.9 KiB

Usage

Starting the Bouncer

bouncer -c config/bouncer.toml -v
Flag Description
-c, --config PATH Config file (default: config/bouncer.toml)
-v, --verbose Debug logging
--version Show version

Connection Lifecycle

The bouncer goes through several states when connecting to an IRC server:

DISCONNECTED -> CONNECTING -> REGISTERING -> PROBATION -> READY
                    |              |              |
                    `--------------+--------------'
                         (failure = reconnect)

1. Stealth Registration

On connect, the bouncer registers with a random identity:

  • Nick: pronounceable markov-generated word (e.g., heliagu, crewo, midon)
  • User/Ident: random pronounceable word
  • Realname: random capitalized word

No fixed prefix or pattern -- each attempt looks like a different person.

2. Probation (15 seconds)

After registration succeeds (001 RPL_WELCOME), the bouncer enters a 15-second probation window. During this time it watches for:

  • ERROR messages (K-line, ban)
  • Server closing the connection

If the connection drops during probation, the bouncer reconnects with a fresh random identity and tries again.

3. Ready

Once probation passes without incident:

  1. Bouncer switches to your configured nick (NICK mynick)
  2. Joins configured channels (if autojoin = true)
  3. Begins relaying messages to/from connected clients

4. Reconnection

On any disconnection, the bouncer reconnects with exponential backoff:

Attempt Delay
1 5s
2 10s
3 30s
4 60s
5 120s
6+ 300s

Each reconnection uses a fresh random identity.

DNS Resolution

Hostnames are resolved locally before being passed to the SOCKS5 proxy. If a hostname resolves to multiple IPs, the bouncer tries each one until a connection succeeds. This handles proxies that don't support remote DNS and avoids IPs that are unreachable through the proxy.

Connecting with an IRC Client

Configure your IRC client to connect to the bouncer:

Setting Value
Server 127.0.0.1
Port 6667 (or as configured)
Password networkname:yourpassword

Password Format

PASS <network>:<password>
  • network -- matches a [networks.NAME] section in config
  • password -- the bouncer.password value from config

If you omit the network prefix (PASS yourpassword), the first configured network is used.

Client Examples

irssi:

/connect -password libera:mypassword 127.0.0.1 6667

weechat:

/server add bouncer 127.0.0.1/6667 -password=libera:mypassword
/connect bouncer

hexchat:

Set server password to libera:mypassword in the network settings.

Multiple Networks

Define multiple [networks.*] sections in the config. Each gets its own persistent server connection through the SOCKS5 proxy.

Connect your client with the appropriate network prefix:

PASS libera:mypassword    # connects to [networks.libera]
PASS oftc:mypassword      # connects to [networks.oftc]

Multiple clients can attach to the same network simultaneously. All receive the same messages in real time.

What Clients Receive on Connect

When a client authenticates and attaches to a network:

  1. Backlog replay -- missed messages since last disconnect
  2. Synthetic welcome -- 001-004 numeric replies from the bouncer
  3. Channel state -- TOPIC and NAMES for each joined channel

Backlog

Messages are stored in bouncer.db (SQLite) next to the config file. When you reconnect, missed messages are automatically replayed.

Configure in bouncer.toml:

[bouncer.backlog]
max_messages = 10000       # per network, 0 = unlimited
replay_on_connect = true   # set false to disable replay

Stored commands: PRIVMSG, NOTICE, TOPIC, KICK, MODE.

Configuration Reference

[bouncer]
bind = "127.0.0.1"        # listen address
port = 6667                # listen port
password = "changeme"      # client authentication password

[bouncer.backlog]
max_messages = 10000       # per network, 0 = unlimited
replay_on_connect = true   # replay missed messages on client connect

[proxy]
host = "127.0.0.1"        # SOCKS5 proxy address
port = 1080                # SOCKS5 proxy port

[networks.libera]
host = "irc.libera.chat"  # IRC server hostname
port = 6697                # server port (default: 6697 if tls, 6667 otherwise)
tls = true                 # use TLS for server connection
nick = "mynick"            # desired IRC nick (set after probation)
channels = ["#test"]       # channels to join (after probation)
autojoin = true            # auto-join channels on ready (default: true)
password = ""              # IRC server password (optional, for PASS command)

Stopping

Press Ctrl+C or send SIGTERM. The bouncer shuts down gracefully, closing all network connections and the backlog database.