Technical Documentation
This section contains comprehensive technical documentation for DaemonEye, covering implementation details, architecture specifications, and technical guides.
Table of Contents
- Core Monitoring
- Business Tier Features
- Enterprise Tier Features
- Technical Architecture
- Implementation Details
- Performance Considerations
- Security Implementation
- Testing Strategy
- Deployment Considerations
Core Monitoring
The core monitoring system provides real-time process monitoring and threat detection capabilities. This is the foundation of DaemonEye and is available in all tiers.
Read Core Monitoring Documentation →
Business Tier Features
Business tier features extend the core monitoring with additional capabilities including the Security Center, enhanced integrations, and curated rule packs.
Read Business Tier Documentation →
Enterprise Tier Features
Enterprise tier features provide advanced monitoring capabilities including kernel monitoring, network event monitoring, and federated security center architecture.
Read Enterprise Tier Documentation →
Technical Architecture
Component Overview
DaemonEye follows a three-component security architecture:
- ProcMonD: Privileged process monitoring daemon
- daemoneye-agent: User-space orchestrator and alerting
- daemoneye-cli: Command-line interface and management
Data Flow
graph LR A[<b>ProcMonD</b><br/>• Process Enum<br/>• Hashing<br/>• Audit] -->|Process Data<br/>Alerts| B[<b>daemoneye-agent</b><br/>• Alerting<br/>• Rules<br/>• Network<br/>• Storage] B -->|Lifecycle Mgmt<br/>Tasking| A B -->|Query Results<br/>Status| C[<b>daemoneye-cli</b><br/>• Queries<br/>• Config<br/>• Monitor<br/>• Manage] C -->|Commands<br/>Config| B
Technology Stack
- Language: Rust 2024 Edition
- Runtime: Tokio async runtime
- Event Store: redb (pure Rust embedded database)
- Audit Ledger: Certificate Transparency-style Merkle tree
- IPC: Custom Protobuf over Unix Sockets
- CLI: clap v4 with derive macros
- Configuration: figment with hierarchical loading
- Logging: tracing ecosystem with structured JSON
- Testing: cargo-nextest with comprehensive test suite
Implementation Details
Process Collection
The process collection system uses the sysinfo
crate for cross-platform process enumeration:
use sysinfo::{System, SystemExt, ProcessExt};
pub struct ProcessCollector {
system: System,
}
impl ProcessCollector {
pub fn new() -> Self {
Self {
system: System::new_all(),
}
}
pub async fn collect_processes(&mut self) -> Result<Vec<ProcessInfo>, CollectionError> {
self.system.refresh_all();
let processes = self.system
.processes()
.values()
.map(|p| ProcessInfo::from(p))
.collect();
Ok(processes)
}
}
Event Store Operations
DaemonEye uses redb for high-performance event storage:
use redb::{Database, ReadableTable, WritableTable};
pub struct EventStore {
db: Database,
}
impl EventStore {
pub fn new(path: &str) -> Result<Self, redb::Error> {
let db = Database::create(path)?;
Ok(Self { db })
}
pub async fn insert_process(&self, process: &ProcessInfo) -> Result<(), redb::Error> {
let write_txn = self.db.begin_write()?;
{
let mut table = write_txn.open_table(PROCESS_TABLE)?;
let key = process.pid;
let value = serde_json::to_vec(process)?;
table.insert(key, &value)?;
}
write_txn.commit()?;
Ok(())
}
}
Alert System
The alert system provides multi-channel alert delivery:
use async_trait::async_trait;
#[async_trait]
pub trait AlertSink: Send + Sync {
async fn send(&self, alert: &Alert) -> Result<DeliveryResult, DeliveryError>;
async fn health_check(&self) -> HealthStatus;
fn name(&self) -> &str;
}
pub struct AlertManager {
sinks: Vec<Box<dyn AlertSink>>,
}
impl AlertManager {
pub async fn send_alert(&self, alert: Alert) -> Result<(), AlertError> {
let mut results = Vec::new();
for sink in &self.sinks {
let result = sink.send(&alert).await;
results.push(result);
}
// Check if any sink succeeded
if results.iter().any(|r| r.is_ok()) {
Ok(())
} else {
Err(AlertError::DeliveryFailed)
}
}
}
Performance Considerations
Memory Management
DaemonEye is designed for minimal memory usage:
- Process Collection: ~1MB per 1000 processes
- Database Operations: ~10MB for 100,000 records
- Alert Processing: ~1MB for 10,000 alerts
- Total Memory: <100MB under normal operation
CPU Usage
CPU usage is optimized for minimal impact:
- Process Collection: <5% CPU sustained
- Database Operations: <2% CPU for queries
- Alert Processing: <1% CPU for delivery
- Total CPU: <5% sustained during monitoring
Storage Requirements
Storage requirements scale with data retention:
- Process Records: ~1KB per process per collection
- Alert Records: ~500B per alert
- Audit Logs: ~100B per operation
- Total Storage: ~1GB per month for 1000 processes
Security Implementation
Input Validation
All inputs are validated using the validator
crate:
use validator::{Validate, ValidationError};
#[derive(Validate)]
pub struct DetectionRule {
#[validate(length(min = 1, max = 1000))]
pub name: String,
#[validate(custom = "validate_sql")]
pub sql_query: String,
#[validate(range(min = 1, max = 1000))]
pub priority: u32,
}
fn validate_sql(sql: &str) -> Result<(), ValidationError> {
// Parse and validate SQL syntax
let ast = sqlparser::parse(sql)?;
validate_ast(&ast)?;
Ok(())
}
SQL Injection Prevention
Multiple layers of SQL injection prevention:
- AST Validation: Parse and validate SQL queries
- Prepared Statements: Use parameterized queries
- Sandboxed Execution: Isolated query execution
- Input Sanitization: Clean and validate all inputs
Cryptographic Integrity
BLAKE3 hashing and Ed25519 signatures ensure data integrity:
use blake3::Hasher;
use ed25519_dalek::{Keypair, Signature};
pub struct IntegrityChecker {
hasher: Hasher,
keypair: Keypair,
}
impl IntegrityChecker {
pub fn hash_data(&self, data: &[u8]) -> [u8; 32] {
self.hasher.update(data).finalize().into()
}
pub fn sign_data(&self, data: &[u8]) -> Signature {
self.keypair.sign(data)
}
}
Testing Strategy
Unit Testing
Comprehensive unit testing with mocks and test doubles:
#[cfg(test)]
mod tests {
use super::*;
use mockall::mock;
mock! {
pub ProcessCollector {}
#[async_trait]
impl ProcessCollectionService for ProcessCollector {
async fn collect_processes(&self) -> Result<CollectionResult, CollectionError>;
}
}
#[tokio::test]
async fn test_agent_with_mock_collector() {
let mut mock_collector = MockProcessCollector::new();
mock_collector
.expect_collect_processes()
.times(1)
.returning(|| Ok(CollectionResult::default()));
let agent = daemoneye-agent::new(Box::new(mock_collector));
let result = agent.run_collection_cycle().await;
assert!(result.is_ok());
}
}
Integration Testing
Test component interactions and data flow:
#[tokio::test]
async fn test_database_integration() {
let temp_dir = TempDir::new().unwrap();
let db_path = temp_dir.path().join("test.db");
let db = Database::new(&db_path).await.unwrap();
db.create_schema().await.unwrap();
let process = ProcessInfo::default();
db.insert_process(&process).await.unwrap();
let retrieved = db.get_process(process.pid).await.unwrap();
assert_eq!(process.pid, retrieved.pid);
}
Performance Testing
Benchmark critical operations:
use criterion::{black_box, criterion_group, criterion_main, Criterion};
fn benchmark_process_collection(c: &mut Criterion) {
let mut group = c.benchmark_group("process_collection");
group.bench_function("collect_processes", |b| {
b.iter(|| {
let collector = ProcessCollector::new();
black_box(collector.collect_processes())
})
});
group.finish();
}
criterion_group!(benches, benchmark_process_collection);
criterion_main!(benches);
Deployment Considerations
Container Deployment
DaemonEye is designed for containerized deployment:
- Docker: Multi-stage builds for minimal images
- Kubernetes: DaemonSet for process monitoring
- Security: Non-root containers with minimal privileges
- Resource Limits: Configurable CPU and memory limits
Platform Support
Cross-platform support with platform-specific optimizations:
- Linux: Primary target with
/proc
filesystem access - macOS: Native process enumeration with security framework
- Windows: Windows API process access with service deployment
Configuration Management
Hierarchical configuration with multiple sources:
- Command-line flags (highest precedence)
- Environment variables (
DaemonEye_*
) - User configuration file (
~/.config/daemoneye/config.yaml
) - System configuration file (
/etc/daemoneye/config.yaml
) - Embedded defaults (lowest precedence)
This technical documentation provides comprehensive information about DaemonEye's implementation. For specific implementation details, consult the individual technical guides.