Modern BBS, old soul, rewired.

A BBS server, written from scratch, with security, graphics, and audio built in at the foundation.

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.

TERMinator · tier 3
Rainwire home screen: logo, your account, system stats, last callers and sysop news
Gomemory-safe, no C on the network path
4 tiersevery screen adapts to the terminal
1 binaryone SQLite file holds all the data
0 accountsneeded to connect over SSH

One BBS, every terminal

Screens are built, not just played back

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.

Home screen
Home
Main menu
Main menu
Login form
Log in
Intrusion protection panel
Intrusion protection panel

These are the same screens from the same server. Use the buttons above to switch looks. Click any screenshot to enlarge it.

TierTypical clientGraphicsMouseAudioWindows
0Basic telnet, retro hardwareCP437, 16 colours——One full-screen app
1Modern terminal24-bit colour, Unicodexterm SGR—Drawn by the server
2SyncTERMSixel images, custom fontsSGRAPC mixerDrawn by the server
3TERMinatorTRACE: GPU, WASM modulesFullNativeDrawn by the client

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.

Drag and drop

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.

Keyboard first, always

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

Intrusion detection and prevention, built in

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.

Threat points form: failed SSH handshake 5, wrong password 10, wrong two-factor code 15, connecting too fast 20, command over SSH 50, honeypot 1000, failing on several handles 30, known scanner client 100, password login as root or admin 50
Threat points: each kind of misbehaviour adds to a score that fades by one point a minute.
  • Allow and deny lists for single IPs and CIDR ranges. The allow list protects retro callers on unusual networks.
  • Connection caps per address, plus rate limits on new connections.
  • Automatic bans once an address passes the score threshold. Each repeat offence doubles the ban, up to a limit you set.
  • Honeypot ports: touch one and you're banned on every listener, then held in a tarpit that feeds your scanner a never-ending banner.
  • Bot fingerprints: known scanner SSH clients and password logins as root or admin are scored on sight.
  • Credential-stuffing detection: one address trying many handles is scored, and guesses on one handle are counted across every address.
  • IPv6 grouped by /64, so rotating addresses doesn't get around a ban.
  • Live control: changes in the sysop panel apply at once, are saved in the database, and override config.lua until you reset.

Accounts that are hard to steal

Two-factor setup screen showing a QR code drawn in the terminal and a text key
Two-factor setup with a QR code drawn right in the terminal. (Test account; the key is throwaway.)
  • argon2id password hashing.
  • TOTP two-factor login works with any authenticator app. Secrets are encrypted at rest, codes can't be replayed, and you get ten one-use recovery codes.
  • 2FA is asked after every kind of login, SSH keys included. Sysops can be required to set it up.
  • Handles lock after repeated failures, from any address, for longer each time. SSH-key logins still get through, so an attacker can't lock the sysop out.
  • Sysop accounts can be tied to your own networks. The right password from anywhere else is treated as a wrong one, and every sysop login raises an alert.
  • No reusable passwords over plain telnet. Telnet callers log in with one-time codes, so a sniffed session exposes that session and never the account.
  • An audit log records every login, failure, ban and privilege change.

Sandboxed doors

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.

No C on the network path

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.

Least privilege

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

SSH without the chicken-and-egg problem

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.

1
ssh new@bbs

new goes straight to signup.

2
ssh yourhandle@bbs

Your SSH username fills in the login form.

3
Options → SSH keys

Remember 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

Simple to run, easy to change

menus/main.lua
-- 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" },
  },
}
  • Menus are Lua tables that read like config files and reload on the fly. Scripts run in a sandbox with no file or OS access.
  • Access expressions such as level >= 50 and group(fido) and not transport(telnet) replace lettered flags. Anything without a rule is sysop-only.
  • Named groups like fido, cosysop or beta, as many per user as you like.
  • Every word is a prompt. All text comes from a prompts file with {placeholders}, ready for rewording and translation.
  • Daily limits per level for calls and minutes, with time left shown in the header.
  • One static binary, one SQLite file. Upgrading means replacing the file and restarting. Nightly verified backups keep 7 daily and 4 weekly copies.
sysop jobs from the shell, with the server running or not
$ 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

The Rainwire network

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.

Signed posts

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.

Any topology

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.

Local control

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

Different choices, for different reasons

Mystic and Synchronet are great, battle-tested systems with decades of history. Here's where Rainwire does things differently.

MysticSynchronetRainwire
SourceClosed sourceOpen source (GPL)All-new, clean-room code
LanguageFree PascalC and C++Go, memory-safe, no cgo
ScreensDisplay files with MCI codesDisplay files with Ctrl-A codesWidgets drawn for each of 4 terminal tiers. Old codes are converted on import
Menus and scriptsMenu editor, MPL scriptsJavaScript shells and modulesLua tables in a sandbox, reloaded on the fly
Access rulesLettered flagsFlag setsNamed groups and readable expressions, denied by default
StorageJAM message basesSMB message basesOne SQLite file, with JAM import
Intrusion protectionVarious built-in protectionsDetection by threat score, automatic bans that grow with repeat offences, per-handle locks, honeypot tarpits, and a kernel firewall that drops banned addresses
DoorsRun as the BBS userEach door in its own sandbox, with no access to the database
Internet servicesFTP, email, NNTP and moreWeb, FTP, email, NNTP and moreDeliberately 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.