using journal instead of ssh file
This commit is contained in:
		| @@ -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" ] | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								src/cli.rs
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/cli.rs
									
									
									
									
									
								
							| @@ -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>, |  | ||||||
|     }, |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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() | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										76
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user