Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "suriconf"
edition = "2024"
version = "1.0.1-dev"
version = "1.1.0-dev"
authors = ["Eliška Červinková <eliska.cervinkova@cesnet.cz>"]
license = "BSD-3-Clause"
description = "A tool for automating Suricata setup and configuration."
Expand All @@ -28,4 +28,5 @@ scirs2-stats = "0.3.0"
scirs2-core = "0.3.0"
sysinfo = "0.38.3"
procfs = "0.18.0"
itertools = "0.14.0"
itertools = "0.14.0"
num_cpus = "1.17.0"
3 changes: 0 additions & 3 deletions ISSUES.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@
- Use shell-check for bash scripts, improve test automation.
- Refactor logging using Rust crates.

## Features
- Specify logical cores as a range in suricata.yaml.

## Tests
- Test Theil-Sen regression.
- How do the Suricata parameters `default-packet-size` and `max-pending-packets` affect performance?
Expand Down
22 changes: 14 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.0.1-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 successfully configured Suricata in 80.8% of test cases with [rules](https://community.emergingthreats.net/).

## Contents

Expand Down Expand Up @@ -37,20 +37,20 @@ The following tools must be installed, and their paths must be accessible and sp

| Tool | Version |
|------|---------|
| Suricata | 9.0.0-dev (d030a9c4e 2026-04-01) |
| Suricata | 9.0.0-dev (746bb48 2026-09-27), https://github.com/KEIAHNY/suricata/tree/ippair-host-defrag-reassembly-counters-feature-8438-v1 |
| ethtool | 5.13 |
| ip | iproute2-6.8.0, libbpf 0.5.0 |

### System

Suriconf v1.0.1-dev requires the network interface to be bound to a specific NUMA node.
Suriconf v1.1.0-dev 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.0.1-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 currently lacks dynamic memory reallocation between these pools. Once allocated, memory assigned to one memcap cannot be reassigned to another at runtime.

## Configuration

Expand All @@ -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.0.1-dev supports only `static` analysis.
> - Version 1.0.1-dev supports only `modify` mode with `yaml_change: force`.
> - Version 1.1.0-dev supports only `static` analysis.
> - Version 1.1.0-dev supports only `modify` mode with `yaml_change: force`.


### Modules
Expand Down Expand Up @@ -116,15 +116,21 @@ sudo grubby --update-kernel=ALL --args="isolcpus=2-4" && sudo reboot
Install Suriconf:

```bash
cargo install suriconf@1.0.1-dev
cargo install suriconf@1.1.0-dev
```

Execute Suriconf:
To display available options, execute:

```bash
suriconf -h
```

To generate the Suriconf configuration file, use:

```bash
suriconf init
```

## Github

Use the Cargo package manager to run the project in `src` directory:
Expand Down
16 changes: 14 additions & 2 deletions src/argument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub struct Args {
#[clap(short='s', long="sconf")]
pub suricata_config: Option<PathBuf>,

/// Specify Suriconf configuration file
/// Specify Suriconf configuration file (default: ./suriconf.yaml)
#[clap(short='c', long="conf", default_value="suriconf.yaml")]
pub suriconf_config: PathBuf,

Expand Down Expand Up @@ -93,6 +93,18 @@ pub enum Commands {

/// Change max cpu usage
#[clap(short='C', long="cpu", value_delimiter = ' ', num_args = 1..)]
max_cpu_usage_vec: Option<Vec<u64>>,
max_cpu_usage_vec: Option<Vec<String>>,
},

/// Generate Suriconf configuration file

Init {
/// Output path (default: ./suriconf.yaml)
#[arg(short, long, default_value = "./suriconf.yaml")]
output: PathBuf,

/// Overwrite existing file
#[arg(short, long)]
force: bool,
}
}
16 changes: 16 additions & 0 deletions src/config_gen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use std::fs;
use std::io;
use std::path::{PathBuf};

use crate::{DEFAULT_CONFIG};

pub fn init(output: &PathBuf, force: bool) -> io::Result<()> {
if output.exists() && !force {
return Err(io::Error::new(
io::ErrorKind::AlreadyExists,
format!("refusing to overwrite {:?} (use --force)", output),
));
}
fs::write(output, DEFAULT_CONFIG)?;
Ok(())
}
5 changes: 4 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ mods!(
flow_threads,
regression,
module,
cpu_affinity
cpu_affinity,
config_gen
);

pub const DEFAULT_CONFIG: &str = include_str!("../suriconf.yaml");

static FLOW_WINDOW: u64 = 5; // in seconds
static MIN_RUN: u64 = 360;
static WINDOWS: u64 = 3;
Expand Down
11 changes: 10 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ This file is a startpoint for Suriconf.

use chrono::{DateTime, Utc};
use clap::Parser;
use std::process;
use std::time::SystemTime;
use suriconf::argument::Args;
use suriconf::argument::{Args, Commands};
use suriconf::config_gen::init;
use suriconf::json::Preconfiguration;
use suriconf::query::Resources;
use suriconf::structures::{CreatedLogs, JsonVar, SuricataAgain};
Expand All @@ -21,6 +23,13 @@ use suriconf::yaml::Suriconf;
fn main() {
let args = Args::parse();

if let Some(Commands::Init { output, force }) = &args.cmd {
if let Err(e) = init(output, *force) {
panic!("{e}");
}
process::exit(0);
}

let suriconf_string = match yaml::open_yaml(&args.suriconf_config) {
Ok(suriconf_string) => suriconf_string,
Err(e) => {
Expand Down
3 changes: 2 additions & 1 deletion src/suricata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use signal_hook::iterator::Signals;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicBool, Ordering};
use std::io;

pub fn execute_suricata<'a>(suriconf: &Suriconf, logs: &mut CreatedLogs, options: &Vec<String>) -> Option<(SystemVar, SuricataAgain)> {
let sys = Arc::new(Mutex::new(SystemVar::default()));
Expand Down Expand Up @@ -222,7 +223,7 @@ pub fn set_log_dir(suriconf: &Suriconf, vec_of_sur_cmd: &mut Vec<String>) {
vec_of_sur_cmd.push(suriconf.log_dir.display().to_string());
}

pub fn delete_pid_file() -> std::io::Result<()> {
pub fn delete_pid_file() -> io::Result<()> {
let status = Command::new("sudo")
.arg("-n")
.arg("rm")
Expand Down
Loading
Loading