All notable changes to pyCluster should be recorded here.
- System Operator Users now includes a Locked view backed by the same account matrix as the main Users and Blocked views.
- Direct RBN feed ingestion now batches accepted spots, yields during burst fanout, and caps live RBN aggregation state to reduce freeze and memory-growth risk on busy feeds.
- Filtered
show/mydxscans deeper durable spot history before reporting no matches, improving behavior when recent RBN or nonmatching traffic dominates the latest rows.
- Telnet registration requests no longer create local user accounts before SysOp approval.
- Denied or deleted accounts now clear stale local user, registration, and MFA challenge state so reused callsign-SSIDs do not inherit old email/MFA data.
- Telnet idle keepalive prompt refresh no longer adds extra blank lines.
- Locked exact callsign-SSID accounts are rejected before password or MFA prompts.
- Outbound PC92 path sanitization and PC61 spot relay now use detected global interface addresses as a runtime fallback when public IP fields are blank, avoiding
localhostor private-address protocol payloads on nodes that have not saved explicit public addresses.
- RBN/Skimmer spot handling now accepts documented
-#Skimmer spotter suffixes. show/rbn [call] [limit]shows summarized RBN/Skimmer reports for a callsign.- Optional direct RBN-enabled telnet feed ingestion can log in, send startup commands, and store DX-style Skimmer spots.
- Public web spot filters now persist common filter combinations into database-backed
accept/spotsrules shared with telnet. - Public web users can request a self-service password reset by verified email address; a successful reset updates the password and clears failed-password account locks.
- RBN spots are opt-in for telnet users by default through
set/rbn;unset/rbndisables live RBN delivery. show/dxnow remains a traditional DX spot history and excludes RBN/Skimmer reports. Useshow/rbnfor RBN history andshow/mydxfor filtered personal spot history.- Telnet self-registration verifies the user's email before creating the sysop review request when SMTP is configured.
- Public web filtering no longer exposes ITU-zone filter controls; CQ zone, continent, band, mode, activity, and spotter filters remain available.
- The public web map seeds the QTH marker from the logged-in user's stored profile grid when no local map override exists.
- Public web failed-password attempts now use the same durable failed-password lock state as telnet and send an account-lock notice when SMTP and a verified email are available.
- Public web RBN/Skimmer spot visibility now honors the user's database-backed
set/rbnpreference andaccept/rbn/reject/rbnfilters. - Telnet
set/passwordnow requires password confirmation and the bare interactive form prompts without echoing the password. - Self-registration callsign validation now rejects user-name-shaped values where the first digit appears too late to look like an amateur callsign.
- Telnet command handling no longer force-flushes still-forming RBN batches around every command, preventing partial RBN summaries from splitting into multiple lines or interleaving with
sh/mydxreplies. - Live RBN aggregation now collapses already-summarized upstream
-#reports for the same call/frequency/time bucket into a single summary line. - DXSpider-profile peers receive legacy PC11 spot relay frames even when configured over a normal TCP DSN.
- Telnet keepalive prompts are line-terminated and freshly rendered during idle waits.
- Telnet startup command output is separated from the final login prompt so configured startup displays do not run into the prompt line.
- Telnet self-service MFA commands now apply to the exact logged-in callsign or SSID instead of collapsing every action to the base callsign.
- Outbound PC92 path data sanitizes non-public IPv4 and IPv6 literals when
public_ip_addressis configured. - Bare-metal nginx setup always writes a
pycluster-sysop.conffile; when no sysop hostname is configured it is an inert placeholder rather than a public listener.
- User self-service MFA controls in public web and telnet.
- System Operator user controls for block/unblock, account unlock, MFA status, and authenticator enrollment.
- Public web spot filtering enhancements and backend Kp propagation data.
- Console upgrade worker support for using the source checkout path.
- Cluster peer records are separated from local users in the System Operator console.
- Node-wide MFA defaults wait for usable user MFA material instead of locking users out before setup.
- Data refresh timers, deployment units, and operations documentation were refreshed.
- Public web and System Operator controls were polished for mobile and foldable layouts.
- SSID users no longer inherit base-call permissions when they have explicit local records.
- Telnet keepalive handling, password prompt echo handling,
announce/full,show/muf, andshow/moonbehavior were tightened. - Public web registration approval and email verification state now produce authenticated, verified user records.
- Saved peer connect/disconnect flows preserve stored peer definitions and credentials.
- Mobile public web sidebar, footer controls, toast placement, modals, and System Operator tab rows no longer overflow or disappear on narrow screens.
- Upgrade and repair scripts now replace an invalid runtime
strings.tomlwith the bundled catalog after backing it up. - Outbound node-link reconnects now advertise the local PC18 software identity so peers refresh cached pyCluster versions.
- System Operator web controls for QRZ XML credentials used by
show/qrz - Saved peer deletion from the System Operator peer editor
- Google Authenticator-compatible TOTP MFA enrollment and login verification
- Satellite pass prediction for
show/satellite <target>using local TLE/keps data - Dedicated public-web taxonomy editor in the System Operator web console
- More aggressive telnet scanner
fail2banjail for repeated invalid login attempts - Public web controls for hiding spot popups and the sidebar
- Default fresh-install authentication gates are off until a sysop enables them
- System Operator maintenance actions are grouped under the Maintenance node-settings pane
- System Operator terminology and recent-authentication-failure labels are clearer
- SMTP settings now include a direct test-email action from the web console
- System Operator peer health now separates live transport activity from stale inbound protocol state
- Remote
talkrouting now relays direct talk messages over node links - Local announce, WX, WCY, and WWV posts are delivered to local users and relayed to peers
- Cluster user totals now use explicit remote roster reports instead of protocol frame counters
- Saved inbound peer definitions can be stored without a transport address and remain visible/editable in the System Operator peer table
- pyCluster-profile peers now receive keepalive frames, and one-way active links report as transmit-active/receive-quiet instead of just stale
- Live WWV announcements use the aligned table-style header instead of running into the prompt
- New peer creation clears the whole peer editor, including the peer filter
- Let's Encrypt setup fails early when required certificate input is missing or host web ports are already occupied by a non-nginx service
- Public web spot toasts no longer cover the sidebar
- User deletion removes the full local account footprint instead of leaving stale preferences behind
- Geomagnetic data parsing (
WcyReading,WwvReading) extracted into dedicatedgeomagmodule - User registration state management (
registrationmodule) with email validation and state normalization - In-place upgrade manager (
upgrade_manager) with systemd path/service units for zero-touch upgrades viadeploy/systemd/pycluster-upgrade.{path,service} - Bundled
CTY.DAT(VER20260404) andwpxloc.rawfixtures updated so fresh installs start with current country data
- Deploy tooling (
install.sh,upgrade.sh,repair.sh,setup-nginx.sh,doctor.sh,lib.sh) updated for 1.0.6 upgrade paths config/pycluster.tomlandconfig/strings.tomlrefreshed- Documentation updated across configuration, installation, node-linking, operations, public-web, sysop-web, and user-manual pages
- README updated
- PC20 keepalive now sent to all connected peers (inbound and outbound), preventing false stale/disconnected state on low-traffic links
- Receiving a PC20 ping from a peer now refreshes its activity timestamp
- Various protocol, transport, web-admin, and telnet command improvements carried forward from staging
- cleaned up the telnet command surface so operator responses are more readable and more consistent across
show/*,set/*,unset/*, mail, route, protocol, and sysop command families - moved a large share of operator-facing telnet text and selected operational log strings into
config/strings.tomlso wording tweaks no longer require code edits or restarts - public web 24-hour spot stats, history, and leaderboard views now use real time-window queries instead of capped recent-spot snapshots
- the System Operator web console now shows country-data status more clearly, including left-nav pills for loaded
CTY.DATandwpxloc.rawversion/date metadata - deploy tooling now treats country-data refresh as
CTY.DATpluswpxloc.raw, anddeploy/doctor.shchecks the public stats endpoint on the correct listener - upgrades and deploys are now documented around
config/pycluster.local.tomlso host-local settings stay out of the tracked base config
wpxloc.rawparsing and fallback lookup support for heading, web spot enrichment, and suspicious-prefix review cues- email OTP MFA recovery paths in both the System Console and telnet via
sysop/clearmfa <call> - stale-user cleanup controls in the System Operator web console
- richer cluster-mail observability in telnet and the System Operator web console
set/name,set/qth,set/qra,set/location,set/home, and relatedshow/*commands now persist and read back consistentlyset/locationnow takes precedence overset/qra, whileset/qrabackfills location only when location is unsetshow/heading,who,show/links,show/route, and related peer/operator views now report more accurate live state- telnet login handling no longer misbehaves when negotiation bytes are present before the callsign
- public web frequency formatting and 24-hour summary counts now match real backend data better
- live spot ingest now uses permissive plausibility checks instead of an over-strict homemade world callsign validator, while suspicious cases are flagged for review instead of being dropped
- cluster mail routing handles offline peers and undeliverable paths more cleanly, with clearer operator readback
show/wm7dCQ-zone handling for calls likeN9JRnow prefers better lookup data instead of stale prefix-only assumptions
- fixed the cumulative upgrade path so older
1.0.0databases with the realuser_prefs(pref_key, pref_value)schema now upgrade cleanly throughdeploy/upgrade.sh - added regression coverage for the upgrader against the legacy
1.0.0config/database shape
show/qrznow targets real QRZ XML lookups when QRZ credentials are configured, and the prior local history view has moved toshow/lastspotshow/wm7dnow performs a real WM7D callsign lookup- the documented in-place upgrade path now explicitly covers
1.0.0through1.0.3 - cluster mail has started moving beyond node-local storage:
PC10is aligned back to talk/direct-message semantics- cluster mail transport now uses
PC28-PC33 msgandreplycan queue and route mail by the recipient's configured home node- pending mail is flushed when the target peer connects
- message listings now show delivery state
- top-level
linksnow shows the richer direct link status view instead of the oldershow/connectsession dump
- DXSpider migration tooling:
deploy/migrate.shscripts/migrate_dxspider.py- DXSpider local-data import support for:
- users
- home node
- MOTD
- bad-word rules
- simple outbound peer definitions from
connect/* - exact
badip.localIP export into pyCluster-managed fail2ban block input
- age-based retention tooling:
scripts/cleanup_retention.pypycluster-retention.servicepycluster-retention.timer
- logrotate policy for
/var/log/pycluster/authfail.log
- README presentation and support matrix wording
- installation, migration, and operations docs now describe validated platforms and current migration/runtime scope more explicitly
- product-facing defaults and examples were scrubbed of site-specific AI3I deployment data
- sysop and public web UI polish continued, including cleanup controls, footer login/logout actions, and sidebar/runtime presentation
deploy/upgrade.shnow performs the 1.0.0 -> 1.0.1 state upgrade tasks automatically- protocol-health flapping detection no longer treats routine
PC24traffic as a flap event, avoiding false flapping status in the sysop console (#32) - public web now exposes bulletin traffic on its own tab, including announce, chat, WX, WCY, and WWV activity (
#24) - sysop web
Non-Authenticateddefaults now match the enforced access policy in the access matrix - sysop user and peer views now surface normalized inbound path and transport details, including source and destination ports (
#30) show/shortcutsnow presents canonical camelcase-style shorthand boundaries more explicitly, and the one-letterbalias is accepted forbye(#22)- spot posting can now be rate-limited per user across telnet, public web, and sysop web, with shared defaults and sysop overrides (
#31) - sysop web now shows visible
Last Pathcolumns for local users, blocked users, and system operators, andRecent Spotsnow includes the originatingNode
Existing 1.0.0 installations should be upgraded in place with:
git pull --ff-only
sudo ./deploy/upgrade.sh
sudo ./deploy/doctor.shThe cumulative upgrader used by deploy/upgrade.sh hashes any legacy plaintext passwords still stored in user_prefs, seeds config/strings.toml if it is missing, preserves compatibility with older configs that predate newer optional sections such as [qrz], and keeps the existing config, data, and logs in place.
- configurable telnet prompt templates via
node.prompt_template sysop/setpromptfor runtime prompt template changes
#4install/bootstrap credential visibility#20default access policy for non-authenticated users#3peer cleanup and disconnect handling hardening#5WWV/WCY persistence and related operator syntax cleanup#6telnet login sanitization and negotiation-byte handling#7node heartbeat / keepalive behavior for linked peers#8public web frequency display alignment with telnet formatting#13show/wm7dimplementation instead of a status stub
- telnet prompts now render from a template instead of a fixed
{node}{suffix}form show/commandsnow returns grouped operator help with family filtering- solar, moon, and grayline views can use stored QRA/node grid context instead of requiring explicit forwarded latitude/longitude
- public web footer/version text now follows
pycluster.__version__ - web spot table frequency column is labeled
Frequencyto match the current kHz-style formatting - install and repair now print the bootstrap
SYSOPcredentials prominently, point at/root/pycluster-initial-sysop.txt, and require explicit acknowledgement in interactive installs - default access fallback now treats non-authenticated users as read-only for spot and announce posting until access is explicitly elevated or overridden
- upgrade runs now hash any legacy plaintext passwords still stored in
user_prefsand seedconfig/strings.tomlwhen it is missing - protocol-health views now distinguish current flapping from older flap history instead of treating an old flap score as a permanent alert
- bootstrap
SYSOPpassword seeding now stores a hash instead of plaintext (#4) - non-authenticated users no longer inherit permissive default posting access for spots and announces (
#20) - blocked users are denied consistently across telnet, sysop web, and public web login paths
- DXSpider-compatible keepalive handling now replies to
PC51pings correctly, allowing validated linked-peer sessions to survive past the old ~900 second timeout window (#3,#7) - login callsign sanitization in the telnet path
- public and sysop web bootstrap access documentation for the initial
SYSOPaccount - telnet login corruption caused by negotiation bytes (
#6) - peer heartbeat / disconnect behavior regressions (
#3,#7) show/wm7dreturning gateway-status output instead of lookup behavior (#13)- public web frequency display/version consistency issues (
#8)
- System Operator web console with runtime, user, peer, protocol, audit, and security views
- public web login, posting, watch, and profile editing flows
- weekly CTY refresh service and timer
- bootstrap
SYSOPaccount creation with one-time note output - sysop web auth now accepts the bootstrap
SYSOPoperator record consistently - nginx/TLS deployment helper
- fail2ban filters and jails for pyCluster auth failures
- auth-failure log rotation and imported
badip.localfail2ban reconciliation
- telnet output was cleaned up for readability and 80-column friendliness
sysop/*command surface is explicit and operator-focused- deploy scripts now support validated Debian-family and EL-family Linux targets
- docs now reflect validated hosts, minimum sizing, and unsupported older platforms
- version sourcing now comes from
pycluster.__version__
- graceful shutdown with active telnet sessions
- duplicate live spot rendering on multi-link ingest
- CTY gaps such as
TX5EU - multiple System Operator UI workflow and clarity issues
- deployment issues around:
- SELinux
- Python 3.11+ selection
- fail2ban startup
- DB ownership
- uninstall cleanup
- deploy sync overwriting live config/data/log directories
- protocol flap scoring falsely reacting to normal peer state churn