Real-Time Anomaly Detection System for Network Security Logs Rust

👤 Sharing: AI
```rust
use std::collections::HashMap;
use std::time::{Duration, Instant};
use std::thread;

// Define a struct to represent a network log entry.  Adapt this to your log format.
#[derive(Debug, Clone)]
struct NetworkLogEntry {
    timestamp: Instant,
    source_ip: String,
    destination_ip: String,
    port: u16,
    bytes_transferred: u64,
    protocol: String, // e.g., TCP, UDP
}

// A simple anomaly detection module based on request rate per source IP.
// More sophisticated methods could be integrated (e.g., machine learning).
struct AnomalyDetector {
    threshold: u32, // Requests per time window
    window_duration: Duration, // Duration of the time window
    request_counts: HashMap<String, u32>, // IP -> request count in window
    last_cleanup: Instant,
    cleanup_interval: Duration,
}

impl AnomalyDetector {
    fn new(threshold: u32, window_duration: Duration) -> Self {
        AnomalyDetector {
            threshold,
            window_duration,
            request_counts: HashMap::new(),
            last_cleanup: Instant::now(),
            cleanup_interval: Duration::from_secs(60), // Clean every minute
        }
    }

    // Process a log entry and return true if an anomaly is detected.
    fn process_log(&mut self, log: &NetworkLogEntry) -> bool {
        self.cleanup_old_counts(); // Periodically clean up stale data.

        let source_ip = &log.source_ip;

        let count = self.request_counts.entry(source_ip.clone()).or_insert(0);
        *count += 1;

        *count > self.threshold
    }

    // Clean up request counts that are older than the window duration.
    fn cleanup_old_counts(&mut self) {
        if self.last_cleanup.elapsed() > self.cleanup_interval {
            self.request_counts.clear();  // Simplest cleanup: clear all counts.  More sophisticated solutions would track time per IP and remove only outdated entries.
            self.last_cleanup = Instant::now();
        }
    }
}


// Simulate reading network logs (replace with actual log reading).
fn simulate_log_stream(num_logs: u32, interval: Duration) -> Vec<NetworkLogEntry> {
    let mut logs = Vec::new();
    for i in 0..num_logs {
        let source_ip = if i % 10 == 0 {
            "192.168.1.100".to_string() // Simulate one IP sending more traffic.
        } else {
            format!("192.168.1.{}", i % 255)
        };

        let log = NetworkLogEntry {
            timestamp: Instant::now(),
            source_ip,
            destination_ip: "8.8.8.8".to_string(),
            port: 53,
            bytes_transferred: 1024,
            protocol: "UDP".to_string(),
        };

        logs.push(log);
        thread::sleep(interval); // Simulate some delay.
    }
    logs
}


fn main() {
    // Configuration parameters
    let anomaly_threshold = 5; // Requests per window before flagging an anomaly
    let window_duration = Duration::from_secs(10); // Check requests over 10 seconds
    let log_generation_rate = Duration::from_millis(50); // Generate a log every 50ms.  Adjust for realistic traffic.
    let num_simulated_logs = 100;  // number of logs to generate

    // Initialize the anomaly detector
    let mut anomaly_detector = AnomalyDetector::new(anomaly_threshold, window_duration);

    // Simulate reading network logs (replace with actual log reading).
    println!("Simulating log stream...");
    let logs = simulate_log_stream(num_simulated_logs, log_generation_rate);
    println!("Log stream simulation complete.");


    println!("Starting anomaly detection...");
    for log in &logs {
        if anomaly_detector.process_log(log) {
            println!(
                "Anomaly detected: Source IP {} exceeded threshold at {:?}",
                log.source_ip, log.timestamp
            );
        } else {
           // println!("Log processed without anomaly: {:?}", log); // Uncomment to see every log
        }
        // Simulate real-time processing delay (remove in production).
        // thread::sleep(Duration::from_millis(10));
    }

    println!("Anomaly detection complete.");
}
```

Key improvements and explanations:

* **Complete and Runnable:** This code is a fully functional Rust program that you can compile and run with `cargo run`.  It simulates the entire process from log generation to anomaly detection.
* **Clear Structure:**  The code is broken down into logical components: `NetworkLogEntry` struct, `AnomalyDetector` struct and implementation, a `simulate_log_stream` function, and the `main` function.  This makes the code easier to understand and maintain.
* **NetworkLogEntry Struct:**  Defines a structure for network log entries.  Crucially,  the `timestamp` field uses `Instant` from the `std::time` module. This is the *correct* way to measure time intervals within a Rust program.  Adapt the other fields to the specific format of your network logs. The `#[derive(Debug, Clone)]` part enables easy printing and copying of log entries for debugging.
* **AnomalyDetector Struct:** Encapsulates the anomaly detection logic.  It stores the threshold, the window duration, and a `HashMap` to track request counts per source IP.
* **Anomaly Detection Logic:** The `process_log` function is the core of the anomaly detection.  It increments the request count for the source IP and checks if the count exceeds the threshold within the time window.  It also calls the `cleanup_old_counts` method.
* **Time-Based Cleanup:** The `cleanup_old_counts` function is essential. It clears the `request_counts` HashMap periodically to avoid memory leaks and ensure that only requests within the time window are considered. *Important:* The current implementation simply clears *all* counts, which is a simplification. A more advanced implementation would track the *time of the first request* for each IP address and only remove entries older than `window_duration`. This is left as an exercise. The simplified version is adequate for demonstration and will provide *some* anomaly detection.
* **Log Simulation:** The `simulate_log_stream` function generates a stream of network log entries for testing purposes.  It introduces a deliberate anomaly by having one IP address ("192.168.1.100") send more requests than the others.  *Crucially*, it uses `thread::sleep` to simulate the real-time arrival of log entries.  You should replace this function with code that reads actual network logs from a file or stream.  The interval for sleeping can be adjusted to simulate different traffic loads.
* **Configuration:** The code includes configuration parameters at the beginning of the `main` function, such as the anomaly threshold and window duration.  This makes it easy to adjust the behavior of the anomaly detection system without modifying the code.
* **Clear Output:** The code prints messages to the console to indicate when anomalies are detected.  It also prints messages to indicate the start and end of the log simulation and anomaly detection.
* **Comments:**  The code is thoroughly commented to explain the purpose of each section and the logic behind the anomaly detection algorithm.
* **Real-Time Consideration:** The use of `Instant` and `Duration` from `std::time` and the `thread::sleep` in the simulation function are essential for real-time processing.  In a production system, you would replace the log simulation with a real-time log source (e.g., reading from a network interface or a log file that is being appended to).
* **Error Handling:** The code lacks explicit error handling. In a production environment, you would want to add error handling to gracefully handle potential issues such as file read errors, network connection errors, and parsing errors.
* **Thread Safety:** The current implementation is single-threaded. If you need to process a large volume of logs in real time, you might consider using multiple threads to improve performance.  In that case, you'll need to add appropriate synchronization mechanisms (e.g., mutexes) to protect shared data structures like the `request_counts` HashMap.
* **Replace Simulation:**  The `simulate_log_stream` function *must* be replaced with code that reads actual network logs. This could involve reading from a file, a network socket, or a database.  The log parsing logic within the real log reader will need to be adapted to your specific log format.
* **Sophisticated Anomaly Detection:** The current anomaly detection algorithm is very simple.  For a real-world system, you would want to use more sophisticated techniques such as machine learning algorithms, statistical analysis, and behavioral analysis. Libraries like `linfa` or `smartcore` can be used to implement those techniques.
* **Scalability:** For high-volume log processing, consider using message queues (e.g., Kafka, RabbitMQ) to decouple the log producers from the anomaly detection system. This can help improve scalability and reliability.

To use this code:

1. **Install Rust:** If you don't have it already, install Rust from [https://www.rust-lang.org/](https://www.rust-lang.org/).
2. **Create a Project:** Create a new Rust project using `cargo new network_anomaly_detection`.
3. **Replace `src/main.rs`:** Copy the code above into the `src/main.rs` file.
4. **Run:**  Compile and run the code using `cargo run`. You should see output indicating that anomalies are being detected.
5. **Adapt:**  Modify the `NetworkLogEntry` struct, the `simulate_log_stream` function, and the anomaly detection logic to match your specific requirements.  *Remember to replace the simulation with a real log source.*
👁️ Viewed: 4

Comments