2024-05-12 14:03:26 +02:00
|
|
|
pub mod iptables_save;
|
2024-05-12 13:46:11 +02:00
|
|
|
pub mod login_attempt;
|
2024-05-20 23:36:34 +02:00
|
|
|
pub mod tpc_command_server;
|
2024-05-12 13:46:11 +02:00
|
|
|
|
2024-05-20 23:36:34 +02:00
|
|
|
use crate::tpc_command_server::start_tcp_command_server;
|
2024-05-12 13:46:11 +02:00
|
|
|
use linemux::MuxedLines;
|
|
|
|
use login_attempt::LoginAttempt;
|
2024-05-20 23:36:34 +02:00
|
|
|
use std::thread;
|
2024-05-12 14:54:47 +02:00
|
|
|
use std::{collections::HashMap, thread::sleep, time::Duration};
|
2024-05-12 13:46:11 +02:00
|
|
|
|
|
|
|
#[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<String, usize> = HashMap::new();
|
|
|
|
|
2024-05-12 14:54:47 +02:00
|
|
|
let seconds_iptables = Duration::from_secs(60);
|
|
|
|
println!(
|
|
|
|
"starting iptables-save, run every {} seconds",
|
|
|
|
seconds_iptables.as_secs()
|
|
|
|
);
|
2024-05-20 23:36:34 +02:00
|
|
|
|
|
|
|
thread::spawn(move || loop {
|
|
|
|
sleep(seconds_iptables);
|
|
|
|
iptables_save::save_iptables();
|
|
|
|
println!("saved iptables rules");
|
|
|
|
});
|
|
|
|
|
|
|
|
thread::spawn(|| {
|
|
|
|
start_tcp_command_server();
|
2024-05-12 14:54:47 +02:00
|
|
|
});
|
|
|
|
|
2024-05-12 14:03:26 +02:00
|
|
|
println!("listening to changes over /host_ssh/auth.log");
|
2024-05-12 13:46:11 +02:00
|
|
|
while let Ok(Some(line)) = lines.next_line().await {
|
2024-05-12 14:03:26 +02:00
|
|
|
if let Some(login_attempt) = LoginAttempt::capture(line.line()) {
|
|
|
|
println!(
|
|
|
|
"failed login attempt from {}@{}:{}",
|
|
|
|
login_attempt.user, login_attempt.ip, login_attempt.port
|
|
|
|
);
|
2024-05-12 13:46:11 +02:00
|
|
|
match login_attempts.get_mut(&login_attempt.ip) {
|
|
|
|
Some(count) => {
|
|
|
|
*count += 1;
|
|
|
|
|
|
|
|
if *count == 3 {
|
2024-05-12 14:03:26 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2024-05-12 13:46:11 +02:00
|
|
|
login_attempts.remove(&login_attempt.ip);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
None => {
|
|
|
|
login_attempts.insert(login_attempt.ip.clone(), 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|