mirror of
https://github.com/pldubouilh/blockfast.git
synced 2026-08-28 04:46:58 -04:00
drop sshd support
This commit is contained in:
committed by
Pierre Dubouilh
parent
ac17c11158
commit
e63e926ccf
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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