pub mod iptables_save; pub mod login_attempt; use linemux::MuxedLines; use login_attempt::LoginAttempt; use std::collections::HashMap; #[tokio::main] async fn main() -> std::io::Result<()> { let iptables = iptables::new(false).unwrap(); let mut lines = MuxedLines::new()?; lines.add_file("/host_ssh/auth.log").await?; let mut login_attempts: HashMap = HashMap::new(); println!("listening to changes over /host_ssh/auth.log"); while let Ok(Some(line)) = lines.next_line().await { if let Some(login_attempt) = LoginAttempt::capture(line.line()) { println!( "failed login attempt from {}@{}:{}", login_attempt.user, login_attempt.ip, login_attempt.port ); match login_attempts.get_mut(&login_attempt.ip) { Some(count) => { *count += 1; if *count == 3 { match iptables.append_unique( "filter", "INPUT", &format!("--source {} -j DROP", login_attempt.ip), ) { Ok(_) => { println!("{} banned", login_attempt.ip); } Err(_) => { println!("{} already banned", login_attempt.ip); } } login_attempts.remove(&login_attempt.ip); } } None => { login_attempts.insert(login_attempt.ip.clone(), 1); } } } } Ok(()) }