feat: add GeoIP country lookup with embedded DB-IP Lite database (PLAN.md 4.3)
Embeds a DB-IP Lite country MMDB (~5MB) in the binary via go:embed, keeping the single-binary deployment story clean. Country codes are stored alongside login attempts and sessions, shown in the dashboard (Top IPs, Top Countries card, Recent/Active Sessions, session detail). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ type LoginAttempt struct {
|
||||
Username string
|
||||
Password string
|
||||
IP string
|
||||
Country string
|
||||
Count int
|
||||
FirstSeen time.Time
|
||||
LastSeen time.Time
|
||||
@@ -20,6 +21,7 @@ type LoginAttempt struct {
|
||||
type Session struct {
|
||||
ID string
|
||||
IP string
|
||||
Country string
|
||||
Username string
|
||||
ShellName string
|
||||
ConnectedAt time.Time
|
||||
@@ -54,18 +56,19 @@ type DashboardStats struct {
|
||||
|
||||
// TopEntry represents a value and its count for top-N queries.
|
||||
type TopEntry struct {
|
||||
Value string
|
||||
Count int64
|
||||
Value string
|
||||
Country string // populated by GetTopIPs
|
||||
Count int64
|
||||
}
|
||||
|
||||
// Store is the interface for persistent storage of honeypot data.
|
||||
type Store interface {
|
||||
// RecordLoginAttempt upserts a login attempt, incrementing the count
|
||||
// for existing (username, password, ip) combinations.
|
||||
RecordLoginAttempt(ctx context.Context, username, password, ip string) error
|
||||
RecordLoginAttempt(ctx context.Context, username, password, ip, country string) error
|
||||
|
||||
// CreateSession creates a new session record and returns its UUID.
|
||||
CreateSession(ctx context.Context, ip, username, shellName string) (string, error)
|
||||
CreateSession(ctx context.Context, ip, username, shellName, country string) (string, error)
|
||||
|
||||
// EndSession sets the disconnected_at timestamp for a session.
|
||||
EndSession(ctx context.Context, sessionID string, disconnectedAt time.Time) error
|
||||
@@ -92,6 +95,9 @@ type Store interface {
|
||||
// GetTopIPs returns the top N IPs by total attempt count.
|
||||
GetTopIPs(ctx context.Context, limit int) ([]TopEntry, error)
|
||||
|
||||
// GetTopCountries returns the top N countries by total attempt count.
|
||||
GetTopCountries(ctx context.Context, limit int) ([]TopEntry, error)
|
||||
|
||||
// GetRecentSessions returns the most recent sessions ordered by connected_at DESC.
|
||||
// If activeOnly is true, only sessions with no disconnected_at are returned.
|
||||
GetRecentSessions(ctx context.Context, limit int, activeOnly bool) ([]Session, error)
|
||||
|
||||
Reference in New Issue
Block a user