use clap::Parser;
use std::io::IsTerminal;
const DEFAULT_IMAGE: &str = "jasonish/suricata";
const DEFAULT_VERSION: &str = "latest";
const AFTER_HELP: &str = r#"Examples:
- omnibox tool suricata -- -i eth0
- omnibox tool suricata --version master -- -i eth0 -l /tmp
Notes:
- If no log directory provided, the current directory will be used.
"#;
#[derive(Parser, Debug)]
#[command(after_help = AFTER_HELP)]
pub(crate) struct Args {
#[arg(long)]
version: Option<String>,
#[arg(long)]
image: Option<String>,
args: Vec<String>,
}
pub(crate) fn run(args: Args) {
let mut docker_args: Vec<String> = vec![];
let mut suricata_args: Vec<String> = vec![];
let image = if let Some(image) = args.image {
image
} else {
let version = if let Some(version) = args.version {
version
} else {
DEFAULT_VERSION.to_string()
};
format!("{}:{}", DEFAULT_IMAGE, version)
};
let args = args.args;
let mut has_log_directory = false;
let mut i = 0;
while i < args.len() {
let arg = &args[i];
if let Some(mut val) = arg.strip_prefix("-l") {
if val.is_empty() {
val = &args[i + 1];
}
let path = std::fs::canonicalize(val).unwrap();
docker_args.push(format!("--volume={}:/var/log/suricata", path.display()));
suricata_args.push("-l".to_string());
suricata_args.push("/var/log/suricata".to_string());
has_log_directory = true;
i += 1;
} else if let Some(mut val) = arg.strip_prefix("-r") {
if val.is_empty() {
val = &args[i + 1];
}
let path = std::fs::canonicalize(val).unwrap();
docker_args.push(format!("--volume={}:/tmp/input.pcap", path.display()));
suricata_args.push("-r".to_string());
suricata_args.push("/tmp/input.pcap".to_string());
i += 1;
} else if let Some(mut val) = arg.strip_prefix("-S") {
if val.is_empty() {
val = &args[i + 1];
}
let path = std::fs::canonicalize(val).unwrap();
docker_args.push(format!("--volume={}:/tmp/suricata.rules", path.display()));
suricata_args.push("-S".to_string());
suricata_args.push("/tmp/suricata.rules".to_string());
i += 1;
} else {
suricata_args.push(arg.to_string());
}
i += 1;
}
if !has_log_directory {
let path = std::env::current_dir().unwrap();
docker_args.push(format!("--volume={}:/var/log/suricata", path.display()));
suricata_args.push("-l".to_string());
suricata_args.push("/var/log/suricata".to_string());
}
if std::io::stdin().is_terminal() {
docker_args.push("-it".to_string());
}
let my_uid = nix::unistd::getuid();
let my_gid = nix::unistd::getgid();
docker_args.push("-e".to_string());
docker_args.push(format!("PUID={}", my_uid));
docker_args.push("-e".to_string());
docker_args.push(format!("PGID={}", my_gid));
let mut cmd = std::process::Command::new("docker");
cmd.args([
"run",
"--rm",
"--network=host",
"--cap-add=net_raw",
"--cap-add=net_admin",
"--cap-add=sys_nice",
]);
cmd.args(&docker_args);
cmd.args([image]);
cmd.args(&suricata_args);
if cmd.status().is_err() {
std::process::exit(1);
}
}