HBBS Patches Documentation
This directory contains the modified RustDesk HBBS server files that enable:
- Real-time device status monitoring through HTTP API
- Device banning system - native ban check during registration
Features
🔒 Device Banning System (NEW!)
Native integration with BetterDesk Console ban functionality. When a device is banned:
- Registration attempts are rejected at source by HBBS
- No "race conditions" - 100% effective blocking
- Minimal performance impact (single SQL query per registration)
- Fail-open policy - system continues if database unavailable
How it works:
Device connects → HBBS checks is_banned → Rejects if banned=1
See: BAN_CHECK_PATCH.md for technical details.
Modified Files
1. http_api.rs (New File)
Purpose: HTTP REST API server for device status queries
Key Features:
- RESTful API endpoints using Axum framework
- Real-time device status detection (memory-based, not database)
- CORS support for web console integration
- JSON response format
Endpoints:
GET /api/health- Health check endpointGET /api/peers- List all registered peers with online status
Technology Stack:
- Axum web framework
- Tower-HTTP for CORS middleware
- Tokio async runtime
Status Detection Algorithm:
const REG_TIMEOUT: i32 = 30_000; // 30 seconds in milliseconds
// A peer is considered online if:
// 1. It exists in the PeerMap (in-memory storage)
// 2. Last registration time < 30 seconds ago
if let Some(peer) = peer_map.get_in_memory(&id).await {
let elapsed = peer.read().await.last_reg_time.elapsed().as_millis() as i32;
online = elapsed < REG_TIMEOUT;
}
This matches the exact same mechanism used by the RustDesk desktop client to determine online status.
2. main.rs
Purpose: Entry point for HBBS server
Modifications:
- Added
api_portparameter (default: 21114) - Passes API port to
RendezvousServer::start() - No changes to core HBBS functionality
Changed Lines:
// Added API port parameter
RendezvousServer::start(
port,
serial,
&get_arg_or("key", "-".to_owned()),
rmem,
21114 // API port
)?;
3. rendezvous_server.rs
Purpose: Main HBBS server managing peer connections
Modifications:
-
Changed PeerMap to Arc for thread-safety:
// Before: pm: PeerMap // After: pm: Arc<PeerMap> -
Added API server spawn:
pub async fn start(..., api_port: u16) -> ResultType<()> { let pm = Arc::new(PeerMap::new().await?); let pm_clone = pm.clone(); // Spawn HTTP API server with shared PeerMap tokio::spawn(async move { crate::http_api::start_api_server(db_path, api_port, pm_clone).await }); // ... rest of the server logic } -
Shared State Architecture:
PeerMapis wrapped inArc<RwLock<...>>for safe concurrent access- Both the main HBBS server and HTTP API access the same
PeerMap - Real-time synchronization without database polling
Why This Approach:
- Zero latency: No database queries needed for status
- Authentic: Uses the same logic as RustDesk client
- Scalable: In-memory lookups are extremely fast
- Consistent: Single source of truth (PeerMap)
4. peer.rs
Purpose: PeerMap management (in-memory peer storage)
Modifications:
-
Changed
update_pk()signature for Arc compatibility:// Before: pub(crate) async fn update_pk(&mut self, ...) // After: pub(crate) async fn update_pk(&self, ...)Reason:
Arc<PeerMap>doesn't allow mutable references. Changed to use interior mutability (RwLock) instead. -
Preserved all existing functionality:
- Peer registration
- Public key updates
- Database synchronization
- Memory management
No breaking changes - all original HBBS functionality remains intact.
Architecture Overview
┌─────────────────────────────────────────────────────────────┐
│ RustDesk Client │
│ (sends heartbeat every ~45s) │
└─────────────────────┬───────────────────────────────────────┘
│ Register peer
▼
┌─────────────────────────────┐
│ RendezvousServer │
│ (HBBS Main Server) │
└─────────────┬───────────────┘
│
▼
┌─────────────────────────────┐
│ Arc<PeerMap> │
│ (Shared In-Memory Store) │
│ - peer_id → LockPeer │
│ - last_reg_time: Instant │
└─────────────┬───────────────┘
│
▼
┌─────────────────────────────┐
│ HTTP API Server │
│ (Port 21114) │
└─────────────┬───────────────┘
│ Query status
▼
┌─────────────────────────────┐
│ Web Console │
│ (Flask + JavaScript) │
└─────────────────────────────┘
Implementation Details
Why Memory-Based Instead of Database?
Original RustDesk behavior:
- HBBS stores peers in memory (
PeerMap) - Database (
db_v2.sqlite3) is used for persistence only - The
statuscolumn in database is NEVER updated by HBBS - Online detection happens in real-time using
last_reg_time.elapsed()
Our implementation:
- ✅ Uses the same memory-based approach
- ✅ Shares
PeerMapbetween main server and API - ✅ Calculates status on-demand (no stale data)
- ✅ 30-second timeout matches RustDesk client behavior
REG_TIMEOUT Constant
const REG_TIMEOUT: i32 = 30_000; // 30 seconds
This is the official RustDesk timeout value found in the original source code (rendezvous_server.rs:781).
A peer must re-register within 30 seconds to remain online. This is why RustDesk clients send heartbeats approximately every 30-45 seconds.
Thread Safety
All modifications maintain thread safety:
Arc<PeerMap>allows shared ownership across threadsRwLock<HashMap<...>>provides concurrent read access- Write operations (peer registration) are already synchronized
- No race conditions or data corruption possible
Compilation Requirements
Additional Dependencies (added automatically by install.sh):
[dependencies]
axum = { version = "0.7", features = ["http1", "json", "tokio"] }
tower-http = { version = "0.5", features = ["cors"] }
tokio = { version = "1", features = ["full"] }
Build Command:
cargo build --release --bin hbbs
Binary output: target/release/hbbs
Testing the API
Health Check:
curl http://localhost:21114/api/health
Response:
{
"success": true,
"data": "RustDesk API is running",
"error": null
}
List Peers:
curl http://localhost:21114/api/peers
Response:
{
"success": true,
"data": [
{
"id": "1234567890",
"note": "Server NYC",
"online": true
},
{
"id": "9876543210",
"note": "Workstation",
"online": false
}
],
"error": null
}
Compatibility
- RustDesk Version: Tested with HBBS 1.1.9+
- Rust Version: 1.70+
- Operating Systems: Linux (Ubuntu 20.04+, Debian 11+, CentOS 8+)
- Architecture: x86_64, ARM64
Security Considerations
-
API Binding: By default, API listens on
0.0.0.0:21114- Consider using a firewall to restrict access
- Or modify
http_api.rsto bind to127.0.0.1only
-
No Authentication: Current implementation has no API authentication
- Suitable for internal networks
- For public exposure, add authentication middleware
-
CORS: Enabled for all origins (
*)- Modify
http_api.rsCORS settings if needed
- Modify
Building with Ban Check
Quick Build (Automated)
# Make script executable
chmod +x build.sh
# Run automated build
./build.sh
This will:
- Clone RustDesk Server v1.1.14
- Apply all patches (HTTP API + Ban Check)
- Compile
hbbs - Create installation package
Manual Build
# Clone repository
git clone --branch 1.1.14 https://github.com/rustdesk/rustdesk-server.git
cd rustdesk-server
# Copy patched files
cp ../hbbs-patch/src/*.rs src/
# Or apply patches manually:
# 1. Add is_device_banned() to src/database.rs (see database_patch.rs)
# 2. Add ban check to update_pk() in src/peer.rs (see peer_patch.rs)
# Compile
cargo build --release --bin hbbs
# Result: target/release/hbbs
Installation on Server
# 1. Stop HBBS
sudo systemctl stop hbbs
# 2. Backup current binary
sudo cp /opt/rustdesk/hbbs /opt/rustdesk/hbbs.backup
# 3. Install new binary
sudo cp target/release/hbbs /opt/rustdesk/
sudo chmod +x /opt/rustdesk/hbbs
# 4. Restart
sudo systemctl start hbbs
# 5. Verify
sudo journalctl -u hbbs -n 20 --no-pager
Testing Ban Functionality
# 1. Ban a device in database
sqlite3 /opt/rustdesk/db_v2.sqlite3 "UPDATE peer SET is_banned=1 WHERE id='123456789'"
# 2. Try to connect from that device
# 3. Check logs - should see:
# "Registration REJECTED for device 123456789: DEVICE IS BANNED"
# 4. Unban
sqlite3 /opt/rustdesk/db_v2.sqlite3 "UPDATE peer SET is_banned=0 WHERE id='123456789'"
Maintenance
Updating to New RustDesk Versions
- Clone the new RustDesk version
- Apply patches from this directory
- Test compilation
- Check for API compatibility
- Update if needed
Reverting to Original HBBS
- Stop the service:
sudo systemctl stop rustdesksignal - Restore from backup:
sudo cp /opt/rustdesk-backup-*/hbbs /opt/rustdesk/ - Start the service:
sudo systemctl start rustdesksignal
Contributing
If you improve these patches or add features:
- Test thoroughly with real RustDesk clients
- Ensure backward compatibility
- Update this documentation
- Submit a pull request
License
These modifications maintain the original RustDesk AGPL-3.0 license.
Credits
- Original RustDesk Server: https://github.com/rustdesk/rustdesk-server
- Enhancement: BetterDesk Console project