1
0

upgrading, and improving ban server

This commit is contained in:
2024-08-30 12:27:32 +02:00
parent dffa6b7ed7
commit 0593a2bfea
3 changed files with 124 additions and 60 deletions

View File

@ -9,12 +9,15 @@ use iptables_wrapper::{
map_secured_ports_allowed_ips, remove_allow_ip_for_port, secure_port, unsecure_port,
};
use linemux::MuxedLines;
use log::{error, info};
use login_attempt::LoginAttempt;
use std::{collections::HashMap, path::PathBuf, thread::sleep, thread::spawn, time::Duration};
use structopt::StructOpt;
#[tokio::main]
async fn main() {
logfmt_logger::init();
match Cli::from_args() {
Cli::BanServer {
ssh_auth_log,
@ -79,11 +82,6 @@ async fn start_ban_server(
ssh_auth_log: PathBuf,
iptables_save: Option<PathBuf>,
) -> std::io::Result<()> {
let iptables = iptables::new(false).unwrap();
let mut lines = MuxedLines::new()?;
lines.add_file(&ssh_auth_log).await?;
let mut login_attempts: HashMap<String, usize> = HashMap::new();
if let Some(iptables_save) = iptables_save {
let seconds_iptables = Duration::from_secs(60);
println!(
@ -97,39 +95,53 @@ async fn start_ban_server(
});
}
println!("Listeging to changer over file: {}", ssh_auth_log.display());
let iptables = iptables::new(false).unwrap();
let mut lines = MuxedLines::new()?;
lines.add_file(&ssh_auth_log).await?;
let mut login_attempts: HashMap<String, usize> = HashMap::new();
info!("listening changes over {}", ssh_auth_log.display());
loop {
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
);
let next_line = lines.next_line().await;
match login_attempts.get_mut(&login_attempt.ip) {
Some(count) => {
*count += 1;
if let Err(err) = next_line {
error!("reading next file: {}", err);
continue;
}
let line = next_line.unwrap();
if line.is_none() {
continue;
}
if *count == 3 {
if iptables
.append_unique(
"filter",
"INPUT",
&format!("--source {} -j DROP", login_attempt.ip),
)
.is_ok()
{
println!("IP {} banned", login_attempt.ip);
} else {
println!("IP {} already banned", login_attempt.ip);
}
let line = line.unwrap();
login_attempts.remove(&login_attempt.ip);
if let Some(login_attempt) = LoginAttempt::capture(line.line()) {
info!(
"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 {
if iptables
.append_unique(
"filter",
"INPUT",
&format!("--source {} -j DROP", login_attempt.ip),
)
.is_ok()
{
info!("IP {} banned", login_attempt.ip);
}
login_attempts.remove(&login_attempt.ip);
}
None => {
login_attempts.insert(login_attempt.ip.clone(), 1);
}
}
None => {
login_attempts.insert(login_attempt.ip.clone(), 1);
}
}
}