Major security update: HTTP API now binds exclusively to localhost (127.0.0.1) on port 21120, eliminating network exposure and avoiding conflict with RustDesk Pro. Added --api-port parameter, updated all documentation, installation scripts, and web console to use the new port. Included new security and migration guides, updated binaries, and enhanced verification steps for secure deployment.
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