From 91a1bbc0a5f2f0aec8a34c1b3179f2af73ed7bd4 Mon Sep 17 00:00:00 2001 From: Eliska Cervinkova Date: Wed, 30 Sep 2026 12:13:36 +0200 Subject: [PATCH 1/6] fix: CPU affinity module parses cpu set --- src/cpu_affinity.rs | 32 ++++++++++++++++++++++++++++---- src/yaml.rs | 4 ++-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/cpu_affinity.rs b/src/cpu_affinity.rs index f01b549..2c79f5a 100644 --- a/src/cpu_affinity.rs +++ b/src/cpu_affinity.rs @@ -7,7 +7,7 @@ This file represents a CPU affinity module. */ use chrono::{DateTime, Utc}; -use std::collections::{HashMap}; +use std::collections::{HashMap, HashSet}; use serde_json::{Value, Number}; use std::fs; use crate::json::CpuThread; @@ -453,10 +453,34 @@ impl CpuAffinityModule { .map(|a| a.as_u64().expect("Expected u64 value")).collect() } + fn get_max_cpu_usage_vec(&self, answers: &Vec>) -> Vec { + let value = answers.iter().find(|h| h.key == &Keys::max_cpu_usage_vec) + .expect("Max cpu usage vector cannot be found.").value; + + let seq = value.as_array().expect("Unable to get max_cpu_usage_vec as array."); + + let mut cpus: Vec = Vec::new(); + let mut seen = HashSet::new(); + + for item in seq { + let s = match item { + Value::Number(n) => n.to_string(), + Value::String(s) => s.clone(), + u => panic!("Invalid CPU {:?}.", u) + }; + yaml::insert_cpu(&s, &mut seen, &mut cpus) + .expect("Unable to parse max_cpu_usage_vec as u64 vector."); + } + + if self.debug { + println!("max_cpu_usage_vec: {:?}", cpus); + } + + cpus + } + pub fn set_new_cpu_set(&self, answers: &Vec>, mut new_workers: u64) -> Vec { - let max_cpu_usage_vec: Vec = answers.iter().find(|h| h.key == &Keys::max_cpu_usage_vec) - .expect("Max cpu usage vector cannot be found.").value.as_array().expect("Unable to get array from max cpu usage vector.") - .iter().map(|a| a.as_u64().expect("Expected u64 value")).collect(); + let max_cpu_usage_vec = self.get_max_cpu_usage_vec(answers); if self.debug { println!("new_workers: {new_workers}"); diff --git a/src/yaml.rs b/src/yaml.rs index dcba121..af0273b 100644 --- a/src/yaml.rs +++ b/src/yaml.rs @@ -1058,7 +1058,7 @@ fn parse_cpu_list(items: &[String]) -> Result, String> { Ok(cpus) } -fn expand_cpu_range(s: &str) -> Result, String> { +pub fn expand_cpu_range(s: &str) -> Result, String> { let system_cpus = num_cpus::get(); let s = s.trim(); match s.split_once('-') { @@ -1086,7 +1086,7 @@ fn expand_cpu_range(s: &str) -> Result, String> { } } -fn insert_cpu(s: &str, seen: &mut HashSet, cpus: &mut Vec) -> Result<(), String> { +pub fn insert_cpu(s: &str, seen: &mut HashSet, cpus: &mut Vec) -> Result<(), String> { for cpu in expand_cpu_range(s)? { if seen.insert(cpu) { cpus.push(cpu); From b30352f3268bde78df8aefe4952edd725250bec0 Mon Sep 17 00:00:00 2001 From: Eliska Cervinkova Date: Fri, 2 Oct 2026 13:57:18 +0200 Subject: [PATCH 2/6] fix: set CPU vector correctly --- suriconf.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/suriconf.yaml b/suriconf.yaml index 3f3ee8c..f93ca16 100644 --- a/suriconf.yaml +++ b/suriconf.yaml @@ -37,4 +37,4 @@ variables: interface: eth0 capture_mode: af_packet # dpdk max_memory_usage: 1 GiB - max_cpu_usage_vec: [0] # [0-6] \ No newline at end of file + max_cpu_usage_vec: [0-2] # [0-6] \ No newline at end of file From 101fb67248ed82effb145d6a977e5996bdce11c1 Mon Sep 17 00:00:00 2001 From: Eliska Cervinkova Date: Fri, 2 Oct 2026 14:38:12 +0200 Subject: [PATCH 3/6] docs: update ISSUES.md --- ISSUES.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ISSUES.md b/ISSUES.md index d62fb32..cdfb79f 100644 --- a/ISSUES.md +++ b/ISSUES.md @@ -14,8 +14,7 @@ --- ## Bugs -- The YAML file is converted to JSON and then back to YAML for searching, which can alter the original formatting and is therefore not fully correct. A hotfix function was introduced specifically for the purposes of the bachelor’s thesis. -- The regression sometimes has fewer samples than is required. +- The YAML file is converted to JSON and then back to YAML for searching, which can alter the original formatting and is therefore not fully correct. A hotfix function was introduced specifically for the purposes of the bachelor’s thesis. - Disable syslog and suricata.log logging after configuration. - Better estimation of TCP overhead. - CPU affinity module should work with `check_nic_warning_counter`, `get_capture_errors_stat` functions. @@ -23,7 +22,9 @@ - The `tcp_reuse` timeout is not considered. - The calculations for flow_memcap and stream_memcap do not account for all memory components in some cases. - Fragment structures are not included in `defrag_memuse` at all. (Suricata) +- Hotfix for defrag_memcap, needs further analysis. - Do not log counters with zero values. Adapt the program to handle missing counters. +- Check for parameter changes (CLI) in Suriconf. (CPU affinity module) ## Future work - Add load factor for hash tables in memory module. From 4f3f5adf73907f274cc24bf4c9d166dc293a22b1 Mon Sep 17 00:00:00 2001 From: Eliska Cervinkova Date: Fri, 2 Oct 2026 14:38:46 +0200 Subject: [PATCH 4/6] fix: apply correction factor to defrag memcap --- src/memory_usage.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/memory_usage.rs b/src/memory_usage.rs index 8442bbf..36c2620 100644 --- a/src/memory_usage.rs +++ b/src/memory_usage.rs @@ -452,7 +452,7 @@ impl MemoryModule { }; let hashsize = self.questions.get(&Keys::defrag_hashsize).expect("Unable to get defrag.").as_f64().expect("Unable to get defrag hash_size as f64."); - hashsize*DEFRAG_TRACKER_HASHROW+(max_defrag_tracker_active+(self.get_ippair_host_defrag_stream_reassembly_prealloc(answers, &HashType::Defrag) as f64)*MULTIPLIER)*DEFRAG_TRACKER + hashsize*DEFRAG_TRACKER_HASHROW+(max_defrag_tracker_active+(self.get_ippair_host_defrag_stream_reassembly_prealloc(answers, &HashType::Defrag) as f64)*MULTIPLIER)*DEFRAG_TRACKER*4.0 } fn get_stream_memcap(&self, answers: &Vec>) -> f64 { From b3c1b98adc5540c6692088be0df1ef5f7d1c020a Mon Sep 17 00:00:00 2001 From: Eliska Cervinkova Date: Fri, 2 Oct 2026 14:32:36 +0200 Subject: [PATCH 5/6] fix: increase Suricata shutdown timeout --- src/suricata.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/suricata.rs b/src/suricata.rs index 3e30baa..acbb361 100644 --- a/src/suricata.rs +++ b/src/suricata.rs @@ -388,7 +388,7 @@ fn get_cores_with_threads(suri_pid: i32, sys: &mut SystemVar) { } pub fn kill_suricata(child: &mut Child) { - let end_timeout = Duration::from_secs(30); + let end_timeout = Duration::from_secs(300); let pid = child.id(); let mut output = Command::new("sudo") .arg("pkill") From ca35d530b341f46448bd952b4566555e729bab8a Mon Sep 17 00:00:00 2001 From: Eliska Cervinkova Date: Fri, 2 Oct 2026 14:45:03 +0200 Subject: [PATCH 6/6] chore: bump version to 1.1.0-dev.2 --- Cargo.toml | 2 +- README.md | 12 ++++++------ suriconf.yaml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 710efd0..4405c94 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "suriconf" edition = "2024" -version = "1.1.0-dev" +version = "1.1.0-dev.2" authors = ["Eliška Červinková "] license = "BSD-3-Clause" description = "A tool for automating Suricata setup and configuration." diff --git a/README.md b/README.md index f94205e..4f892ec 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Rust](https://img.shields.io/badge/rust-1.88+-orange.svg)](https://rustup.rs/) [![Bachelor's Thesis](https://img.shields.io/badge/thesis-completed-success)](https://www.vut.cz/studenti/zav-prace/detail/170986) -Suriconf is an automated configuration assistant for [Suricata](https://github.com/OISF/suricata). It analyzes network traffic and system resources to optimize Suricata's configuration through a modular approach. Each module uses mathematical methods and performance metrics to configure specific Suricata components. Testing showed Suriconf v1.1.0-dev successfully configured Suricata in 80.8% of test cases with [rules](https://community.emergingthreats.net/). +Suriconf is an automated configuration assistant for [Suricata](https://github.com/OISF/suricata). It analyzes network traffic and system resources to optimize Suricata's configuration through a modular approach. Each module uses mathematical methods and performance metrics to configure specific Suricata components. Testing showed Suriconf v1.1.0-dev.2 successfully configured Suricata in 80.8% of test cases with [rules](https://community.emergingthreats.net/). ## Contents @@ -43,14 +43,14 @@ The following tools must be installed, and their paths must be accessible and sp ### System -Suriconf v1.1.0-dev requires the network interface to be bound to a specific NUMA node. +Suriconf v1.1.0-dev.2 requires the network interface to be bound to a specific NUMA node. ### Suricata configuration file > [!WARNING] > Consider stream and reassembly memcap in Suricata configuration file. (host and IPpair memcap). -Configure these with high values first. Suriconf will automatically reduce them if needed. This is necessary because Suriconf v1.1.0-dev currently lacks dynamic memory reallocation between these pools. Once allocated, memory assigned to one memcap cannot be reassigned to another at runtime. +Configure these with high values first. Suriconf will automatically reduce them if needed. This is necessary because Suriconf v1.1.0-dev.2 currently lacks dynamic memory reallocation between these pools. Once allocated, memory assigned to one memcap cannot be reassigned to another at runtime. ## Configuration @@ -69,8 +69,8 @@ The entire configuration is defined in a YAML file, typically named `suriconf.ya > [!WARNING] > - Flow threads module requires minimum 6 minutes (`preconf-time`). -> - Version 1.1.0-dev supports only `static` analysis. -> - Version 1.1.0-dev supports only `modify` mode with `yaml_change: force`. +> - Version 1.1.0-dev.2 supports only `static` analysis. +> - Version 1.1.0-dev.2 supports only `modify` mode with `yaml_change: force`. ### Modules @@ -116,7 +116,7 @@ sudo grubby --update-kernel=ALL --args="isolcpus=2-4" && sudo reboot Install Suriconf: ```bash -cargo install suriconf@1.1.0-dev +cargo install suriconf@1.1.0-dev.2 ``` To display available options, execute: diff --git a/suriconf.yaml b/suriconf.yaml index f93ca16..0c8c17c 100644 --- a/suriconf.yaml +++ b/suriconf.yaml @@ -1,7 +1,7 @@ %YAML 1.1 --- -suriconf-version: 1.1.0-dev +suriconf-version: 1.1.0-dev.2 suri-configuration: suricata.yaml suricata-bin: /usr/bin/suricata