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:
299
projects/msp-tools/guru-rmm/agent/src/transport/mod.rs
Normal file
299
projects/msp-tools/guru-rmm/agent/src/transport/mod.rs
Normal file
@@ -0,0 +1,299 @@
|
||||
//! Transport layer for agent-server communication
|
||||
//!
|
||||
//! Handles WebSocket connection to the GuruRMM server with:
|
||||
//! - Auto-reconnection on disconnect
|
||||
//! - Authentication via API key
|
||||
//! - Sending metrics and receiving commands
|
||||
//! - Heartbeat to maintain connection
|
||||
|
||||
mod websocket;
|
||||
|
||||
pub use websocket::WebSocketClient;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Messages sent from agent to server
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(tag = "type", content = "payload")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AgentMessage {
|
||||
/// Authentication message (sent on connect)
|
||||
Auth(AuthPayload),
|
||||
|
||||
/// Metrics report
|
||||
Metrics(crate::metrics::SystemMetrics),
|
||||
|
||||
/// Network state update (sent on connect and when interfaces change)
|
||||
NetworkState(crate::metrics::NetworkState),
|
||||
|
||||
/// Command execution result
|
||||
CommandResult(CommandResultPayload),
|
||||
|
||||
/// Watchdog event (service stopped, restarted, etc.)
|
||||
WatchdogEvent(WatchdogEventPayload),
|
||||
|
||||
/// Update result (success, failure, rollback)
|
||||
UpdateResult(UpdateResultPayload),
|
||||
|
||||
/// Heartbeat to keep connection alive
|
||||
Heartbeat,
|
||||
}
|
||||
|
||||
/// Authentication payload
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AuthPayload {
|
||||
/// API key for this agent (or site)
|
||||
pub api_key: String,
|
||||
|
||||
/// Unique device identifier (hardware-derived)
|
||||
pub device_id: String,
|
||||
|
||||
/// Hostname of this machine
|
||||
pub hostname: String,
|
||||
|
||||
/// Operating system type
|
||||
pub os_type: String,
|
||||
|
||||
/// Operating system version
|
||||
pub os_version: String,
|
||||
|
||||
/// Agent version
|
||||
pub agent_version: String,
|
||||
|
||||
/// Architecture (amd64, arm64, etc.)
|
||||
#[serde(default = "default_arch")]
|
||||
pub architecture: String,
|
||||
|
||||
/// Previous version if reconnecting after update
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub previous_version: Option<String>,
|
||||
|
||||
/// Update ID if reconnecting after update
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub pending_update_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
fn default_arch() -> String {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{ "amd64".to_string() }
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
{ "arm64".to_string() }
|
||||
#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
|
||||
{ "unknown".to_string() }
|
||||
}
|
||||
|
||||
/// Command execution result payload
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CommandResultPayload {
|
||||
/// Command ID (from the server)
|
||||
pub command_id: Uuid,
|
||||
|
||||
/// Exit code (0 = success)
|
||||
pub exit_code: i32,
|
||||
|
||||
/// Standard output
|
||||
pub stdout: String,
|
||||
|
||||
/// Standard error
|
||||
pub stderr: String,
|
||||
|
||||
/// Execution duration in milliseconds
|
||||
pub duration_ms: u64,
|
||||
}
|
||||
|
||||
/// Watchdog event payload
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct WatchdogEventPayload {
|
||||
/// Service or process name
|
||||
pub name: String,
|
||||
|
||||
/// Event type
|
||||
pub event: WatchdogEvent,
|
||||
|
||||
/// Additional details
|
||||
pub details: Option<String>,
|
||||
}
|
||||
|
||||
/// Types of watchdog events
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum WatchdogEvent {
|
||||
/// Service/process was found stopped
|
||||
Stopped,
|
||||
|
||||
/// Service/process was restarted by the agent
|
||||
Restarted,
|
||||
|
||||
/// Restart attempt failed
|
||||
RestartFailed,
|
||||
|
||||
/// Max restart attempts reached
|
||||
MaxRestartsReached,
|
||||
|
||||
/// Service/process recovered on its own
|
||||
Recovered,
|
||||
}
|
||||
|
||||
/// Messages sent from server to agent
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(tag = "type", content = "payload")]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ServerMessage {
|
||||
/// Authentication acknowledgment
|
||||
AuthAck(AuthAckPayload),
|
||||
|
||||
/// Command to execute
|
||||
Command(CommandPayload),
|
||||
|
||||
/// Configuration update
|
||||
ConfigUpdate(ConfigUpdatePayload),
|
||||
|
||||
/// Agent update command
|
||||
Update(UpdatePayload),
|
||||
|
||||
/// Acknowledgment of received message
|
||||
Ack { message_id: Option<String> },
|
||||
|
||||
/// Error message
|
||||
Error { code: String, message: String },
|
||||
}
|
||||
|
||||
/// Authentication acknowledgment payload
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct AuthAckPayload {
|
||||
/// Whether authentication was successful
|
||||
pub success: bool,
|
||||
|
||||
/// Agent ID assigned by server
|
||||
pub agent_id: Option<Uuid>,
|
||||
|
||||
/// Error message if authentication failed
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
/// Command payload from server
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CommandPayload {
|
||||
/// Unique command ID
|
||||
pub id: Uuid,
|
||||
|
||||
/// Type of command
|
||||
pub command_type: CommandType,
|
||||
|
||||
/// Command text to execute
|
||||
pub command: String,
|
||||
|
||||
/// Optional timeout in seconds
|
||||
pub timeout_seconds: Option<u64>,
|
||||
|
||||
/// Whether to run as elevated/admin
|
||||
pub elevated: bool,
|
||||
}
|
||||
|
||||
/// Types of commands
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CommandType {
|
||||
/// Shell command (cmd on Windows, bash on Unix)
|
||||
Shell,
|
||||
|
||||
/// PowerShell command (Windows)
|
||||
PowerShell,
|
||||
|
||||
/// Python script
|
||||
Python,
|
||||
|
||||
/// Raw script (requires interpreter path)
|
||||
Script { interpreter: String },
|
||||
}
|
||||
|
||||
/// Configuration update payload
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ConfigUpdatePayload {
|
||||
/// New metrics interval (if changed)
|
||||
pub metrics_interval_seconds: Option<u64>,
|
||||
|
||||
/// Updated watchdog config
|
||||
pub watchdog: Option<WatchdogConfigUpdate>,
|
||||
}
|
||||
|
||||
/// Watchdog configuration update
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct WatchdogConfigUpdate {
|
||||
/// Enable/disable watchdog
|
||||
pub enabled: Option<bool>,
|
||||
|
||||
/// Check interval
|
||||
pub check_interval_seconds: Option<u64>,
|
||||
|
||||
// Services and processes would be included here for remote config updates
|
||||
}
|
||||
|
||||
/// Update command payload from server
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UpdatePayload {
|
||||
/// Unique update ID for tracking
|
||||
pub update_id: Uuid,
|
||||
|
||||
/// Target version to update to
|
||||
pub target_version: String,
|
||||
|
||||
/// Download URL for the new binary
|
||||
pub download_url: String,
|
||||
|
||||
/// SHA256 checksum of the binary
|
||||
pub checksum_sha256: String,
|
||||
|
||||
/// Whether to force update (skip version check)
|
||||
#[serde(default)]
|
||||
pub force: bool,
|
||||
}
|
||||
|
||||
/// Update result payload sent back to server
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UpdateResultPayload {
|
||||
/// Update ID (from the server)
|
||||
pub update_id: Uuid,
|
||||
|
||||
/// Update status
|
||||
pub status: UpdateStatus,
|
||||
|
||||
/// Old version before update
|
||||
pub old_version: String,
|
||||
|
||||
/// New version after update (if successful)
|
||||
pub new_version: Option<String>,
|
||||
|
||||
/// Error message if failed
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
/// Update status codes
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum UpdateStatus {
|
||||
/// Update starting
|
||||
Starting,
|
||||
|
||||
/// Downloading new binary
|
||||
Downloading,
|
||||
|
||||
/// Download complete, verifying
|
||||
Verifying,
|
||||
|
||||
/// Installing (replacing binary)
|
||||
Installing,
|
||||
|
||||
/// Restarting service
|
||||
Restarting,
|
||||
|
||||
/// Update completed successfully
|
||||
Completed,
|
||||
|
||||
/// Update failed
|
||||
Failed,
|
||||
|
||||
/// Rolled back to previous version
|
||||
RolledBack,
|
||||
}
|
||||
Reference in New Issue
Block a user