Windows you can drag
Doors and apps run in windows callers can move, resize and switch between, like a desktop. TERMinator draws its windows locally, so dragging has no lag. Everyone else gets a server-drawn window manager in the spirit of DESQview.
Modern BBS, old soul, rewired.
Rainwire gives every caller the best screen their terminal can draw, from TERMinator and SyncTERM down to a basic telnet session on retro hardware. It's a single Go binary with built-in intrusion detection and prevention, two-factor login and sandboxed doors.
One BBS, every terminal
Most BBS screens are hand-drawn .ANS files, and everyone gets the same bytes. Rainwire builds each screen from widgets (menus, forms, lists, dialogs) and draws it with a renderer for the caller's terminal. It finds out what your terminal can do when you connect: device attributes, SyncTERM's CTerm reply, a UTF-8 probe and TERMinator's TRACE query. Hand-drawn ANSI art still works as an asset.




These are the same screens from the same server. Use the buttons above to switch looks. Click any screenshot to enlarge it.
| Tier | Typical client | Graphics | Mouse | Audio | Windows |
|---|---|---|---|---|---|
| 0 | Basic telnet, retro hardware | CP437, 16 colours | — | — | One full-screen app |
| 1 | Modern terminal | 24-bit colour, Unicode | xterm SGR | — | Drawn by the server |
| 2 | SyncTERM | Sixel images, custom fonts | SGR | APC mixer | Drawn by the server |
| 3 | TERMinator | TRACE: GPU, WASM modules | Full | Native | Drawn by the client |
Doors and apps run in windows callers can move, resize and switch between, like a desktop. TERMinator draws its windows locally, so dragging has no lag. Everyone else gets a server-drawn window manager in the spirit of DESQview.
Drop a file from your desktop into TERMinator and it uploads over SFTP, with no ZMODEM needed. Drag from the file browser into the message editor to attach a file.
The mouse and graphics are extras. Every action can be done from the keyboard at every tier, so retro callers never hit a dead end.
Security as a headline feature
Detection: Rainwire watches how every caller behaves. Failed logins, wrong two-factor codes, bad SSH handshakes, connection floods and honeypot hits all add to a threat score for that address. Prevention: once the score passes your threshold, the address is banned automatically on every listener, and repeat offenders get longer bans each time. Banned and denied addresses are refused the moment they connect, before any SSH or telnet handshake, so they cost almost nothing.
This is an application-layer intrusion prevention system (IPS) that understands BBS logins. Rainwire also ships the packet layer: a stateful nftables ruleset with SYN-flood and per-source rate limits, and a small privileged helper that turns every Rainwire ban into a kernel drop, so banned addresses never reach the server again.

root or admin are scored on sight.config.lua until you reset.


Each door runs as an unprivileged user in its own sandbox (bubblewrap or systemd on Linux), with CPU, memory and time limits. It sees its own folder and drop file, never the BBS database.
The server is pure Go. ZMODEM and BinkP are written fresh in Go from the public specs and fuzz-tested, so there's no lrzsz or binkd. Uploaded archives are opened in the sandbox, which stops zip bombs.
The server runs as a dedicated non-root user under a hardened systemd unit. Uploads are quarantined and scanned with ClamAV before they reach a public area.
Getting in
On most BBSes you need an account to get SSH access, and you need to connect to make an account. On Rainwire, anyone can connect. The real gate is the BBS login, and there's no shell behind it.
ssh new@bbsnew goes straight to signup.
ssh yourhandle@bbsYour SSH username fills in the login form.
Options → SSH keysRemember your key, and next time it logs you straight in (2FA still applies).
Clients like SyncTERM that send a saved password are logged in directly. A bad match lands on the normal form, which gives nothing away about whether the handle exists.
For sysops
-- Edit and save: the next caller sees it. No restart.
return {
title = "Main Menu",
items = {
{ key = "M", label = "Message bases",
access = "true" },
{ key = "F", label = "Fido echoes",
access = "level >= 50 and group(fido)" },
{ key = "Y", label = "Sysop",
access = "level >= 255 and mfa",
action = "menu:sysop" },
},
}
level >= 50 and group(fido) and not transport(telnet) replace lettered flags. Anything without a rule is sysop-only.fido, cosysop or beta, as many per user as you like.{placeholders}, ready for rewording and translation.

$ rainwire admin users
$ rainwire admin level SomeUser 50
$ rainwire admin group SomeUser add fido
$ rainwire admin mfa-reset SomeUser # lost phone
$ rainwire admin unban 203.0.113.9
$ rainwire admin audit 40
$ rainwire admin backup
Linked boards
Rainwire BBSes can share message boards, with posts from every member system. It's off by default, and each sysop chooses which boards to carry. This network is a modern layer between Rainwire systems.
Every post is signed by the BBS it was written on, so it can't be forged or altered in transit. A post's ID is the hash of its content, so duplicates and loops drop out automatically.
Store and forward over mutual TLS 1.3. Link every server to every other or use hubs. Anyone can also run a private network with its own admin key.
Board moderators act across the network, but every sysop can still hide posts, block users or drop a peer on their own system. Passwords, emails and IPs never leave the home BBS.
Rainwire vs Mystic and Synchronet
Mystic and Synchronet are great, battle-tested systems with decades of history. Here's where Rainwire does things differently.
| Mystic | Synchronet | Rainwire | |
|---|---|---|---|
| Source | Closed source | Open source (GPL) | All-new, clean-room code |
| Language | Free Pascal | C and C++ | Go, memory-safe, no cgo |
| Screens | Display files with MCI codes | Display files with Ctrl-A codes | Widgets drawn for each of 4 terminal tiers. Old codes are converted on import |
| Menus and scripts | Menu editor, MPL scripts | JavaScript shells and modules | Lua tables in a sandbox, reloaded on the fly |
| Access rules | Lettered flags | Flag sets | Named groups and readable expressions, denied by default |
| Storage | JAM message bases | SMB message bases | One SQLite file, with JAM import |
| Intrusion protection | Various built-in protections | Detection by threat score, automatic bans that grow with repeat offences, per-handle locks, honeypot tarpits, and a kernel firewall that drops banned addresses | |
| Doors | Run as the BBS user | Each door in its own sandbox, with no access to the database | |
| Internet services | FTP, email, NNTP and more | Web, FTP, email, NNTP and more | Deliberately focused: SSH, telnet over TLS, wss:// and restricted plain telnet |
Rainwire deliberately leaves out FTP, a web front end, an inbound email server and legacy services like Gopher and finger. That keeps the attack surface small. If you need those today, Mystic and Synchronet have you covered.