mirror of
https://github.com/pldubouilh/blockfast.git
synced 2026-08-29 13:27:04 -04:00
drop sshd support
This commit is contained in:
committed by
Pierre Dubouilh
parent
ac17c11158
commit
e63e926ccf
+2
-16
@@ -7,7 +7,6 @@ use linemux::{Line, MuxedLines};
|
||||
mod clf;
|
||||
mod generic;
|
||||
mod json;
|
||||
mod sshd;
|
||||
mod utils;
|
||||
|
||||
mod jail;
|
||||
@@ -33,13 +32,6 @@ async fn run() -> Result<()> {
|
||||
log!("starting with generic parsing at {:?}", &p);
|
||||
}
|
||||
|
||||
// sshd
|
||||
let sshd_logpaths = &args.sshd_logpath;
|
||||
for p in sshd_logpaths {
|
||||
ml.add_file(&p).await?;
|
||||
log!("starting with sshd parsing at {:?}", &p);
|
||||
}
|
||||
|
||||
// common log format
|
||||
let clf_logpaths = &args.clf_logpath;
|
||||
for p in clf_logpaths {
|
||||
@@ -54,11 +46,7 @@ async fn run() -> Result<()> {
|
||||
log!("starting with json parsing at {:?}", &p);
|
||||
}
|
||||
|
||||
if json_logpaths.is_empty()
|
||||
&& clf_logpaths.is_empty()
|
||||
&& sshd_logpaths.is_empty()
|
||||
&& generic_paths.is_empty()
|
||||
{
|
||||
if json_logpaths.is_empty() && clf_logpaths.is_empty() && generic_paths.is_empty() {
|
||||
bail!("no log files to parse, see --help");
|
||||
}
|
||||
|
||||
@@ -70,9 +58,7 @@ async fn run() -> Result<()> {
|
||||
let path_buf = Some(line.source().to_path_buf());
|
||||
let path = path_buf.as_ref();
|
||||
|
||||
let (target, ret) = if path.is_some_and(|p| sshd_logpaths.contains(p)) {
|
||||
("sshd", sshd::parse(payload)?)
|
||||
} else if path.is_some_and(|p| clf_logpaths.contains(p)) {
|
||||
let (target, ret) = if path.is_some_and(|p| clf_logpaths.contains(p)) {
|
||||
("clf", clf::parse(payload, invalid_statuses_ref)?)
|
||||
} else if path.is_some_and(|p| json_logpaths.contains(p)) {
|
||||
("json", json::parse(payload, invalid_statuses_ref)?)
|
||||
|
||||
-96
@@ -1,96 +0,0 @@
|
||||
use anyhow::*;
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
use std::{net::IpAddr, str::FromStr};
|
||||
|
||||
use crate::utils::ParsingStatus;
|
||||
|
||||
struct Rule {
|
||||
matcher: String,
|
||||
extractor: Regex,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref SSHD_BAD: [Rule; 3] = [
|
||||
Rule {
|
||||
matcher: "Failed password".to_string(),
|
||||
extractor: Regex::new(r"(from.)(\S+)").unwrap(),
|
||||
},
|
||||
Rule {
|
||||
matcher: "Invalid user ".to_string(),
|
||||
extractor: Regex::new(r"(from.)(\S+)").unwrap(),
|
||||
},
|
||||
Rule {
|
||||
matcher: "authentication failure".to_string(),
|
||||
extractor: Regex::new(r"(rhost=)(\S+)").unwrap()
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
pub fn parse(line: &str) -> Result<ParsingStatus> {
|
||||
let hits = SSHD_BAD
|
||||
.iter()
|
||||
.find(|rule| line.contains(&rule.matcher))
|
||||
.and_then(|r| r.extractor.captures(line));
|
||||
|
||||
if hits.is_none() {
|
||||
return Ok(ParsingStatus::OkEntry);
|
||||
}
|
||||
|
||||
let ip = hits
|
||||
.and_then(|c| c.get(2))
|
||||
.and_then(|m| IpAddr::from_str(m.as_str()).ok())
|
||||
.ok_or_else(|| anyhow!("cant parse sshd line"))?;
|
||||
|
||||
Ok(ParsingStatus::BadEntry(ip))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn positive() {
|
||||
let vectors = [
|
||||
"Sep 26 06:25:19 livecompute sshd[23246]: Failed password for root from 179.124.36.195 port 41883 ssh2",
|
||||
"Sep 26 06:26:14 livecompute sshd[23292]: pam_unix(sshd:auth): authentication failure; logname= u =0 tty=ssh ruser= rhost=5.101.107.190",
|
||||
"Sep 26 06:25:32 livecompute sshd[23254]: Invalid user neal from 35.184.211.144"
|
||||
];
|
||||
|
||||
vectors.iter().for_each(|e| {
|
||||
let ret = parse(*e).unwrap();
|
||||
match ret {
|
||||
ParsingStatus::BadEntry(_) => {}
|
||||
_ => panic!("bad parsing"),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn negative() {
|
||||
let vectors = [
|
||||
"Sep 26 06:25:19 livecompute sshd[23246]: successful login 179.124.36.195 port 41883 ssh2",
|
||||
"Sep 26 06:26:14 livecompute sshd[23292]: pam_unix(sshd:auth): authentication total success; logname= u =0 tty=ssh ruser= rhost=5.101.107.190",
|
||||
"Sep 26 06:25:32 livecompute sshd[23254]: very good user neal from 35.184.211.144"
|
||||
];
|
||||
|
||||
vectors.iter().for_each(|e| {
|
||||
let ret = parse(*e).unwrap();
|
||||
match ret {
|
||||
ParsingStatus::OkEntry => {}
|
||||
_ => panic!("bad parsing"),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn malformed() {
|
||||
let vectors = [
|
||||
"Sep 26 06:25:19 livecompute sshd[23246]: Failed password for root from 179.124.36.195.232 port 41883 ssh2",
|
||||
];
|
||||
|
||||
vectors.iter().for_each(|e| {
|
||||
parse(*e).expect_err("");
|
||||
})
|
||||
}
|
||||
}
|
||||
+3
-7
@@ -86,11 +86,11 @@ Blockfast - block internets scanners fast 🍶
|
||||
Author: pierre dubouilh <pldubouilh@gmail.com>
|
||||
|
||||
Blockfast reads logs from various sources and blocks the offending IPs using iptables and ipset.
|
||||
It supports logs from sshd, Common-Log-Format (Apache, etc..), JSON (Caddy) and a generic logs parser.
|
||||
It supports logs in Common-Log-Format (Apache, etc..), JSON (Caddy) and a generic logs parser.
|
||||
|
||||
Example:
|
||||
# block invalid sshd attempts & invalid http statuses from caddy
|
||||
./blockfast -s=/var/log/auth.log -j=/caddy/logs
|
||||
# block invalid http statuses from caddy
|
||||
./blockfast -j=/caddy/logs
|
||||
|
||||
# generic log parser example with a log text to flag, and a regex to parse the offending IP.
|
||||
./blockfast --generic-logpath=/tmp/generictest --generic-positive='Failed password' --generic-ip='from ([0-9a-fA-F:.]+) port'",
|
||||
@@ -110,10 +110,6 @@ pub struct Args {
|
||||
#[clap(short, long)]
|
||||
pub verbose: bool,
|
||||
|
||||
/// path of sshd logfile, can be repeated
|
||||
#[clap(short, long, value_parser = resolve_path)]
|
||||
pub sshd_logpath: Vec<PathBuf>,
|
||||
|
||||
/// path of Common-Log-Format logfile (Apache, etc..), can be repeated
|
||||
#[clap(short, long, value_parser = resolve_path)]
|
||||
pub clf_logpath: Vec<PathBuf>,
|
||||
|
||||
Reference in New Issue
Block a user