Documentation

Hermes BBS Sysop Guide

Hermes BBS is a bulletin board system for the Mac, now in its fourth generation. One app, Hermes BBS, runs the board and is also the sysop console you manage it from. Callers connect with any Telnet or SSH client, a web browser, or the free Hermes Terminal app for macOS, iPhone and iPad.

This guide covers setting up a board and the parts of the console you'll use most. It is written for the current beta builds; menus may move slightly between builds, and Hermes BBS › What's New in Hermes BBS… lists each build's changes.

1. Installing and first launch

  1. Download Hermes BBS from hermesbbs.com/downloads, unzip it and drag the app into Applications. (On disk the app is still named Hermes 4.app; everywhere you see it, it's Hermes BBS.)
  2. Open it. On first launch Hermes BBS creates its data folder, a self-signed TLS certificate, an SSH host key and a Sysop account, then starts listening for callers.
  3. Open File › Sysop Terminal (⇧⌘T). This is a built-in terminal that logs you straight in as Sysop. Use it to look around the board the way callers will see it.

Requirements: a Mac with Apple Silicon, running macOS 13 or later.

Run the board in the background

In Settings › Server › Background Server, turn on Run BBS in the background (hermesd). The board then keeps running when you quit the console window, and starts again at login. With it off, the board only runs while the Hermes BBS app is open.

The Sysop account's password

The Sysop account is created with a random password, because you don't need one locally: the Sysop Terminal logs you in. To log in as Sysop from another computer, set a password in Users › Sysop › Reset Password.

Where your data lives

Everything is in ~/Library/Application Support/com.hermes.server/:

ItemWhat it is
hermes.sqliteThe database: users, forums, messages, email, chat, settings
Files/Files callers have uploaded (unless an area has its own folder, see §6)
GFiles/Bulletins, welcome screens and other ANSI/text screens
Externals/Classic Hermes 68K externals and their data
DOSDoors/DOS door games (a suggested home; see §9)

Use Maintenance › Backup & Restore rather than copying these by hand while the board is running. Backups cover the database, Files/, GFiles/ and Externals/. They do not include DOSDoors/, native door folders, or file areas kept in their own folders. Back those up separately (Time Machine works well).


2. Letting callers in

Ports

Hermes BBS listens on a block of ports starting at 2300:

PortProtocolUsed by
2300TelnetSyncTERM, NetRunner, PuTTY, Hermes Terminal and other BBS clients
2301Telnet over TLS (TelnetS)Encrypted Telnet clients, Hermes Terminal
2302HTTPS and secure WebSocketWeb terminal, file transfers
2304SSHAny SSH client

Each listener can be turned on or off, and its port changed, in Settings › Server.

To accept callers from the internet, forward these TCP ports on your router to the Mac running Hermes BBS. Forward 2302 if you want browser access and HTTPS file transfers; without it, callers can still use ZMODEM.

TLS certificate

Hermes BBS makes a self-signed certificate on first launch. It encrypts traffic, but browsers and some clients warn about it. For a trusted certificate under your own domain, use a free Let's Encrypt certificate. The same steps are in the app under Settings › Security › TLS Certificate (the ⓘ button).

These steps assume your domain's DNS is hosted on Cloudflare. With another DNS provider, use the matching certbot DNS plugin; the rest is the same.

  1. Install certbot in Terminal:

    brew install certbot
    pip3 install certbot-dns-cloudflare
  2. Create a Cloudflare API token at dash.cloudflare.com › My Profile › API Tokens, with permission Zone › DNS › Edit, limited to your domain.
  3. Save the token where certbot can read it:

    mkdir -p ~/.secrets
    cat > ~/.secrets/cloudflare.ini << 'EOF'
    dns_cloudflare_api_token = YOUR_TOKEN_HERE
    EOF
    chmod 600 ~/.secrets/cloudflare.ini
  4. Request the certificate:

    sudo certbot certonly \
      --dns-cloudflare \
      --dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
      -d bbs.yourdomain.com
  5. Let Hermes BBS read it. certbot saves certificates readable only by root:

    sudo chmod 755 /etc/letsencrypt/live /etc/letsencrypt/archive
    sudo chmod 644 /etc/letsencrypt/live/bbs.yourdomain.com/*.pem
    sudo chmod 644 /etc/letsencrypt/archive/bbs.yourdomain.com/*.pem
  6. Restart the server. Hermes BBS looks in /etc/letsencrypt/live/ automatically. Use Change… in Settings › Security › TLS Certificate only if your certificate is somewhere else. The settings show the domain, expiry date and fingerprint once it's loaded.

Renewal is automatic: certbot renews on a schedule, and Hermes BBS checks for a renewed certificate every six hours.

Web access

Port 2302 also accepts secure WebSocket connections at wss://yourhost:2302/ws. Browser-based terminals built on xterm.js use this to reach the board without any software install.

Keeping trouble out

Settings › Security › Geo-IP & IP Blocking looks up each caller's country (shown as a flag on the Connections screen). From there you can block whole countries or individual IP addresses and ranges.

Settings › Security › Password Policy sets the minimum password length and whether passwords must mix letters, numbers and symbols. It can also reject common passwords.


3. Users, security levels and groups

New callers type NEW at the username prompt to register. Callers who forget their password type RESET. If they have an email address on file, they're sent a reset code.

Security levels

Every user has a security level from 0 to 255. New users start at 10, and the Sysop is 255. Forums, file areas, GFiles, menu items and door games each have a minimum level; anything above a user's level is hidden from them. A common scheme:

LevelTypical use
0–9Restricted or unvalidated
10New users (default)
20–100Validated and trusted callers
255Sysop

Groups

Groups are for access that doesn't fit a single ladder, such as "beta-testers" or "game-ops". Select any user in Users and use the Groups box to create groups and tick memberships. Any forum, file area, GFile, menu item or door can list Required Groups. A user then needs both the security level and membership in one of those groups.

Managing a user

Select a user in Users to edit their profile, security level, groups and display settings. You can also reset their password, or delete and restore the account. Users who have asked for internet email show an EMAIL REQ badge, which you approve or deny there.


4. Forums and messages

Forums are organized as forums containing subforums, and each level has its own security level and required groups.

Callers see a new-message scan when they log on. They can catch up, reply, and vote in polls (the Voting Booth on the main menu).


5. Screens (GFiles) and menus

GFiles

GFiles are the board's text and ANSI screens. GFiles › Import Files… adds .ans or .txt files. Then pick where each one appears:

ContextShown
Welcome (Pre-Login)Before the login prompt
Login (Post-Login)Right after login
NewsIn the news reader
Info (Browsable)In the Information section
Main MenuAs the main-menu screen
Logoff (Goodbye)When a caller logs off

ANSI screens must use DOS-style CRLF line endings. Without them the art drifts to the right line by line. When the GFiles screen sees a file with plain LF endings, it offers Fix (Convert to CRLF).

Language Variants let you provide translated versions of the same screen. Callers who chose that language see the matching variant.

File › New ANSI Document opens the built-in ANSI editor for drawing your own screens.

The Menus screen lets you rename main-menu items, change their hotkeys, hide them, and restrict them by security level or group. Reset to Default undoes your changes.


6. File areas

The Files screen manages file areas, the download libraries callers browse.

Keeping an area on an external drive

Each file area can store its files in a folder of your choosing, so a large library can live on an external drive instead of the Mac's internal disk.

  1. Select the area in Files.
  2. Under Storage Folder, click Choose Folder… and pick or create a folder on the drive.
  3. If the area already has files, Hermes BBS asks before moving them. They're copied to the new folder first and only removed from the old one once every file has arrived. Callers can keep downloading while this runs, and a progress bar shows how far it has got.

Use Default moves an area back to the shared Files/ folder. You can also choose a folder when you create a new area.

If the drive is disconnected, the area shows an orange warning in the console. Callers trying to download or upload there are told the area is unavailable right now. Nothing is lost: reconnect the drive and the area works again. Hermes BBS never recreates a missing folder on the internal disk.

macOS may ask whether Hermes BBS can access files on a removable volume the first time it reads the drive. Click Allow. If you missed the prompt, enable it under System Settings › Privacy & Security › Files & Folders.

Backups do not include areas that have their own folder. Back those drives up separately (Time Machine works well).

How callers transfer files

MethodUsed by
HTTPSHermes Terminal (native progress) and browsers. Telnet callers get a link to open in a browser
ZMODEMClassic terminal programs like SyncTERM and NetRunner

Each caller picks Auto, HTTPS or ZMODEM under Defaults on the main menu. Auto uses HTTPS in Hermes Terminal and ZMODEM elsewhere.


7. Chat and AI chat bots

Callers press C on the main menu to join multi-channel chat. They can switch channels, use @mentions, send private messages and share files with /share. The Chat screen shows every channel live and lets you post as the sysop, create or delete channels, and drag in files to share.

AI chat bots

Chat bots are AI-powered regulars. They greet people joining a channel, reply when someone talks to them, and keep a quiet channel from feeling empty. They use xAI's Grok models:

  1. Get an API key from x.ai and paste it into Settings › Chat › AI Chat Bots › xAI API Key.
  2. On the Chat Bots screen, turn bots on, choose which channels each bot sits in, and pick a Personality (or write your own system prompt).
  3. Max/hour caps how many messages each bot can send. This keeps your API bill under control, and Stats shows messages and tokens used.

Bots always answer a person who is talking with them. Responsive sets how readily they join conversations they weren't asked into.


8. Email and internet email

Users can always email each other on the board, with no setup. Internet email goes further: it gives each permitted caller a real address, username@yourdomain.com, that can send to and receive from anywhere. You don't run a mail server. Incoming mail arrives through a provider's webhook, and outgoing mail leaves through a provider's API or an SMTP relay.

Everything is set in Settings › Email. Changes save automatically, and each box has a ? button with the same steps shown below.

What you need

A common, proven pairing is Cloudflare for inbound and Amazon SES for outbound.

Step 1: choose providers and your domain

At the top of the settings, set Inbound to Cloudflare and choose an Outbound provider. Then enter your Domain. This is the part after the @ in your users' addresses.

Step 2: receiving mail (Cloudflare Email Routing)

Cloudflare receives mail for your domain, and a small Cloudflare Worker turns each message into a signed web request to your board.

  1. Turn on Email Routing. In the Cloudflare dashboard, select your domain › Email › Email Routing › Enable. Cloudflare adds the MX records for you.
  2. Create the Email Worker. Go to Email Routing › Email Workers › Create Worker. Open the ? next to Receiving (Inbound) in Hermes BBS, click the copy button above the Worker code, and paste it into the Worker in place of the default code. The code imports the postal-mime library to read each message. If the dashboard editor can't resolve that import, deploy the Worker with Cloudflare's wrangler tool after running npm install postal-mime.
  3. Give the webhook a proxied hostname. Email Workers can only call standard HTTPS (port 443), but Hermes BBS listens on 2302. To bridge them:

    • Add a DNS A record such as mail.yourdomain.com, pointing at your public IP, with the proxy turned on (orange cloud).
    • Add an Origin Rule (Rules › Origin Rules) for that hostname that rewrites the destination port to 2302.
    • Enter that hostname as Webhook Host in Hermes BBS. The Webhook URL below it then reads https://mail.yourdomain.com/mail/inbound.
  4. Connect the Worker to your board. In the Worker's Settings › Variables, add:

    • HERMES_WEBHOOK_URL: copy it from the Webhook URL field.
    • WEBHOOK_SECRET: copy it from the Webhook Secret field.

    The secret proves messages came from your Worker. If you ever click Regenerate, update WEBHOOK_SECRET in the Worker to match.

  5. Route all mail to the Worker. Under Email Routing › Routes, add a catch-all rule that sends to your Worker.
  6. Test it. From an outside account (Gmail, iCloud…), email someuser@yourdomain.com. The message should land in that user's BBS inbox within seconds. Attachments are kept in the hidden Email Attachments file area.

Amazon SES can't be used for inbound mail yet; it is outbound only.

Step 3: sending mail

Pick one outbound provider. Whichever you choose, finish by typing your own address into Test to and clicking Send Test. This sends a real message using the settings on screen, so you can check them before any user relies on them.

Amazon SES

  1. In the AWS console, open SES in your preferred region (for example us-east-1). Go to Identities › Create identity › Domain and enter your mail domain.
  2. Add the three DKIM CNAME records SES gives you to your DNS.
  3. Add deliverability records to your DNS:

    • TXT yourdomain.com "v=spf1 include:amazonses.com include:_spf.mx.cloudflare.net ~all"
    • TXT _dmarc.yourdomain.com "v=DMARC1; p=quarantine"

    The SPF record covers both SES (sending) and Cloudflare (receiving).

  4. In IAM, create a user with ses:SendEmail and ses:SendRawEmail permissions and generate an access key. Enter the Access Key, Secret Key, Region and From Identity (your domain) in Hermes BBS.
  5. New SES accounts start in a sandbox that can only send to addresses you've verified. To send to anyone, request production access under SES › Account dashboard › Request production access.

SMTP relay

Any authenticated SMTP relay works: SES SMTP, Mailgun, Postal, your own Postfix, or Cloudflare's smtp.mx.cloudflare.net. The relay does the signing and delivery, so use one that is authorized to send for your domain.

  1. Enter the relay's Host and Port. Use implicit TLS on port 465. STARTTLS (port 587) isn't supported yet, so pick the 465 endpoint if your provider offers both. Plain, unencrypted port 25 is only for a trusted relay on your own network.
  2. Enter the Username and Password if the relay needs them (most do).
  3. Leave From Override empty to send as each user's own address, or set it to force one fixed sender.

Cloudflare

Cloudflare's sending service is in public beta. Either:

Step 4: deciding who gets internet email

Internet email is granted per user, through membership in the built-in internet-email group.

9. Door games and external programs

Hermes BBS runs three kinds of programs for callers. On the board they all appear on the same Externals menu (X on the main menu), grouped as Externals (Hermes 68K Emulation), Door Games (Native) and Door Games (Hermes x86 Emulation). Callers don't need to know the difference.

KindWhat it isManaged in
Classic Hermes externalsOriginal 1990s Hermes programs for 68K Macs, run in a built-in 68K emulatorExternals
Native doorsModern doors built for macOS that read a DOOR32.SYS drop fileDoor Games
DOS doorsClassic MS-DOS BBS doors, run in the built-in 8086 emulator (no DOSBox)Door Games

Classic Hermes externals (68K)

Where to get them. The hermesbbs.com Downloads page has three collections, each a single archive of every known external for that era:

CollectionContents
v2.2 Externals (60+ programs)Blackjack, Checkers, Chess, Hangman, Slots, HerTris, ANSI Doodle, H:UX, sysop utilities and more
v3.1 Externals (16 programs)Blackjack Pro, HerTris, Taipan, Othello, Video Poker, Merchant, BattleRoom and more
v3.5 Externals (9 programs)Blackjack Pro 1.3.1, Snake, Leech 3.5, TakeStock, Cups, Slycrel

Externals from Hermes v2.2 through v3.5.11 run unmodified.

Unpacking. The archives are classic Mac StuffIt (.sit) files. Expand them with The Unarchiver (free, on the Mac App Store) or StuffIt Expander. These tools keep each file's resource fork, which is where a classic external's program code lives. Don't unpack them with tools that drop resource forks, or copy them through a non-Mac file system (a FAT USB stick, a zip made on another OS). An external that lost its resource fork shows no code segments and won't run.

Installing.

  1. Open the Externals screen and click Import Externals….
  2. Select one or more external files, or a whole folder of them. Hermes BBS copies them into ~/Library/Application Support/com.hermes.server/Externals/, keeping their resource forks.
  3. Select each external to review it. You'll see its version, code segments and original settings. Then set:

    • Enabled: whether callers see it.
    • Override min security level: replace the level built into the external.
    • Required Groups: limit it to certain groups.

    Click Save Access Settings.

Good to know:

Native doors (DOOR32.SYS)

Native doors are ordinary macOS programs. Each time a caller launches one, Hermes BBS writes a DOOR32.SYS drop file describing the caller (name, node, time left, ANSI support). It starts the program with that file's path added to the end of its arguments, and connects the program's input and output to the caller.

Where to put them. Anywhere stable on the server Mac. This guide uses a doors folder in your home folder, with one subfolder per door: ~/doors/usurper-reborn, for example. Keep each door's data files next to it; many doors store their game data in their own folder.

Adding one. In Door Games, click Add Door Game…, set Type to Native (macOS binary), and fill in:

FieldWhat to enter
NameWhat callers see on the menu
ExecutableThe door program (use Browse…)
ArgumentsAny options the door needs before the drop-file path, space-separated
Working DirectoryUsually the door's own folder
Use PTYTurn on for doors that need a real terminal (they check isatty())
Min Security Level, Required Groups, Sort OrderWho can play it and where it sits in the list

Example: Usurper Reborn, the medieval RPG that's a flagship native door.

  1. Download the latest macOS-AppleSilicon zip from the Usurper Reborn releases on GitHub and unzip it.
  2. The zip contains usurper-reborn.app. Copy the contents of usurper-reborn.app/Contents/Resources/ into ~/doors/usurper-reborn/. Don't point Hermes BBS at the .app itself.
  3. The download doesn't mark the program as executable. Fix that in Terminal:

    chmod +x ~/doors/usurper-reborn/UsurperReborn
  4. Add it in Door Games: Executable ~/doors/usurper-reborn/UsurperReborn, Arguments --door32, Working Directory ~/doors/usurper-reborn.

To update later, back up usurper_online.db (it holds players' characters), copy the new release's files over the old ones, and run the chmod again.

Python doors. If you write your own doors, Add Python Door… takes a .py script and configures everything: the interpreter, the drop file, and a copy of the Hermes door kit (hermes_door.py) next to your script. It needs Python 3 on the Mac. If it's missing, Hermes BBS tells you to install Apple's command line tools with xcode-select --install. Native and Python doors also get two extra environment variables: HERMES_DOOR_LANG (the caller's language) and HERMES_DOOR_GROUPS (their groups).

DOS doors (Hermes86)

DOS doors run inside Hermes BBS's own 8086 emulator. There's nothing else to install: no DOSBox and no FOSSIL driver.

Where to get them. Classic doors come from their authors' or publishers' distribution archives and from the many BBS software archives online. Check each door's license and registration terms. Doors confirmed working today are Legend of the Red Dragon (LORD) and Pimp Wars. Others may work too, but the emulator covers the DOS features doors commonly use, not all of DOS, so test a new door before opening it to callers.

Where to put them. One folder per door inside the data folder:

~/Library/Application Support/com.hermes.server/DOSDoors/games/lord/
~/Library/Application Support/com.hermes.server/DOSDoors/games/pimpwars/

Unzip the door's original archive into its folder. Run any setup the door needs on another DOS system first if it requires one; many doors, LORD included, come ready to run.

Adding one. In Door Games, click Add Door Game…, set Type to DOS (Hermes86 emulator), and fill in:

FieldWhat to enter
Door DirectoryThe door's folder. Inside the emulator this is drive C:
Executable + ArgsThe .EXE name plus its command line, exactly as a DOS BBS would run it
Max concurrent nodesHow many callers can play at once; each gets their own node number

For each session, Hermes BBS writes the two classic drop files, DOOR.SYS and DORINFO1.DEF. They go on drive D: and are also copied into the door's folder, so doors find them wherever they look.

Settings for the two confirmed doors:

DoorDoor DirectoryExecutable + Args
Legend of the Red Dragon…/DOSDoors/games/lordLORD.EXE 1 /DREW
Pimp Wars…/DOSDoors/games/pimpwarsPIMPWARS.EXE DORINFO1.DEF 1

Pimp Wars must be told to use DORINFO1.DEF; it doesn't work with DOOR.SYS. For both, 4 concurrent nodes is a sensible starting point.

Remember: DOSDoors/ and native door folders are not in Hermes BBS backups, and they hold your players' game data. Include them in your own backups.

10. Maintenance and updates

Maintenance

Activity Log

The Activity Log screen is a live record of logons, uploads, downloads, door sessions and admin changes. Filter it by user or event type.

Software updates

Settings › Advanced › Software Update controls how Hermes BBS updates itself:

SettingWhat happens
OffNo update checks
Notify OnlyYou're told when an update is available
Install When AvailableUpdates install as soon as they're released
Install at Scheduled TimeUpdates install at a quiet hour you choose

Hermes BBS › Check for Updates… checks right away.

Importing a classic Hermes board

Import reads a classic Hermes BBS folder and brings its users and message base into Hermes BBS. Point it at the old board's folder, click Scan, review what it found, then Import Selected.

Administering from another Mac

Settings › Remote Admin lets a copy of Hermes BBS on another Mac manage this server. Turn on remote administration, then pair the other Mac with the one-time code shown. Folder choices made from a remote console, such as a file area's storage folder, are typed paths on the server Mac.


Getting help