Add VPN configuration tools and agent documentation
Created comprehensive VPN setup tooling for Peaceful Spirit L2TP/IPsec connection and enhanced agent documentation framework. VPN Configuration (PST-NW-VPN): - Setup-PST-L2TP-VPN.ps1: Automated L2TP/IPsec setup with split-tunnel and DNS - Connect-PST-VPN.ps1: Connection helper with PPP adapter detection, DNS (192.168.0.2), and route config (192.168.0.0/24) - Connect-PST-VPN-Standalone.ps1: Self-contained connection script for remote deployment - Fix-PST-VPN-Auth.ps1: Authentication troubleshooting for CHAP/MSChapv2 - Diagnose-VPN-Interface.ps1: Comprehensive VPN interface and routing diagnostic - Quick-Test-VPN.ps1: Fast connectivity verification (DNS/router/routes) - Add-PST-VPN-Route-Manual.ps1: Manual route configuration helper - vpn-connect.bat, vpn-disconnect.bat: Simple batch file shortcuts - OpenVPN config files (Windows-compatible, abandoned for L2TP) Key VPN Implementation Details: - L2TP creates PPP adapter with connection name as interface description - UniFi auto-configures DNS (192.168.0.2) but requires manual route to 192.168.0.0/24 - Split-tunnel enabled (only remote traffic through VPN) - All-user connection for pre-login auto-connect via scheduled task - Authentication: CHAP + MSChapv2 for UniFi compatibility Agent Documentation: - AGENT_QUICK_REFERENCE.md: Quick reference for all specialized agents - documentation-squire.md: Documentation and task management specialist agent - Updated all agent markdown files with standardized formatting Project Organization: - Moved conversation logs to dedicated directories (guru-connect-conversation-logs, guru-rmm-conversation-logs) - Cleaned up old session JSONL files from projects/msp-tools/ - Added guru-connect infrastructure (agent, dashboard, proto, scripts, .gitea workflows) - Added guru-rmm server components and deployment configs Technical Notes: - VPN IP pool: 192.168.4.x (client gets 192.168.4.6) - Remote network: 192.168.0.0/24 (router at 192.168.0.10) - PSK: rrClvnmUeXEFo90Ol+z7tfsAZHeSK6w7 - Credentials: pst-admin / 24Hearts$ Files: 15 VPN scripts, 2 agent docs, conversation log reorganization, guru-connect/guru-rmm infrastructure additions Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
155
projects/msp-tools/guru-rmm/server/src/main.rs
Normal file
155
projects/msp-tools/guru-rmm/server/src/main.rs
Normal file
@@ -0,0 +1,155 @@
|
||||
//! GuruRMM Server - RMM Management Server
|
||||
//!
|
||||
//! Provides the backend API and WebSocket endpoint for GuruRMM agents.
|
||||
//! Features:
|
||||
//! - Agent registration and management
|
||||
//! - Real-time WebSocket communication with agents
|
||||
//! - Metrics storage and retrieval
|
||||
//! - Command execution via agents
|
||||
//! - Dashboard authentication
|
||||
|
||||
mod api;
|
||||
mod auth;
|
||||
mod config;
|
||||
mod db;
|
||||
mod updates;
|
||||
mod ws;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::Result;
|
||||
use axum::{
|
||||
routing::{get, post},
|
||||
Router,
|
||||
};
|
||||
use sqlx::postgres::PgPoolOptions;
|
||||
use tokio::sync::RwLock;
|
||||
use tower_http::cors::{Any, CorsLayer};
|
||||
use tower_http::trace::TraceLayer;
|
||||
use tracing::info;
|
||||
|
||||
use crate::config::ServerConfig;
|
||||
use crate::updates::UpdateManager;
|
||||
use crate::ws::AgentConnections;
|
||||
|
||||
/// Shared application state
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
/// Database connection pool
|
||||
pub db: sqlx::PgPool,
|
||||
|
||||
/// Server configuration
|
||||
pub config: Arc<ServerConfig>,
|
||||
|
||||
/// Connected agents (WebSocket connections)
|
||||
pub agents: Arc<RwLock<AgentConnections>>,
|
||||
|
||||
/// Agent update manager
|
||||
pub updates: Arc<UpdateManager>,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
// Load environment variables from .env file
|
||||
dotenvy::dotenv().ok();
|
||||
|
||||
// Initialize logging
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(
|
||||
tracing_subscriber::EnvFilter::from_default_env()
|
||||
.add_directive("gururmm_server=info".parse()?)
|
||||
.add_directive("tower_http=debug".parse()?)
|
||||
.add_directive("info".parse()?),
|
||||
)
|
||||
.init();
|
||||
|
||||
info!("GuruRMM Server starting...");
|
||||
|
||||
// Load configuration
|
||||
let config = ServerConfig::from_env()?;
|
||||
info!("Server configuration loaded");
|
||||
|
||||
// Connect to database
|
||||
info!("Connecting to database...");
|
||||
let db = PgPoolOptions::new()
|
||||
.max_connections(config.database.max_connections)
|
||||
.connect(&config.database.url)
|
||||
.await?;
|
||||
info!("Database connected");
|
||||
|
||||
// Run migrations
|
||||
info!("Running database migrations...");
|
||||
sqlx::migrate!("./migrations").run(&db).await?;
|
||||
info!("Migrations complete");
|
||||
|
||||
// Initialize update manager
|
||||
let update_manager = UpdateManager::new(
|
||||
config.updates.downloads_dir.clone(),
|
||||
config.updates.downloads_base_url.clone(),
|
||||
config.updates.auto_update_enabled,
|
||||
config.updates.update_timeout_secs,
|
||||
);
|
||||
|
||||
// Initial scan for available versions
|
||||
info!("Scanning for available agent versions...");
|
||||
if let Err(e) = update_manager.scan_versions().await {
|
||||
tracing::warn!("Failed to scan agent versions: {} (continuing without auto-update)", e);
|
||||
}
|
||||
|
||||
let update_manager = Arc::new(update_manager);
|
||||
|
||||
// Spawn background scanner (handle is intentionally not awaited - runs until server shutdown)
|
||||
let _scanner_handle = update_manager.spawn_scanner(config.updates.scan_interval_secs);
|
||||
info!(
|
||||
"Auto-update: {} (scan interval: {}s)",
|
||||
if config.updates.auto_update_enabled { "enabled" } else { "disabled" },
|
||||
config.updates.scan_interval_secs
|
||||
);
|
||||
|
||||
// Create shared state
|
||||
let state = AppState {
|
||||
db,
|
||||
config: Arc::new(config.clone()),
|
||||
agents: Arc::new(RwLock::new(AgentConnections::new())),
|
||||
updates: update_manager,
|
||||
};
|
||||
|
||||
// Build router
|
||||
let app = build_router(state);
|
||||
|
||||
// Start server
|
||||
let addr = format!("{}:{}", config.server.host, config.server.port);
|
||||
info!("Starting server on {}", addr);
|
||||
|
||||
let listener = tokio::net::TcpListener::bind(&addr).await?;
|
||||
axum::serve(listener, app).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Build the application router
|
||||
fn build_router(state: AppState) -> Router {
|
||||
// CORS configuration (allow dashboard access)
|
||||
let cors = CorsLayer::new()
|
||||
.allow_origin(Any)
|
||||
.allow_methods(Any)
|
||||
.allow_headers(Any);
|
||||
|
||||
Router::new()
|
||||
// Health check
|
||||
.route("/health", get(health_check))
|
||||
// WebSocket endpoint for agents
|
||||
.route("/ws", get(ws::ws_handler))
|
||||
// API routes
|
||||
.nest("/api", api::routes())
|
||||
// Middleware
|
||||
.layer(TraceLayer::new_for_http())
|
||||
.layer(cors)
|
||||
// State
|
||||
.with_state(state)
|
||||
}
|
||||
|
||||
/// Health check endpoint
|
||||
async fn health_check() -> &'static str {
|
||||
"OK"
|
||||
}
|
||||
Reference in New Issue
Block a user