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

View File

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

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")
.args(["-f", path.to_str().unwrap()])
.args(["-f", "/etc/iptables/rules.v4"])
.output()
}

View File

@ -8,10 +8,15 @@ use iptables_wrapper::{
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,
};
use linemux::MuxedLines;
use log::{error, info};
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;
#[tokio::main]
@ -19,11 +24,8 @@ async fn main() {
start_logger();
match Cli::from_args() {
Cli::BanServer {
ssh_auth_log,
iptables_save,
} => {
if let Err(error) = start_ban_server(ssh_auth_log, iptables_save).await {
Cli::BanServer => {
if let Err(error) = start_ban_server().await {
error!("ban server: {error}");
}
}
@ -68,52 +70,52 @@ async fn main() {
Cli::RemoveAllowIpPort { ip, port, docker } => {
println!("{}", remove_allow_ip_for_port(&ip, port, docker).is_ok())
}
Cli::SaveIPTables { iptables_save } => {
let path = if let Some(iptables_save) = iptables_save {
iptables_save
} else {
PathBuf::from("/etc/iptables/rules.v4")
};
println!("{}", iptables_save::save_iptables(&path).is_ok())
Cli::SaveIPTables => {
println!("{}", iptables_save::save_iptables().is_ok())
}
}
}
async fn start_ban_server(
ssh_auth_log: PathBuf,
iptables_save: Option<PathBuf>,
) -> 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());
async fn start_ban_server() -> std::io::Result<()> {
let seconds_iptables = Duration::from_secs(60);
info!("saving IPTables every {} secs", seconds_iptables.as_secs());
spawn(move || loop {
sleep(seconds_iptables);
iptables_save::save_iptables(&iptables_save);
});
}
spawn(move || loop {
sleep(seconds_iptables);
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 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());
info!("Start reading logins from SSH");
loop {
let next_line = lines.next_line().await;
if let Err(err) = next_line {
error!("reading next file: {}", err);
let mut line = String::new();
if let Err(err) = reader.read_line(&mut line) {
error!("Reading line: {}", err);
continue;
}
let line = next_line?;
if line.is_none() {
println!("line: {}", line);
if line.is_empty() {
continue;
}
let line = line.unwrap();
if let Some(login_attempt) = LoginAttempt::capture(line.line()) {
if let Some(login_attempt) = LoginAttempt::capture(&line) {
info!(
"login attempt from {}@{}:{}",
login_attempt.user, login_attempt.ip, login_attempt.port