html terminal
Diffstat (limited to 'src/alerts.rs')
| -rw-r--r-- | src/alerts.rs | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/alerts.rs b/src/alerts.rs new file mode 100644 index 0000000..a16ba0e --- /dev/null +++ b/src/alerts.rs @@ -0,0 +1,73 @@ +use emoji::named::*; +use regex::Regex; +use std::{ + sync::{ + atomic::{ + AtomicU64, + Ordering::{Acquire, Relaxed}, + }, + LazyLock, + }, + time::Duration, +}; +use tokio::{ + io::{AsyncBufReadExt, AsyncReadExt}, + sync::broadcast::error::TryRecvError, +}; +pub async fn run() { + let (tx, mut rx) = tokio::sync::broadcast::channel::<u64>(10); + static COUNT: AtomicU64 = AtomicU64::new(0); + let mut f = + tokio::io::BufReader::new(tokio::fs::File::open("/var/log/kern.log").await.unwrap()); + let mut buf = [0; 1 << 20]; + while f.read(&mut buf).await.unwrap() != 0 {} + static RE: LazyLock<Regex> = LazyLock::new(|| { + Regex::new("[^ ]+ [0-9]+ [0-9]+:[0-9]+:[0-9]+ .+ kernel: [[0-9]+.[0-9]+] IN=.+ OUT= MAC=.+ SRC=([0-9]+.[0-9]+.[0-9]+.[0-9]+) DST=[0-9]+.[0-9]+.[0-9]+.[0-9]+ LEN=[0-9]+ TOS=0x[0-9a-f]+ PREC=0x[0-9a-f]+ TTL=[0-9]+ ID=[0-9]+(?: DF)? PROTO=TCP SPT=[0-9]+ DPT=[0-9]+ WINDOW=[0-9]+ RES=0x[a-f0-9]+ SYN URGP=[0-9]").unwrap() + }); + tokio::spawn(async move { + loop { + let mut s = String::new(); + f.read_line(&mut s).await.unwrap(); + if RE.is_match(&s) { + COUNT.fetch_add(1, Relaxed); + } + tokio::time::sleep(tokio::time::Duration::from_millis(5)).await; + } + }); + tokio::spawn(async move { + let mut alarmed = tokio::time::Instant::now() - Duration::from_secs(5 * 60); + loop { + let before = COUNT.load(Acquire); + tokio::time::sleep(tokio::time::Duration::from_secs(5)).await; + let after = COUNT.load(Acquire); + let δ = after - before; + let now = tokio::time::Instant::now(); + if δ > 10 && alarmed < now - Duration::from_secs(5 * 60) { + alarmed = now; + tx.send((δ + 1) / 5).unwrap(); + } + } + }); + let http = serenity::http::Http::new(""); + let wh = + std::env::var("AOOK").unwrap_or(std::fs::read_to_string("aook").expect("wher webhook")); + let wh = crate::webhook::Webhook::new(&http, &wh).await; + loop { + match rx.try_recv() { + Ok(x) => { + wh.send(|m| { + m.content(&format!( + "{WARNING} <@&1202414272030974033> attacked by {x} bots/s" + )) + }) + .await; + } + Err(TryRecvError::Closed) => panic!(), + Err(TryRecvError::Lagged(_)) => continue, + Err(TryRecvError::Empty) => { + tokio::time::sleep(Duration::from_secs(4)).await; + continue; + } + } + } +} |