Per-network, per-nick client certificates (EC P-256, self-signed, 10-year validity) stored as combined PEM files. Authentication cascade: SASL EXTERNAL > SASL PLAIN > NickServ IDENTIFY. New commands: GENCERT, CERTFP, DELCERT. GENCERT auto-registers the fingerprint with NickServ CERT ADD when the network is connected. Includes email verification module for NickServ registration and expanded NickServ interaction (IDENTIFY, REGISTER, VERIFY).
197 lines
5.2 KiB
Markdown
197 lines
5.2 KiB
Markdown
# Cheatsheet
|
|
|
|
## Run
|
|
|
|
```bash
|
|
bouncer -c config/bouncer.toml # start
|
|
bouncer -c config/bouncer.toml -v # start (debug)
|
|
bouncer --version # version
|
|
bouncer --help # help
|
|
```
|
|
|
|
## Podman
|
|
|
|
```bash
|
|
make build # build container image
|
|
make up # podman-compose up -d
|
|
make down # podman-compose down
|
|
make logs # podman logs -f bouncer
|
|
```
|
|
|
|
```bash
|
|
podman logs bouncer 2>&1 | grep -E 'INFO|WARN' # filtered logs
|
|
podman exec -it bouncer bash # shell into container
|
|
podman ps --filter name=bouncer # status
|
|
```
|
|
|
|
## Develop
|
|
|
|
```bash
|
|
make dev # install with dev deps into .venv
|
|
make test # pytest
|
|
make lint # ruff check
|
|
make fmt # black + ruff --fix
|
|
make run # run with config/bouncer.toml
|
|
make clean # rm .venv, build artifacts
|
|
```
|
|
|
|
## Client Auth
|
|
|
|
```
|
|
PASS <password> # authenticate (all networks)
|
|
```
|
|
|
|
## Bouncer Commands
|
|
|
|
### Inspection
|
|
|
|
```
|
|
/msg *bouncer HELP # list commands
|
|
/msg *bouncer STATUS # all network states
|
|
/msg *bouncer INFO libera # detailed network info
|
|
/msg *bouncer UPTIME # process uptime
|
|
/msg *bouncer NETWORKS # list networks
|
|
/msg *bouncer CREDS [network] # NickServ creds
|
|
/msg *bouncer CHANNELS [network] # joined channels + topics
|
|
/msg *bouncer CLIENTS # connected clients
|
|
/msg *bouncer BACKLOG [network] # message counts + DB size
|
|
/msg *bouncer VERSION # bouncer + Python version
|
|
```
|
|
|
|
### Network Control
|
|
|
|
```
|
|
/msg *bouncer CONNECT libera # start disconnected network
|
|
/msg *bouncer DISCONNECT libera # stop network
|
|
/msg *bouncer RECONNECT libera # restart with fresh identity
|
|
/msg *bouncer NICK libera newnick # change nick
|
|
/msg *bouncer RAW libera WHOIS user # send raw IRC command
|
|
```
|
|
|
|
### Config Management
|
|
|
|
```
|
|
/msg *bouncer REHASH # reload config file
|
|
/msg *bouncer ADDNETWORK name host=h port=N tls=yes nick=n channels=#a,#b
|
|
/msg *bouncer DELNETWORK name # remove network
|
|
/msg *bouncer AUTOJOIN net +#chan # add to autojoin
|
|
/msg *bouncer AUTOJOIN net -#chan # remove from autojoin
|
|
```
|
|
|
|
### NickServ
|
|
|
|
```
|
|
/msg *bouncer IDENTIFY libera # force IDENTIFY
|
|
/msg *bouncer REGISTER libera # trigger registration
|
|
/msg *bouncer DROPCREDS libera # delete all creds
|
|
/msg *bouncer DROPCREDS libera nick # delete one nick's creds
|
|
```
|
|
|
|
### CertFP
|
|
|
|
```
|
|
/msg *bouncer GENCERT libera # generate cert (current nick)
|
|
/msg *bouncer GENCERT libera nick # generate cert (specific nick)
|
|
/msg *bouncer CERTFP # list all cert fingerprints
|
|
/msg *bouncer CERTFP libera # list certs for one network
|
|
/msg *bouncer DELCERT libera # delete cert (current nick)
|
|
/msg *bouncer DELCERT libera nick # delete cert (specific nick)
|
|
```
|
|
|
|
## Namespacing
|
|
|
|
```
|
|
#channel/network # channel on a specific network
|
|
nick/network # foreign nick on a specific network
|
|
own-nick # own nicks shown without suffix
|
|
```
|
|
|
|
```
|
|
/msg #libera/libera hello # send to #libera on libera network
|
|
/join #test/oftc # join #test on oftc
|
|
/join #a/libera,#b/oftc # comma-separated, different networks
|
|
```
|
|
|
|
## Connection States
|
|
|
|
```
|
|
DISCONNECTED -> CONNECTING -> REGISTERING -> PROBATION (15s) -> READY
|
|
```
|
|
|
|
| State | What happens |
|
|
|-------|-------------|
|
|
| CONNECTING | TCP + SOCKS5 + TLS handshake |
|
|
| REGISTERING | Random nick/user/realname sent to server |
|
|
| PROBATION | 15s wait, watching for K-line |
|
|
| READY | Switch to configured nick, join channels |
|
|
|
|
## Auth Cascade
|
|
|
|
```
|
|
SASL EXTERNAL (cert + creds) > SASL PLAIN (creds) > NickServ IDENTIFY
|
|
```
|
|
|
|
## Reconnect Backoff
|
|
|
|
```
|
|
5s -> 10s -> 30s -> 60s -> 120s -> 300s (cap)
|
|
```
|
|
|
|
## Config Skeleton
|
|
|
|
```toml
|
|
[bouncer]
|
|
bind / port / password
|
|
[bouncer.backlog]
|
|
max_messages / replay_on_connect
|
|
|
|
[proxy]
|
|
host / port
|
|
|
|
[networks.<name>] # repeatable
|
|
host / port / tls
|
|
nick / channels / autojoin
|
|
password # optional, IRC server PASS
|
|
```
|
|
|
|
## Files
|
|
|
|
| Path | Purpose |
|
|
|------|---------|
|
|
| `config/bouncer.toml` | Active config (gitignored) |
|
|
| `config/bouncer.example.toml` | Example template |
|
|
| `config/bouncer.db` | SQLite backlog (auto-created) |
|
|
| `{data_dir}/certs/{net}/{nick}.pem` | Client certificates (auto-created) |
|
|
|
|
## Backlog Queries
|
|
|
|
```sql
|
|
-- recent messages
|
|
SELECT * FROM messages ORDER BY id DESC LIMIT 20;
|
|
|
|
-- per-network counts
|
|
SELECT network, COUNT(*) FROM messages GROUP BY network;
|
|
|
|
-- last seen state
|
|
SELECT * FROM client_state;
|
|
```
|
|
|
|
## Source Layout
|
|
|
|
```
|
|
src/bouncer/
|
|
__main__.py # entry point, event loop
|
|
cli.py # argparse
|
|
config.py # TOML loader
|
|
irc.py # IRC message parse/format
|
|
namespace.py # /network encode/decode for multiplexing
|
|
proxy.py # SOCKS5 connector (local DNS, multi-IP, CertFP)
|
|
network.py # server connection + state machine + SASL
|
|
client.py # client session handler
|
|
cert.py # client certificate generation + management
|
|
commands.py # 25 bouncer control commands (/msg *bouncer)
|
|
router.py # message routing + backlog trigger
|
|
server.py # TCP listener
|
|
backlog.py # SQLite store/replay/prune
|
|
```
|