Table of Contents
Monitoring and Control via MQTT
Synchronet v3.20 can publish and subscribe to message “topics” on a configured MQTT broker.
As enabled and configured in SCFG->Networks->MQTT:
╔══════════════════════════════════════╗ ║ Message Queue Telemetry Transport ║ ╠══════════════════════════════════════╣ ║ │Enabled Yes ║ ║ │Broker Address 192.168.1.2 ║ ║ │Broker Port 1883 ║ ║ │Username ║ ║ │Password ║ ║ │Keep-alive 60 seconds ║ ║ │Protocol Version 5 ║ ║ │Publish Verbosity High ║ ║ │Publish QOS 0: At most once ║ ║ │Subscribe QOS 2: Exactly once ║ ║ │Log Level Informational ║ ║ │TLS (encryption) Off ║ ╚══════════════════════════════════════╝
Retention
Most Synchronet MQTT messages are published with the retain flag enabled. Retained messages published before a client/subscriber connects will still be received (upon new client connection) until until the broker is restarted or the retained messages are explicitly removed from the broker.
Topics
Synchronet MQTT message topics start with sbbs/BBSID where BBSID is the System's BBS ID (for QWK Packets) as configured in SCFG->Message Options. It's possible for a single MQTT broker to serve multiple Synchronet BBSes in this way. The full BBS name is published to this topic level (not a leaf topic). For example:
sbbs/MYBBS = My Brand-new BBS
All leaf topics are published as children of the sbbs/BBSID topic under 3 main branches:
sbbs/BBSID/node- BBS nodessbbs/BBSID/host- Server hostssbbs/BBSID/action- Client actions (events)
All MQTT messages published by Synchronet contain just plain text (US-ASCII characters), the one exception being sbbs/+/node/+/output topics that include terminal control characters/sequences. Numeric values, unless otherwise are specified, are represented in US-ASCII decimal characters.
Nodes
The BBS's terminal server nodes (servicing terminal connections via Telnet, SSH, RLogin, Raw TCP) can be monitored and controlled via MQTT.
Under the sbbs/BBSID/node hierarchy, you'll find a sub-topic for each BBS node, with the total node count published to the node topic, for example:
sbbs/MYBBS/node = 4 total
In “High” Publish Verbosity mode, human-readable node status messages are published directly to node/+ topics. For example:
sbbs/MYBBS/node/1 = Bubbaboy at external program menu via telnet sbbs/MYBBS/node/2 = At login prompt via telnet sbbs/MYBBS/node/3 = At login prompt via telnet sbbs/MYBBS/node/4 = Waiting for connection
Sub-topics of each node/+ topic include:
- sbbs/+/node/+/status - tab-delimited node status values (see
load/nodedefs.jsfor details) - sbbs/+/node/+/terminal - tab-delimited current (or last) connected-terminal definition
- sbbs/+/node/+/output - live output to connected-terminal (for spying)
Example:
sbbs/VERT/node/1/status = 0 0 1 65535 0 0 0 7 sbbs/VERT/node/1/terminal = 80 24 syncterm ANSI CP437 6 0 2005
Control
Nodes can be controlled by publishing messages to the following topics:
- sbbs/+/node/+/input - keyboard input to inject into connected-node
- sbbs/+/node/+/msg - send a short text message to the node (message should be terminated with a newline character)
- sbbs/+/node/+/set/status - set the node's status value (to an integer value: “0” is waiting for connection, “5” is off-line)
- sbbs/+/node/+/set/errors - set the node's error counter value (to an integer value, e.g. “0” to clear the error counter)
- sbbs/+/node/+/set/misc - set the node's miscellaneous attribute flags (to an integer value, “0x” prefix for hexadecimal values)
- sbbs/+/node/+/set/lock - only a sysop can login (publish “0” to clear this flag)
- sbbs/+/node/+/set/intr - interrupt (disconnect) a user's session (publish “0” to clear this flag)
- sbbs/+/node/+/set/down - make the node not available for connections (status = 5) (publish “0” to clear this flag)
- sbbs/+/node/+/set/rerun - have the node reload its configuration upon next connection (publish “0” to clear this flag)
Hosts
A single Synchronet BBS can be split across multiple instances running on separate inter-networked host computers. Each host will be represented with its own sub-topic of the sbbs/BBSID/host topic. For example:
sbbs/MYBBS/host/MYCOMPUTER sbbs/MYBBS/host/rPi sbbs/MYBBS/host/ubuntu
The public host name (configured in ctrl/sbbs.ini) of the host is published to this topic level (not a leaf). For example:
sbbs/MYBBS/host/MYCOMPUTER = mybbs.synchro.net
The control and monitoring of a specific Synchronet instance is done through this “host sub-topic” tree.
| Host sub-topic | Description |
|---|---|
| recycle | Publishing any message to the recycle sub-topic of any host topic will initiate a recycling of that host's servers (all of them). |
| pause | Publishing any message to the pause sub-topic of any host topic will initiate pause that host's servers (all of them), preventing the acceptance of any new incoming client connections. |
| resume | Publishing any message to the resume sub-topic of any host topic will un-pause that host's servers (all of them), that we previously paused via the pause topic. |
| clear | Publishing to the clear sub-topic of any host topic clears the failed-login attempt list (host-shared across all of that host's servers) and that host's terminal server's max-concurrent-connection strike list. Payload may be empty (clear everything) or a numeric IPv4/IPv6 address (clear only entries for that IP). The same effect can be triggered locally by creating ctrl/clear (or ctrl/clear.term, ctrl/clear.ftp, etc.) optionally containing an IP address as its first line. |
Servers
Each Synchronet instance (host) contains the following servers, each represented by its own sub-topic of sbbs/BBSID/host/hostname/server:
- sbbs/+/host/+/server/term - Terminal Server
- sbbs/+/host/+/server/mail - Mail Server
- sbbs/+/host/+/server/ftp - FTP Server
- sbbs/+/host/+/server/web - Web Server
- sbbs/+/host/+/server/srvc - Services
The status of each server is published to its server topic, for example:
sbbs/MYBBS/host/MYCOMPUTER/server/term = ready 1/5 clients 223 served
The state (first field of status) for each server is one of:
- stopped
- initializing
- ready
- paused
- reloading
- stopping
- disconnected
The server status contains more details/statistics and is published more often when “High” MQTT->Publish Verbosity is enabled in SCFG.
| Server sub-topic | Description |
|---|---|
| recycle | Publishing any message to the recycle sub-topic of any server topic will initiate a recycling of that server. |
| pause | Publishing any message to the pause sub-topic of any server topic will prevent that server from accepting any new incoming client connections. |
| resume | Publishing any message to the resume sub-topic of any server topic will un-pause that server, returning to the “ready” state, accepting incoming client connections. |
| clear | Publishing to the clear sub-topic of any server topic clears that server's view of the failed-login attempt list (and, for the terminal server, its max-concurrent-connection strike list). Payload may be empty (clear all) or a numeric IPv4/IPv6 address (clear only that IP). |
Each server topic has the following sub-topics for status reporting:
- sbbs/+/host/+/server/+/version - name, version/revision, and build date/time/tool of server
- sbbs/+/host/+/server/+/state/# - server state change events
- sbbs/+/host/+/server/+/client - current count of connected clients and maximum number of concurrent clients supported by this server
- sbbs/+/host/+/server/+/client/list - tab-delimited details of all connected clients, one client per line
- sbbs/+/host/+/server/+/client/action/# - client actions (e.g. connect, disconnect)
- sbbs/+/host/+/server/+/served - total clients served since server was started
- sbbs/+/host/+/server/+/highwater - highest concurrent client count since server was started
- sbbs/+/host/+/server/+/error_count - total errors logged since server was started
Logs
Each server/+ and event sub-topics has a log child topic where all messages of all log levels (severity) will be published as well as a grandchild topic for each log level (0-7, decreasing in severity) of logged messages.
Log messages published directly to the “log” topic also have a MQTT v5 user property that specifies the log level of each message (for indication / sorting by the receiving client).
- sbbs/+/host/+/server/+/log
- sbbs/+/host/+/server/+/log/#
- sbbs/+/host/+/event/log
- sbbs/+/host/+/event/log/#
Login Attempts
Synchronet maintains two per-IP lists for surveilling unsuccessful logins and connection-limit hits, both published as retained MQTT messages so subscribers see live state immediately on connect.
Failed Login Attempts
Each source IP with one or more unsuccessful login attempts to any of the BBS's protocol servers (terminal/FTP/mail/services/web) is published as a retained message at:
- sbbs/+/host/+/login_attempts/IP
Fields are tab-delimited:
- date/time of first failed attempt (ISO-8601)
- date/time of latest failed attempt (ISO-8601)
- total attempt count
- duplicate-attempt count (consecutive same username+password)
- protocol of the latest attempt (e.g.
SSH,POP3,FTP) - username tried in the latest attempt
For example:
sbbs/VERT/host/vert/login_attempts/27.79.1.152 = 20260502T141018-0700 20260502T141023-0700 2 0 SSH ftp
The plaintext password (kept internally for sysop inspection on the running host) is not published, since MQTT publishes may be visible to off-host subscribers.
Entries are removed (an empty retained payload is published, which the broker treats as a delete of the retained topic) when:
- the user successfully authenticates from that IP, or
- the sysop publishes that IP as the payload to a host-level or server-level
clearcontrol topic, or - the sysop publishes an empty payload to
clear(removes every entry).
The list is shared across all of a host's servers, so failed FTP, mail, web, and services attempts share the same login_attempts/IP topic; the protocol of the latest attempt is recorded in the payload.
This topic is complementary to the per-event action/login_fail topic, not a replacement. login_fail is an event stream: one message fires for each individual failed authentication, and the broker keeps no record after delivery. login_attempts/IP is the aggregated retained state: one message per IP, overwritten on each new attempt, deleted on success or sysop clear. A subscriber to login_fail sees every attempt as it happens but knows nothing on first connect; a subscriber to login_attempts/+ sees the current per-IP state of every tracked IP immediately (via retained-message replay) and updates as state changes. Use login_fail for a live feed or alerting, login_attempts/+ for a “current bad-IP state” dashboard or to enumerate the IPs your tooling can pass to clear.
Max-Concurrent-Connection Strikes
The Terminal Server tracks each source IP that hits the maximum concurrent connections without login limit (configured in SCFG->Servers->Terminal Server). The current strike count for each tracked IP is published as a retained message at:
- sbbs/+/host/+/server/term/max_concurrent/IP
The payload is the bare decimal strike count.
Entries are removed when:
- the sysop publishes a host- or terminal-server
clearcontrol message (empty or matching IP payload), or - the strike count reaches the filter threshold and Synchronet automatically adds the IP to the IP filter, or
- a successful login from that IP arrives.
Actions
Client actions are published to the following BBS-wide topics:
- sbbs/+/action/hack/METHOD - suspected hack attempt
- sbbs/+/action/spam/ACTION - suspected SPAM received
- sbbs/+/action/error/LEVEL - unexpected condition
- sbbs/+/action/exec/PROGCODE - external program executed
- sbbs/+/action/login/PROTOCOL - successful user authentication
- sbbs/+/action/login_fail/PROTOCOL - unsuccessful user authentication
- sbbs/+/action/logout/PROTOCOL - user logged-out
- sbbs/+/action/download/DIRCODE - file downloaded
- sbbs/+/action/upload/DIRCODE - file uploaded
- sbbs/+/action/post/SUBCODE - message posted
- sbbs/+/action/newuser/PROTOCOL - new user created
- sbbs/+/action/page/node/NODE_NUM - sysop paged for chat
Fields are tab-delimited and begin with a date/time stamp in ISO-8601 format.
Triggers
The Terminal Server's event thread can be instructed to executed Timed Events or initiate QWKnet call-outs by posting a message to the following topics:
- sbbs/+/exec - send the internal code of the timed event to execute (case-insensitive)
- sbbs/+/call - send the QWK-ID of the QWKnet node to force a call-out to (case-insensitive)
