Skip to content

Commit c316f94

Browse files
author
vsilent
committed
ip_ban::engine::tests
1 parent d790554 commit c316f94

File tree

4 files changed

+82
-9
lines changed

4 files changed

+82
-9
lines changed

ebpf/.cargo/config.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[build]
2+
target = ["bpfel-unknown-none"]
3+
4+
[target.bpfel-unknown-none]
5+
6+
[unstable]
7+
build-std = ["core"]

src/firewall/response.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ pub struct ResponseAction {
3333
}
3434

3535
impl ResponseAction {
36+
fn quarantine_container_error(container_id: &str) -> anyhow::Error {
37+
anyhow::anyhow!(
38+
"Docker-based container quarantine flow is required for {} because firewall backends do not implement container-specific quarantine. Use the Docker/API quarantine path instead.",
39+
container_id
40+
)
41+
}
42+
3643
fn preferred_backend() -> Result<Box<dyn FirewallBackend>> {
3744
if let Ok(mut backend) = NfTablesBackend::new() {
3845
backend.initialize()?;
@@ -105,10 +112,7 @@ impl ResponseAction {
105112
let backend = Self::preferred_backend()?;
106113
backend.block_port(*port)
107114
}
108-
ResponseType::QuarantineContainer(id) => {
109-
let backend = Self::preferred_backend()?;
110-
backend.block_container(id)
111-
}
115+
ResponseType::QuarantineContainer(id) => Err(Self::quarantine_container_error(id)),
112116
ResponseType::KillProcess(pid) => {
113117
let output = Command::new("kill")
114118
.args(["-TERM", &pid.to_string()])

src/ip_ban/engine.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,19 @@ mod tests {
181181
use crate::database::repositories::offenses::OffenseStatus;
182182
use crate::database::{create_pool, init_database, list_alerts, AlertFilter};
183183
use chrono::Utc;
184+
#[cfg(target_os = "linux")]
185+
use std::process::Command;
186+
187+
#[cfg(target_os = "linux")]
188+
fn running_as_root() -> bool {
189+
Command::new("id")
190+
.arg("-u")
191+
.output()
192+
.ok()
193+
.and_then(|output| String::from_utf8(output.stdout).ok())
194+
.map(|stdout| stdout.trim() == "0")
195+
.unwrap_or(false)
196+
}
184197

185198
#[actix_rt::test]
186199
async fn test_extract_ip_candidates() {
@@ -227,10 +240,21 @@ mod tests {
227240
source_path: Some("/var/log/auth.log".into()),
228241
sample_line: Some("Failed password from 192.0.2.44".into()),
229242
})
230-
.await
231-
.unwrap();
243+
.await;
232244

233245
assert!(!first);
246+
#[cfg(target_os = "linux")]
247+
if !running_as_root() {
248+
let error = second.unwrap_err().to_string();
249+
assert!(
250+
error.contains("Operation not permitted")
251+
|| error.contains("Permission denied")
252+
|| error.contains("you must be root")
253+
);
254+
return;
255+
}
256+
257+
let second = second.unwrap();
234258
assert!(second);
235259
assert!(active_block_for_ip(&pool, "192.0.2.44").unwrap().is_some());
236260
}
@@ -260,8 +284,20 @@ mod tests {
260284
source_path: Some("/var/log/auth.log".into()),
261285
sample_line: Some("Failed password from 192.0.2.55".into()),
262286
})
263-
.await
264-
.unwrap();
287+
.await;
288+
289+
#[cfg(target_os = "linux")]
290+
if !running_as_root() {
291+
let error = blocked.unwrap_err().to_string();
292+
assert!(
293+
error.contains("Operation not permitted")
294+
|| error.contains("Permission denied")
295+
|| error.contains("you must be root")
296+
);
297+
return;
298+
}
299+
300+
let blocked = blocked.unwrap();
265301
assert!(blocked);
266302

267303
let released = engine.unban_expired().await.unwrap();

src/sniff/mod.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,19 @@ mod tests {
300300
use crate::ip_ban::{IpBanConfig, IpBanEngine};
301301
use crate::sniff::analyzer::{AnomalySeverity, LogAnomaly, LogSummary};
302302
use chrono::Utc;
303+
#[cfg(target_os = "linux")]
304+
use std::process::Command;
305+
306+
#[cfg(target_os = "linux")]
307+
fn running_as_root() -> bool {
308+
Command::new("id")
309+
.arg("-u")
310+
.output()
311+
.ok()
312+
.and_then(|output| String::from_utf8(output.stdout).ok())
313+
.map(|stdout| stdout.trim() == "0")
314+
.unwrap_or(false)
315+
}
303316

304317
fn memory_sniff_config() -> SniffConfig {
305318
let mut config = SniffConfig::from_env_and_args(config::SniffArgs {
@@ -473,7 +486,20 @@ mod tests {
473486
);
474487

475488
orchestrator.apply_ip_ban(&summary, &engine).await.unwrap();
476-
orchestrator.apply_ip_ban(&summary, &engine).await.unwrap();
489+
let second_attempt = orchestrator.apply_ip_ban(&summary, &engine).await;
490+
491+
#[cfg(target_os = "linux")]
492+
if !running_as_root() {
493+
let error = second_attempt.unwrap_err().to_string();
494+
assert!(
495+
error.contains("Operation not permitted")
496+
|| error.contains("Permission denied")
497+
|| error.contains("you must be root")
498+
);
499+
return;
500+
}
501+
502+
second_attempt.unwrap();
477503

478504
assert!(active_block_for_ip(&orchestrator.pool, "192.0.2.81")
479505
.unwrap()

0 commit comments

Comments
 (0)