drop sshd support

This commit is contained in:
Pierre Dubouilh
2026-08-28 00:34:23 +02:00
committed by Pierre Dubouilh
parent ac17c11158
commit e63e926ccf
5 changed files with 19 additions and 144 deletions
+1 -8
View File
@@ -8,12 +8,11 @@ build::
cargo fmt --all
run::
touch /tmp/sshdtest
touch /tmp/clftest
touch /tmp/jsontest
touch /tmp/generictest
cargo build
sudo target/debug/blockfast -v -s=/tmp/sshdtest -c=/tmp/clftest -j=/tmp/jsontest --generic-logpath=/tmp/generictest --generic-ip='from ([0-9a-fA-F:.]+) port' --generic-positive='Failed password'
sudo target/debug/blockfast -v -c=/tmp/clftest -j=/tmp/jsontest --generic-logpath=/tmp/generictest --generic-ip='from ([0-9a-fA-F:.]+) port' --generic-positive='Failed password'
ci:: test
cargo fmt --all -- --check
@@ -44,12 +43,6 @@ test::
release::
cargo build --target x86_64-unknown-linux-musl --release
hit-sshd::
echo "Sep 26 06:25:32 livecompute sshd[23254]: Invalid user neal from 9.124.36.195" >> /tmp/sshdtest
ok-sshd::
echo "Sep 26 06:25:19 livecompute sshd[23246]: successful login 8.124.36.195 port 41883 ssh2" >> /tmp/sshdtest
hit-generic::
echo "Sep 26 06:25:19 livecompute sshd[23246]: Failed password for root from 179.124.36.195 port 41883 ssh2" >> /tmp/generictest
+13 -17
View File
@@ -3,7 +3,6 @@
Block internets scanners fast 🍶
Features:
- SSH log parser
- Common Log Format parser (apache logs, etc...)
- JSON log parser (caddy logs)
- Generic log parser
@@ -14,16 +13,15 @@ Features:
## example
```txt
$ ./blockfast -s=/var/log/auth.log -j=/caddy/logs
1737927469 - starting with sshd parsing at "/tmp/sshdtest"
$ ./blockfast -j=/caddy/logs
1737927469 - starting with json parsing at "/tmp/jsontest"
1737927469 - jail setup, allowance 5, time 21600s
1737927477 - sshd logged offence for 9.124.36.195
1737927478 - sshd logged offence for 9.124.36.195
1737927479 - sshd logged offence for 9.124.36.195
1737927479 - sshd logged offence for 9.124.36.195
1737927480 - sshd logged offence for 9.124.36.195
1737927480 - sshd jailtime for 9.124.36.195
1737927477 - json logged offence for 9.124.36.195
1737927478 - json logged offence for 9.124.36.195
1737927479 - json logged offence for 9.124.36.195
1737927479 - json logged offence for 9.124.36.195
1737927480 - json logged offence for 9.124.36.195
1737927480 - json jailtime for 9.124.36.195
```
## build
@@ -36,11 +34,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'
@@ -54,14 +52,12 @@ Options:
how many offences allowed (max 255) [default: 5]
-v, --verbose
log all offences
-s, --sshd-logpath <SSHD_LOGPATH>
path of sshd logfile
-c, --clf-logpath <CLF_LOGPATH>
path of Common-Log-Format logfile (Apache, etc..)
path of Common-Log-Format logfile (Apache, etc..), can be repeated
-j, --json-logpath <JSON_LOGPATH>
path of JSON logfile (works with Caddy)
path of JSON logfile (works with Caddy), can be repeated
--generic-logpath <GENERIC_LOGPATH>
generic parser log file path
generic parser log file path, can be repeated
--generic-ip <GENERIC_IP>
generic parser ip regex
--generic-positive <GENERIC_POSITIVE>
+2 -16
View File
@@ -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
View File
@@ -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
View File
@@ -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>,