This document covers security architecture, critical operational concerns, and troubleshooting common issues.
- Transport Security - Meshtastic PSK
- Encryption Architecture
- Master Key Salt - CRITICAL
- Backup Strategy
- Troubleshooting
advBBS authentication commands (!register, !login, !passwd) are sent via Meshtastic direct messages. This approach is similar to IRC's NickServ model, where users send commands via private message to register and authenticate.
The Problem: Meshtastic direct messages are only "private" in that they're addressed to a specific node - they are not encrypted by default. Without PSK (Pre-Shared Key) encryption enabled, anyone with a Meshtastic receiver can intercept:
- Registration commands containing usernames and passwords
- Login attempts
- Password change requests
| Scenario | Protection Level |
|---|---|
| No PSK | ❌ Passwords visible to anyone with a receiver in radio range |
| PSK enabled | ✅ AES-256 encrypted, equivalent to IRC with TLS |
Enable PSK on all nodes in your mesh network:
# Generate and set a random encryption key
meshtastic --ch-set psk random --ch-index 0
# View the generated key (to share with other mesh members)
meshtastic --ch-get psk --ch-index 0
# Set a specific key on other nodes
meshtastic --ch-set psk base64:YOUR_KEY_HERE --ch-index 0Important notes:
- All nodes on the mesh must use the same PSK to communicate
- Share the key securely with mesh members (not over unencrypted radio!)
- Different channels can have different keys
Unlike traditional internet services where traffic is naturally obscured by network infrastructure, radio transmissions are inherently public. Anyone within reception range (~1-10+ km depending on terrain and power) can passively receive all traffic.
With PSK enabled:
- All Meshtastic traffic is encrypted with AES-256
- Only nodes with the correct key can decrypt messages
- BBS commands become as secure as HTTPS/TLS traffic
Even if an attacker intercepts credentials, advBBS provides defense-in-depth:
| Protection | Description |
|---|---|
| Node-based 2FA | Login requires both password AND a pre-registered node ID |
| Password hashing | Argon2id - passwords never stored in plaintext |
| Rate limiting | Brute-force attempts are throttled |
| Encrypted storage | All mail encrypted at rest with per-user keys |
The node-based 2FA means that even with a stolen password, an attacker cannot login from an unregistered node. They would need physical access to a victim's registered Meshtastic device.
| Threat | Without PSK | With PSK |
|---|---|---|
| Password interception | ❌ Vulnerable | ✅ Protected |
| Session hijacking | ✅ Protected | |
| Mail interception | ✅ Fully protected | |
| Replay attacks | ✅ Protected |
Recommendation: Always enable PSK encryption on meshes running advBBS.
advBBS uses a layered encryption system to protect user data:
┌─────────────────────────────────────────────────────────────┐
│ Admin Password │
│ + │
│ Master Key Salt (stored in DB) │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ Argon2id KDF │ │
│ │ (time=3, mem=32MB) │ │
│ └─────────────────────┘ │
│ │ │
│ ▼ │
│ Master Key │
│ │ │
│ ┌───────────────┼───────────────┐ │
│ ▼ ▼ ▼ │
│ User 1 Key User 2 Key User N Key │
│ (encrypted) (encrypted) (encrypted) │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ User 1 Mail User 2 Mail User N Mail │
│ (encrypted) (encrypted) (encrypted) │
└─────────────────────────────────────────────────────────────┘
| Component | Storage | Purpose |
|---|---|---|
| Admin Password | config.toml | Input to master key derivation |
| Master Key Salt | bbs_settings table | Random salt for key derivation |
| Master Key | Memory only | Encrypts/decrypts user keys |
| User Keys | users table (encrypted) | Per-user encryption key |
| Mail Content | messages table (encrypted) | Encrypted with recipient's key |
The master key salt is a random 16-byte value generated once when the BBS is first started. It is stored in the bbs_settings table:
SELECT * FROM bbs_settings WHERE key = 'master_key_salt';The salt is combined with the admin password using Argon2id to derive the master key. This master key is used to encrypt all user encryption keys.
The salt is CRITICAL to data recovery. Without the exact same salt:
- The master key cannot be regenerated (even with correct admin password)
- User encryption keys cannot be decrypted
- All user mail becomes permanently unreadable
- The only recovery is to delete all users and start fresh
Symptoms:
CRITICAL: Master key salt missing but 3 users exist!
User encryption keys cannot be decrypted. Database may be corrupted.
Either restore the bbs_settings table from backup or delete all users.
Cause: The bbs_settings table was truncated, corrupted, or restored from a backup that didn't include the salt.
Resolution:
- Restore the database from a backup that includes the correct salt
- OR delete all users and let them re-register (data loss)
In versions before the safety check was added, if the salt was missing, the BBS would silently generate a new one. Users created before the regeneration would have encryption keys that could never be decrypted.
Symptoms:
InvalidTagerrors when composing/reading mail- "Failed to decrypt message" errors
- Mail works for some users but not others
Cause: User was created with salt A, but the BBS is now using salt B.
Resolution:
- Delete affected users (those created before salt regeneration)
- Have them re-register
Changing the admin password in config.toml will generate a different master key, breaking all existing user encryption.
DO NOT change the admin password after users have registered.
As of v0.4.0, advBBS stores a fingerprint of the admin password in the database and refuses to start if it detects a change while users exist:
CRITICAL: admin_password has changed but 3 users exist!
Changing admin_password after users have registered will break ALL encrypted mail.
Restore the original password in config.toml.
If you must change it:
- Export all user data (if possible)
- Delete the database
- Start fresh with new password
- Never delete or truncate the
bbs_settingstable - Never change the admin password after users exist
- Always backup the full database (includes salt automatically)
- Use Docker volumes to persist
/dataacross container recreations
Check that salt exists and matches your backup:
# Inside container or with access to DB
sqlite3 /data/advbbs.db "SELECT value FROM bbs_settings WHERE key = 'master_key_salt';"The value should be a base64-encoded string like Abc123XyZ...==
If salt is lost but you have a backup:
# Stop BBS
docker stop advbbs
# Restore bbs_settings from backup
sqlite3 /data/advbbs.db "DELETE FROM bbs_settings WHERE key = 'master_key_salt';"
sqlite3 /data/backup.db "SELECT * FROM bbs_settings WHERE key = 'master_key_salt';" | \
sqlite3 /data/advbbs.db
# Restart BBS
docker start advbbsThe automatic backup (via backup_interval_hours) copies the entire SQLite database, including:
userstable (with encrypted keys)messagestable (encrypted mail and posts)bbs_settingstable (including master_key_salt)- All other tables
Configured in config.toml:
[database]
path = "/data/advbbs.db"
backup_path = "/data/backups"
backup_interval_hours = 24# From host (Docker volume)
docker exec advbbs sqlite3 /data/advbbs.db ".backup /data/backups/manual_$(date +%Y%m%d).db"
# Or copy the volume directly
cp /var/lib/docker/volumes/advbbs_data/_data/advbbs.db ~/advbbs_backup_$(date +%Y%m%d).dbThe BBS keeps the last 7 backups automatically. Older backups are deleted.
For critical deployments, consider:
- Copying backups off the host
- Using a separate backup solution (e.g., restic, borg)
- Storing at least one backup with the salt separately
Error: Master key salt missing but X users exist
The safety check is preventing data corruption. See Salt Lost, Users Exist.
Error: Admin password must be changed from default
Edit config.toml and change the admin password from changeme.
Error: InvalidTag or Failed to decrypt message
The user's encryption key cannot be decrypted. This usually means:
- User was created with a different salt
- User was created with a different admin password
Resolution: Delete the affected user via the config tool (option 7 → 4) and have them re-register.
Error: Invalid username or password
- User may be typing wrong password
- User may be banned (check in config tool option 7 → 1)
- Try
!logoutfirst, then!loginagain
Check the logs for ACK status:
docker logs advbbs --tail 100 | grep -E "(ACK|NAK|deliver)"ACK from !nodeId (Xms)- Message was acknowledgedNAK from !nodeId: NO_ROUTE- Recipient not reachableMail composed: X -> Y- Mail was createdMail delivered- Notification was sent
Error: database is locked
Another process is accessing the database. This can happen if:
- The config tool is open while BBS is running (usually OK)
- Backup is in progress
- Multiple BBS instances pointing to same database (don't do this)
Wait a moment and retry, or restart the BBS.