From b63da17043ef27d3912c79b27b9cc4660e0ba6d9 Mon Sep 17 00:00:00 2001 From: d3m0k1d Date: Tue, 13 Jan 2026 16:53:46 +0300 Subject: [PATCH] Feat: add storage block(first methods to db, migrations, models) add nginx parser with regular expression, add to deps sqlite driver --- go.mod | 1 + go.sum | 2 ++ internal/parser/NginxParser.go | 41 +++++++++++++++++++++++++++++++++ internal/storage/db.go | 42 ++++++++++++++++++++++++++++++++++ internal/storage/migrations.go | 27 ++++++++++++++++++++++ internal/storage/models.go | 15 ++++++++++++ 6 files changed, 128 insertions(+) create mode 100644 internal/parser/NginxParser.go create mode 100644 internal/storage/db.go create mode 100644 internal/storage/migrations.go create mode 100644 internal/storage/models.go diff --git a/go.mod b/go.mod index b7ec84e..181cfb2 100644 --- a/go.mod +++ b/go.mod @@ -9,5 +9,6 @@ require ( require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/mattn/go-sqlite3 v1.14.33 // indirect github.com/spf13/pflag v1.0.10 // indirect ) diff --git a/go.sum b/go.sum index e5ddfcb..2349eee 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,8 @@ github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2 github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/mattn/go-sqlite3 v1.14.33 h1:A5blZ5ulQo2AtayQ9/limgHEkFreKj1Dv226a1K73s0= +github.com/mattn/go-sqlite3 v1.14.33/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= diff --git a/internal/parser/NginxParser.go b/internal/parser/NginxParser.go new file mode 100644 index 0000000..27014e8 --- /dev/null +++ b/internal/parser/NginxParser.go @@ -0,0 +1,41 @@ +package parser + +import ( + "fmt" + "regexp" + + "github.com/d3m0k1d/BanForge/internal/logger" + "github.com/d3m0k1d/BanForge/internal/storage" +) + +type NginxParser struct { + pattern *regexp.Regexp + logger *logger.Logger +} + +func NewNginxParser() *NginxParser { + pattern := regexp.MustCompile( + `^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*\[(.*?)\]\s+"(\w+)\s+(.*?)\s+HTTP.*"\s+(\d+)`, + ) + return &NginxParser{ + pattern: pattern, + logger: logger.New(false), + } +} + +func (p *NginxParser) Parse(line string) (*storage.LogEntry, error) { + // Group 1: IP, Group 2: Timestamp, Group 3: Method, Group 4: Path, Group 5: Status + matches := p.pattern.FindStringSubmatch(line) + if matches == nil { + return nil, fmt.Errorf("invalid log format") + } + + return &storage.LogEntry{ + Service: "nginx", + IP: matches[1], + Path: &matches[4], + Status: &matches[5], + Method: &matches[3], + Reason: nil, + }, nil +} diff --git a/internal/storage/db.go b/internal/storage/db.go new file mode 100644 index 0000000..6795ce8 --- /dev/null +++ b/internal/storage/db.go @@ -0,0 +1,42 @@ +package storage + +import ( + "database/sql" + + "github.com/d3m0k1d/BanForge/internal/logger" + _ "github.com/mattn/go-sqlite3" +) + +type DB struct { + logger *logger.Logger + db *sql.DB +} + +func NewDB(path string) (*DB, error) { + db, err := sql.Open("sqlite3", "/var/lib/banforge/storage.db") + if err != nil { + return nil, err + } + return &DB{ + logger: logger.New(false), + db: db, + }, nil +} + +func (d *DB) Close() error { + d.logger.Info("Closing database connection") + err := d.db.Close() + if err != nil { + return err + } + return nil +} + +func (d *DB) CreateTable() error { + _, err := d.db.Exec(CreateTables) + if err != nil { + return err + } + d.logger.Info("Created tables") + return nil +} diff --git a/internal/storage/migrations.go b/internal/storage/migrations.go new file mode 100644 index 0000000..5375f8d --- /dev/null +++ b/internal/storage/migrations.go @@ -0,0 +1,27 @@ +package storage + +const CreateTables = ` + +CREATE TABLE IF NOT EXISTS requests ( + id INTEGER PRIMARY KEY, + service TEXT NOT NULL, + ip TEXT NOT NULL, + path TEXT, + method TEXT, + status TEXT, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE IF NOT EXISTS bans ( + id INTEGER PRIMARY KEY, + ip TEXT UNIQUE NOT NULL, + reason TEXT, + banned_at DATETIME DEFAULT CURRENT_TIMESTAMP +); + +CREATE INDEX IF NOT EXISTS idx_service ON requests(service); +CREATE INDEX IF NOT EXISTS idx_ip ON requests(ip); +CREATE INDEX IF NOT EXISTS idx_status ON requests(status); +CREATE INDEX IF NOT EXISTS idx_created_at ON requests(created_at); +CREATE INDEX IF NOT EXISTS idx_ban_ip ON bans(ip); + ` diff --git a/internal/storage/models.go b/internal/storage/models.go new file mode 100644 index 0000000..98d4c62 --- /dev/null +++ b/internal/storage/models.go @@ -0,0 +1,15 @@ +package storage + +type LogEntry struct { + Service string + IP string + Path *string + Status *string + Method *string + Reason *string +} + +type Ban struct { + IP string + Reason *string +}