From 237116f2516834f181d3bba19f45bd7efba2b8b9 Mon Sep 17 00:00:00 2001 From: Vomitblood Date: Sun, 9 Feb 2025 17:05:57 +0800 Subject: [PATCH] changed modsecurity logs location --- .gitignore | 10 ++- docker/chungus/docker-compose.yml | 6 +- docker/chungus/setup.sh | 13 ++-- server/go.mod | 2 + server/go.sum | 4 ++ server/internal/telegram/telegram.go | 99 +++++++++++++++++++++++----- 6 files changed, 102 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index 3575be2..37b2df7 100644 --- a/.gitignore +++ b/.gitignore @@ -20,9 +20,7 @@ # server server/server -# nginx logs -docker/suricata/nginx/logs/access.log -docker/suricata/nginx/logs/error.log - -# suricata logs -docker/suricata/suricata/logs/* \ No newline at end of file +# logs +**/*.log +**/*.pcap* +**/eve.json \ No newline at end of file diff --git a/docker/chungus/docker-compose.yml b/docker/chungus/docker-compose.yml index f8527e0..5200632 100644 --- a/docker/chungus/docker-compose.yml +++ b/docker/chungus/docker-compose.yml @@ -29,9 +29,9 @@ services: PARANOIA: 1 network_mode: "host" volumes: - - "/tmp/host-fs-auditlog.log:/var/log/modsec_audit.log" - - "/tmp/host-fs-errorlog.log:/var/log/modsec_error.log" - - "/tmp/host-fs-accesslog.log:/var/log/apache2/access.log" + - "./logs/host-fs-auditlog.log:/var/log/modsec_audit.log" + - "./logs/host-fs-errorlog.log:/var/log/modsec_error.log" + - "./logs/host-fs-accesslog.log:/var/log/apache2/access.log" dvwa: image: vulnerables/web-dvwa diff --git a/docker/chungus/setup.sh b/docker/chungus/setup.sh index 1c69e9d..b762f60 100644 --- a/docker/chungus/setup.sh +++ b/docker/chungus/setup.sh @@ -1,6 +1,7 @@ -touch /tmp/host-fs-auditlog.log -touch /tmp/host-fs-errorlog.log -touch /tmp/host-fs-accesslog.log -chmod 777 /tmp/host-fs-auditlog.log -chmod 777 /tmp/host-fs-errorlog.log -chmod 777 /tmp/host-fs-accesslog.log \ No newline at end of file +mkdir logs +touch ./logs/host-fs-auditlog.log +touch ./logs/host-fs-errorlog.log +touch ./logs/host-fs-accesslog.log +chmod 777 ./logs/host-fs-auditlog.log +chmod 777 ./logs/host-fs-errorlog.log +chmod 777 ./logs/host-fs-accesslog.log \ No newline at end of file diff --git a/server/go.mod b/server/go.mod index 1a26945..3061caf 100644 --- a/server/go.mod +++ b/server/go.mod @@ -5,6 +5,7 @@ go 1.23.2 require github.com/jackc/pgx/v5 v5.7.1 require ( + github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect @@ -14,5 +15,6 @@ require ( github.com/tidwall/pretty v1.2.0 // indirect golang.org/x/crypto v0.32.0 // indirect golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect ) diff --git a/server/go.sum b/server/go.sum index 866e910..248432a 100644 --- a/server/go.sum +++ b/server/go.sum @@ -1,6 +1,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= +github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= @@ -28,6 +30,8 @@ golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/server/internal/telegram/telegram.go b/server/internal/telegram/telegram.go index dcdd61c..a1086b0 100644 --- a/server/internal/telegram/telegram.go +++ b/server/internal/telegram/telegram.go @@ -2,21 +2,29 @@ package telegram import ( "bufio" + "encoding/json" "fmt" - "io" "log" "os" - "time" + "github.com/fsnotify/fsnotify" tg "github.com/go-telegram-bot-api/telegram-bot-api/v5" ) const ( - modsecLogFile = "/tmp/host-fs-auditlog.log" + modsecLogFile = "/home/vomitblood/build/cspj-application/docker/chungus/logs/host-fs-auditlog.log" telegramToken = "7215466800:AAGwjZnXEfbbjQiA0y7qtSzbSZNUWQJnyjo" telegramChatID = 622943829 ) +var lastReadPosition int64 = 0 + +type LogEntry struct { + AuditData struct { + Messages []string `json:"messages"` + } `json:"audit_data"` +} + func TelegramBotInit() { bot, err := tg.NewBotAPI(telegramToken) if err != nil { @@ -32,28 +40,85 @@ func TelegramBotInit() { log.Fatal("Failed to send test message:", err) } - // open the log file - logFile, err := os.Open(modsecLogFile) + // Start watching the log file for changes + watchLogFile(bot) +} + +func watchLogFile(bot *tg.BotAPI) { + watcher, err := fsnotify.NewWatcher() if err != nil { - log.Fatal("Failed to open log file:", err) + log.Fatal("Failed to initialize watcher:", err) } - defer logFile.Close() + defer watcher.Close() - // seek to the end of the file to read only new entries - logFile.Seek(0, io.SeekEnd) + // Add log file to watcher + err = watcher.Add(modsecLogFile) + if err != nil { + log.Fatal("Failed to watch log file:", err) + } + + log.Println("🔍 Monitoring log file for changes...") - reader := bufio.NewReader(logFile) for { - line, err := reader.ReadString('\n') - if err == nil { - sendTelegramAlert(bot, line) + select { + case event, ok := <-watcher.Events: + if !ok { + return + } + if event.Op&fsnotify.Write == fsnotify.Write { + log.Println("📄 Log file updated, reading new entries...") + readNewLines(bot) + } + + case err, ok := <-watcher.Errors: + if !ok { + return + } + log.Println("⚠️ Watcher error:", err) } - // maybe change this logic? interrupt vs polling?????? - time.Sleep(1 * time.Second) + } +} + +func readNewLines(bot *tg.BotAPI) { + file, err := os.Open(modsecLogFile) + if err != nil { + log.Println("❌ Failed to reopen log file:", err) + return + } + defer file.Close() + + // Move to the last read position + file.Seek(lastReadPosition, os.SEEK_SET) + scanner := bufio.NewScanner(file) + + for scanner.Scan() { + line := scanner.Text() + var logEntry LogEntry + + // Try to parse JSON + if err := json.Unmarshal([]byte(line), &logEntry); err != nil { + log.Println("⚠️ Failed to parse JSON:", err) + continue // Skip invalid JSON lines + } + + // Send only the first message from messages[] + if len(logEntry.AuditData.Messages) > 0 { + sendTelegramAlert(bot, logEntry.AuditData.Messages[0]) + } + } + + // Update last read position + lastReadPosition, _ = file.Seek(0, os.SEEK_CUR) + + if err := scanner.Err(); err != nil { + log.Println("❌ Error reading log file:", err) } } func sendTelegramAlert(bot *tg.BotAPI, message string) { - msg := tg.NewMessage(telegramChatID, fmt.Sprintf("*WEEWOO ALERT*\n%s", message)) - bot.Send(msg) + msg := tg.NewMessage(telegramChatID, fmt.Sprintf("🚨 *WEEWOO ALERT* 🚨\n%s", message)) + _, err := bot.Send(msg) + if err != nil { + log.Println("❌ Failed to send Telegram message:", err) + } }