html terminal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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;
            }
        }
    }
}