[TSM.ID].[11031972] PXE : 19 Cangkang -> REAL Implementation (for/if/match/tests)
This commit is contained in:
@@ -1,62 +1,224 @@
|
||||
#![deny(warnings)]
|
||||
// [TSM.ID].[11031972] -- All Rights Reserved. Proprietary & Confidential.
|
||||
use anyhow::{Result, anyhow};
|
||||
use tracing::{info, error};
|
||||
//! [TSM.ID].[11031972] -- Platform X Ecosystem
|
||||
//! xcu-sentinel -- System Watchdog with Resource Monitoring
|
||||
//! CPU/RAM/disk monitoring, threshold alerts, SLA enforcement
|
||||
|
||||
/// THE SENTINEL MATRIX (Phase 53)
|
||||
/// Sistem Imun Predator (Autonomous SOAR & Threat Hunting)
|
||||
pub struct SentinelMatrix;
|
||||
use std::collections::VecDeque;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::SystemTime;
|
||||
|
||||
impl SentinelMatrix {
|
||||
/// PREDATORY THREAT HUNTING
|
||||
/// Mengawasi aktivitas lalu lintas data di level Bare-Metal.
|
||||
/// Jika ada 1 IP yang mencoba menyentuh lebih dari 5 port berbeda dalam 1 detik,
|
||||
/// itu adalah kepastian mutlak dari serangan (Port Scan / Exploit Recon).
|
||||
pub fn hunt_anomalies(log_akses_jaringan: &[(&str, u16)]) -> Result<&'static str> {
|
||||
// Simulasi logika deteksi anomali (Threat Hunting)
|
||||
let mut target_ip = "";
|
||||
let mut port_disentuh = std::collections::HashSet::new();
|
||||
#[derive(Debug)]
|
||||
pub enum SentinelError {
|
||||
ThresholdExceeded(String),
|
||||
MonitorFailed(String),
|
||||
ConfigError(String),
|
||||
}
|
||||
|
||||
for (ip, port) in log_akses_jaringan {
|
||||
if target_ip == "" {
|
||||
target_ip = ip;
|
||||
impl std::fmt::Display for SentinelError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::ThresholdExceeded(e) => write!(f, "Threshold exceeded: {e}"),
|
||||
Self::MonitorFailed(e) => write!(f, "Monitor failed: {e}"),
|
||||
Self::ConfigError(e) => write!(f, "Config error: {e}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for SentinelError {}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ResourceSnapshot {
|
||||
pub cpu_percent: f64,
|
||||
pub memory_used_mb: u64,
|
||||
pub memory_total_mb: u64,
|
||||
pub disk_used_percent: f64,
|
||||
pub open_connections: u32,
|
||||
pub timestamp: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AlertThreshold {
|
||||
pub cpu_critical: f64,
|
||||
pub cpu_warning: f64,
|
||||
pub memory_critical_percent: f64,
|
||||
pub memory_warning_percent: f64,
|
||||
pub disk_critical_percent: f64,
|
||||
pub response_time_ms_critical: u64,
|
||||
}
|
||||
|
||||
impl Default for AlertThreshold {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
cpu_critical: 90.0,
|
||||
cpu_warning: 70.0,
|
||||
memory_critical_percent: 85.0,
|
||||
memory_warning_percent: 70.0,
|
||||
disk_critical_percent: 90.0,
|
||||
response_time_ms_critical: 5000,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum AlertLevel { Info, Warning, Critical, Fatal }
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Alert {
|
||||
pub level: AlertLevel,
|
||||
pub resource: String,
|
||||
pub message: String,
|
||||
pub value: f64,
|
||||
pub threshold: f64,
|
||||
pub timestamp: u64,
|
||||
}
|
||||
|
||||
pub struct Sentinel {
|
||||
thresholds: AlertThreshold,
|
||||
history: Arc<Mutex<VecDeque<ResourceSnapshot>>>,
|
||||
alerts: Arc<Mutex<Vec<Alert>>>,
|
||||
max_history: usize,
|
||||
}
|
||||
|
||||
impl Sentinel {
|
||||
pub fn new(thresholds: AlertThreshold, max_history: usize) -> Self {
|
||||
Self {
|
||||
thresholds,
|
||||
history: Arc::new(Mutex::new(VecDeque::with_capacity(max_history))),
|
||||
alerts: Arc::new(Mutex::new(Vec::new())),
|
||||
max_history,
|
||||
}
|
||||
}
|
||||
|
||||
/// Record a resource snapshot and check thresholds
|
||||
pub fn record(&self, snapshot: ResourceSnapshot) -> Result<Vec<Alert>, SentinelError> {
|
||||
let mut new_alerts = Vec::new();
|
||||
let ts = snapshot.timestamp;
|
||||
|
||||
// CPU check
|
||||
if snapshot.cpu_percent >= self.thresholds.cpu_critical {
|
||||
new_alerts.push(Alert {
|
||||
level: AlertLevel::Critical,
|
||||
resource: "cpu".into(),
|
||||
message: format!("CPU {}% >= {}%", snapshot.cpu_percent, self.thresholds.cpu_critical),
|
||||
value: snapshot.cpu_percent,
|
||||
threshold: self.thresholds.cpu_critical,
|
||||
timestamp: ts,
|
||||
});
|
||||
} else if snapshot.cpu_percent >= self.thresholds.cpu_warning {
|
||||
new_alerts.push(Alert {
|
||||
level: AlertLevel::Warning,
|
||||
resource: "cpu".into(),
|
||||
message: format!("CPU {}% >= {}%", snapshot.cpu_percent, self.thresholds.cpu_warning),
|
||||
value: snapshot.cpu_percent,
|
||||
threshold: self.thresholds.cpu_warning,
|
||||
timestamp: ts,
|
||||
});
|
||||
}
|
||||
|
||||
// Memory check
|
||||
let mem_percent = if snapshot.memory_total_mb > 0 {
|
||||
(snapshot.memory_used_mb as f64 / snapshot.memory_total_mb as f64) * 100.0
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
if mem_percent >= self.thresholds.memory_critical_percent {
|
||||
new_alerts.push(Alert {
|
||||
level: AlertLevel::Critical,
|
||||
resource: "memory".into(),
|
||||
message: format!("Memory {:.1}% >= {}%", mem_percent, self.thresholds.memory_critical_percent),
|
||||
value: mem_percent,
|
||||
threshold: self.thresholds.memory_critical_percent,
|
||||
timestamp: ts,
|
||||
});
|
||||
} else if mem_percent >= self.thresholds.memory_warning_percent {
|
||||
new_alerts.push(Alert {
|
||||
level: AlertLevel::Warning,
|
||||
resource: "memory".into(),
|
||||
message: format!("Memory {:.1}% >= {}%", mem_percent, self.thresholds.memory_warning_percent),
|
||||
value: mem_percent,
|
||||
threshold: self.thresholds.memory_warning_percent,
|
||||
timestamp: ts,
|
||||
});
|
||||
}
|
||||
|
||||
// Disk check
|
||||
if snapshot.disk_used_percent >= self.thresholds.disk_critical_percent {
|
||||
new_alerts.push(Alert {
|
||||
level: AlertLevel::Critical,
|
||||
resource: "disk".into(),
|
||||
message: format!("Disk {:.1}% >= {}%", snapshot.disk_used_percent, self.thresholds.disk_critical_percent),
|
||||
value: snapshot.disk_used_percent,
|
||||
threshold: self.thresholds.disk_critical_percent,
|
||||
timestamp: ts,
|
||||
});
|
||||
}
|
||||
|
||||
// Store history
|
||||
if let Ok(mut hist) = self.history.lock() {
|
||||
if hist.len() >= self.max_history {
|
||||
hist.pop_front();
|
||||
}
|
||||
if *ip == target_ip {
|
||||
port_disentuh.insert(port);
|
||||
hist.push_back(snapshot);
|
||||
}
|
||||
|
||||
// Store alerts
|
||||
if let Ok(mut alert_log) = self.alerts.lock() {
|
||||
for a in &new_alerts {
|
||||
alert_log.push(a.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Jika 1 IP menyentuh terlalu banyak ruang tertutup, SOAR memicu Mode Karantina
|
||||
if port_disentuh.len() > 5 {
|
||||
error!("SENTINEL: ANCAMAN KRITIS! IP [{}] mencoba menjebol {} pelabuhan secara brutal.", target_ip, port_disentuh.len());
|
||||
return Err(anyhow!("INTRUSION_DETECTED"));
|
||||
Ok(new_alerts)
|
||||
}
|
||||
|
||||
/// Calculate moving average of CPU over last N samples
|
||||
pub fn cpu_moving_average(&self, window: usize) -> Result<f64, SentinelError> {
|
||||
if let Ok(hist) = self.history.lock() {
|
||||
let samples: Vec<f64> = hist.iter().rev().take(window).map(|s| s.cpu_percent).collect();
|
||||
if samples.is_empty() {
|
||||
return Ok(0.0);
|
||||
}
|
||||
let sum: f64 = samples.iter().sum();
|
||||
Ok(sum / samples.len() as f64)
|
||||
} else {
|
||||
Err(SentinelError::MonitorFailed("Lock poisoned".into()))
|
||||
}
|
||||
|
||||
info!("SENTINEL: Jaringan terpantau aman. Tidak ada aktivitas predator musuh.");
|
||||
Ok("AMAN")
|
||||
}
|
||||
|
||||
/// INSTANT NETWORK QUARANTINE (Karantina Absolut)
|
||||
/// Saat bahaya dipastikan, Sentinel tidak mengirim notifikasi ke Admin. Ia mengeksekusi sendiri.
|
||||
/// Ini adalah simulasi dari "Null Routing" atau mencabut kabel jaringan secara digital (Air-Gapping).
|
||||
pub fn execute_instant_quarantine(ip_penyerang: &str) -> String {
|
||||
error!("SENTINEL EKSEKUSI: Memicu Protokol Isolasi VVIP!");
|
||||
error!("SENTINEL EKSEKUSI: Memutuskan rute statis ke IP [{}]...", ip_penyerang);
|
||||
error!("SENTINEL EKSEKUSI: Mengunci pintu masuk (Drop All Inbound).");
|
||||
|
||||
// Hasil mutlak: Serangan terputus di tengah jalan.
|
||||
format!("Karantina Berhasil. Perangkat VVIP kini terisolasi secara digital. Koneksi musuh ke [{}] dihancurkan.", ip_penyerang)
|
||||
/// Detect anomaly: sudden spike compared to moving average
|
||||
pub fn detect_anomaly(&self, current_cpu: f64, window: usize) -> Result<bool, SentinelError> {
|
||||
let avg = self.cpu_moving_average(window)?;
|
||||
if avg > 0.0 {
|
||||
let deviation = (current_cpu - avg).abs() / avg;
|
||||
Ok(deviation > 0.5) // 50% deviation = anomaly
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
/// FORENSIC COUNTER-INTELLIGENCE
|
||||
/// Alih-alih meretas balik, kita mengunci sidik jari serangan musuh untuk dijadikan senjata hukum.
|
||||
pub fn generate_forensic_dossier(ip_penyerang: &str, jenis_serangan: &str) -> String {
|
||||
info!("SENTINEL FORENSIC: Membungkus intelijen serangan...");
|
||||
let laporan = format!(
|
||||
"--- DOKUMEN FORENSIK VVIP ---\nTARGET PENYERANG: {}\nJENIS SERANGAN: {}\nSTATUS: PENYERANG DIISOLASI DAN DIBLOKIR SECARA OTONOM.\nBUKTI TERENKRIPSI SHA-256.",
|
||||
ip_penyerang, jenis_serangan
|
||||
);
|
||||
laporan
|
||||
/// SLA check: uptime percentage
|
||||
pub fn calculate_uptime(&self, total_checks: u64, failed_checks: u64) -> Result<f64, SentinelError> {
|
||||
if total_checks == 0 {
|
||||
return Err(SentinelError::ConfigError("No checks recorded".into()));
|
||||
}
|
||||
let uptime = ((total_checks - failed_checks) as f64 / total_checks as f64) * 100.0;
|
||||
Ok(uptime)
|
||||
}
|
||||
|
||||
/// Get current epoch timestamp
|
||||
pub fn now_epoch() -> u64 {
|
||||
SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.map(|d| d.as_secs())
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn get_alerts(&self) -> Vec<Alert> {
|
||||
self.alerts.lock().map(|a| a.clone()).unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn get_history(&self) -> Vec<ResourceSnapshot> {
|
||||
self.history.lock().map(|h| h.iter().cloned().collect()).unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,28 +227,51 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_predatory_defense_annihilation() {
|
||||
// 1. UJI THREAT HUNTING
|
||||
// Simulasi serangan agresif dari sebuah botnet peretas
|
||||
let ip_musuh = "203.0.113.88";
|
||||
let log_serangan = vec![
|
||||
(ip_musuh, 22), (ip_musuh, 80), (ip_musuh, 443),
|
||||
(ip_musuh, 3306), (ip_musuh, 5432), (ip_musuh, 8080)
|
||||
];
|
||||
|
||||
let deteksi = SentinelMatrix::hunt_anomalies(&log_serangan);
|
||||
assert!(deteksi.is_err());
|
||||
println!("THREAT HUNTING BERHASIL: Sentinel mengendus pergerakan musuh sebelum mereka masuk.");
|
||||
fn test_cpu_critical_alert() {
|
||||
let sentinel = Sentinel::new(AlertThreshold::default(), 100);
|
||||
let snap = ResourceSnapshot {
|
||||
cpu_percent: 95.0, memory_used_mb: 4000, memory_total_mb: 8000,
|
||||
disk_used_percent: 50.0, open_connections: 100, timestamp: 1000,
|
||||
};
|
||||
let alerts = sentinel.record(snap).unwrap();
|
||||
assert!(!alerts.is_empty());
|
||||
assert!(matches!(alerts[0].level, AlertLevel::Critical));
|
||||
}
|
||||
|
||||
// 2. UJI KARANTINA INSTAN (Automated Response)
|
||||
// Karena deteksi gagal (Err), Sentinel Otonom langsung membekukan jaringan.
|
||||
let eksekusi = SentinelMatrix::execute_instant_quarantine(ip_musuh);
|
||||
assert!(eksekusi.contains("dihancurkan"));
|
||||
println!("KARANTINA INSTAN BERHASIL: Mesin memutus kabel digital VVIP dalam 0 ms. Musuh lumpuh.");
|
||||
#[test]
|
||||
fn test_moving_average() {
|
||||
let sentinel = Sentinel::new(AlertThreshold::default(), 100);
|
||||
for i in 0..10 {
|
||||
let snap = ResourceSnapshot {
|
||||
cpu_percent: 30.0 + i as f64, memory_used_mb: 2000,
|
||||
memory_total_mb: 8000, disk_used_percent: 40.0,
|
||||
open_connections: 50, timestamp: i as u64,
|
||||
};
|
||||
let _ = sentinel.record(snap);
|
||||
}
|
||||
let avg = sentinel.cpu_moving_average(5).unwrap();
|
||||
assert!(avg > 30.0 && avg < 40.0);
|
||||
}
|
||||
|
||||
// 3. UJI PENGUMPULAN INTELIJEN MUSUH
|
||||
let intelijen = SentinelMatrix::generate_forensic_dossier(ip_musuh, "Brute-Force Port Scan");
|
||||
assert!(intelijen.contains("DOKUMEN FORENSIK VVIP"));
|
||||
println!("COUNTER-INTELLIGENCE BERHASIL: Sidik jari musuh diamankan. Kita memiliki senjata telak untuk serangan balasan diplomatis/hukum.");
|
||||
#[test]
|
||||
fn test_anomaly_detection() {
|
||||
let sentinel = Sentinel::new(AlertThreshold::default(), 100);
|
||||
for i in 0..20 {
|
||||
let snap = ResourceSnapshot {
|
||||
cpu_percent: 30.0, memory_used_mb: 2000,
|
||||
memory_total_mb: 8000, disk_used_percent: 40.0,
|
||||
open_connections: 50, timestamp: i,
|
||||
};
|
||||
let _ = sentinel.record(snap);
|
||||
}
|
||||
let is_anomaly = sentinel.detect_anomaly(80.0, 10).unwrap();
|
||||
assert!(is_anomaly);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sla_uptime() {
|
||||
let sentinel = Sentinel::new(AlertThreshold::default(), 100);
|
||||
let uptime = sentinel.calculate_uptime(1000, 1).unwrap();
|
||||
assert!(uptime > 99.8);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user