1
0

using journal instead of ssh file

This commit is contained in:
midefos 2024-09-22 03:33:48 +02:00
parent 75104020fc
commit 5f2f49d0eb
5 changed files with 48 additions and 53 deletions

View File

@ -10,4 +10,4 @@ FROM ubuntu:latest
RUN apt update && apt upgrade -y && apt install iptables iptables-persistent -y RUN apt update && apt upgrade -y && apt install iptables iptables-persistent -y
COPY --from=builder /target/release/martillo-maldito ./ COPY --from=builder /target/release/martillo-maldito ./
CMD [ "/martillo-maldito", "ban-server", "-f", "/host_ssh/auth.log", "-s", "/host_iptables/rules.v4" ] CMD [ "/martillo-maldito", "ban-server" ]

View File

@ -4,6 +4,7 @@ services:
martillo-maldito: martillo-maldito:
image: git.midefos.com/midefos/martillo-maldito:latest image: git.midefos.com/midefos/martillo-maldito:latest
restart: always restart: always
# pull_policy: build
network_mode: "host" network_mode: "host"
cap_add: cap_add:
@ -11,5 +12,5 @@ services:
- NET_RAW - NET_RAW
volumes: volumes:
- /var/log/auth.log:/host_ssh/auth.log - /var/log/journal:/var/log/journal
- /etc/iptables/rules.v4:/host_iptables/rules.v4 - /etc/iptables/rules.v4:/etc/iptables/rules.v4

View File

@ -8,12 +8,7 @@ use structopt::StructOpt;
)] )]
pub enum Cli { pub enum Cli {
#[structopt(about = "Initialize ban server")] #[structopt(about = "Initialize ban server")]
BanServer { BanServer,
#[structopt(name = "Ssh auth log file", short = "f", long = "ssh-file")]
ssh_auth_log: PathBuf,
#[structopt(name = "Iptables save file", short = "s", long = "iptables-save")]
iptables_save: Option<PathBuf>,
},
#[structopt(about = "List all banned ips")] #[structopt(about = "List all banned ips")]
ListBannedIps { ListBannedIps {
#[structopt(name = "Docker", short = "d", long = "docker")] #[structopt(name = "Docker", short = "d", long = "docker")]
@ -82,8 +77,5 @@ pub enum Cli {
docker: bool, docker: bool,
}, },
#[structopt(about = "Saves the IPTables configuration")] #[structopt(about = "Saves the IPTables configuration")]
SaveIPTables { SaveIPTables,
#[structopt(name = "Iptables save file", short = "s", long = "iptables-save")]
iptables_save: Option<PathBuf>,
},
} }

View File

@ -1,7 +1,7 @@
use std::{path::Path, process::Command}; use std::process::Command;
pub fn save_iptables(path: &Path) -> std::io::Result<std::process::Output> { pub fn save_iptables() -> std::io::Result<std::process::Output> {
Command::new("iptables-save") Command::new("iptables-save")
.args(["-f", path.to_str().unwrap()]) .args(["-f", "/etc/iptables/rules.v4"])
.output() .output()
} }

View File

@ -8,10 +8,15 @@ use iptables_wrapper::{
allow_ip_for_port, is_port_secured, list_banned_ips, list_secured_ports, allow_ip_for_port, is_port_secured, list_banned_ips, list_secured_ports,
map_secured_ports_allowed_ips, remove_allow_ip_for_port, secure_port, unsecure_port, map_secured_ports_allowed_ips, remove_allow_ip_for_port, secure_port, unsecure_port,
}; };
use linemux::MuxedLines;
use log::{error, info}; use log::{error, info};
use login_attempt::LoginAttempt; use login_attempt::LoginAttempt;
use std::{collections::HashMap, path::PathBuf, thread::sleep, thread::spawn, time::Duration}; use std::{
collections::HashMap,
io::BufRead,
process::{Child, Command, Stdio},
thread::{sleep, spawn},
time::Duration,
};
use structopt::StructOpt; use structopt::StructOpt;
#[tokio::main] #[tokio::main]
@ -19,11 +24,8 @@ async fn main() {
start_logger(); start_logger();
match Cli::from_args() { match Cli::from_args() {
Cli::BanServer { Cli::BanServer => {
ssh_auth_log, if let Err(error) = start_ban_server().await {
iptables_save,
} => {
if let Err(error) = start_ban_server(ssh_auth_log, iptables_save).await {
error!("ban server: {error}"); error!("ban server: {error}");
} }
} }
@ -68,52 +70,52 @@ async fn main() {
Cli::RemoveAllowIpPort { ip, port, docker } => { Cli::RemoveAllowIpPort { ip, port, docker } => {
println!("{}", remove_allow_ip_for_port(&ip, port, docker).is_ok()) println!("{}", remove_allow_ip_for_port(&ip, port, docker).is_ok())
} }
Cli::SaveIPTables { iptables_save } => { Cli::SaveIPTables => {
let path = if let Some(iptables_save) = iptables_save { println!("{}", iptables_save::save_iptables().is_ok())
iptables_save
} else {
PathBuf::from("/etc/iptables/rules.v4")
};
println!("{}", iptables_save::save_iptables(&path).is_ok())
} }
} }
} }
async fn start_ban_server( async fn start_ban_server() -> std::io::Result<()> {
ssh_auth_log: PathBuf, let seconds_iptables = Duration::from_secs(60);
iptables_save: Option<PathBuf>, info!("saving IPTables every {} secs", seconds_iptables.as_secs());
) -> std::io::Result<()> {
if let Some(iptables_save) = iptables_save {
let seconds_iptables = Duration::from_secs(60);
info!("saving IPTables every {} secs", seconds_iptables.as_secs());
spawn(move || loop { spawn(move || loop {
sleep(seconds_iptables); sleep(seconds_iptables);
iptables_save::save_iptables(&iptables_save); iptables_save::save_iptables();
}); });
}
let mut child: Child = Command::new("journalctl")
.arg("-D")
.arg("/var/log/journal")
.arg("-u")
.arg("ssh")
.arg("-f")
.stdout(Stdio::piped())
.spawn()?;
let stdout = child.stdout.as_mut().expect("Failed to capture stdout");
let mut reader = std::io::BufReader::new(stdout);
let iptables = iptables::new(false).unwrap(); 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(); let mut login_attempts: HashMap<String, usize> = HashMap::new();
info!("listening changes over {}", ssh_auth_log.display()); info!("Start reading logins from SSH");
loop { loop {
let next_line = lines.next_line().await; let mut line = String::new();
if let Err(err) = next_line {
error!("reading next file: {}", err); if let Err(err) = reader.read_line(&mut line) {
error!("Reading line: {}", err);
continue; continue;
} }
let line = next_line?; println!("line: {}", line);
if line.is_none() {
if line.is_empty() {
continue; continue;
} }
let line = line.unwrap(); if let Some(login_attempt) = LoginAttempt::capture(&line) {
if let Some(login_attempt) = LoginAttempt::capture(line.line()) {
info!( info!(
"login attempt from {}@{}:{}", "login attempt from {}@{}:{}",
login_attempt.user, login_attempt.ip, login_attempt.port login_attempt.user, login_attempt.ip, login_attempt.port