You've already forked caddy-opnsense-blocker
Add background IP intel and restore dashboard stats
This commit is contained in:
@@ -159,6 +159,87 @@ sources:
|
||||
}
|
||||
}
|
||||
|
||||
func TestServiceBackgroundInvestigationEnrichesRecentIPs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tempDir := t.TempDir()
|
||||
logPath := filepath.Join(tempDir, "access.log")
|
||||
if err := os.WriteFile(logPath, nil, 0o600); err != nil {
|
||||
t.Fatalf("create log: %v", err)
|
||||
}
|
||||
|
||||
configPath := filepath.Join(tempDir, "config.yaml")
|
||||
payload := fmt.Sprintf(`storage:
|
||||
path: %s/blocker.db
|
||||
investigation:
|
||||
enabled: true
|
||||
refresh_after: 24h
|
||||
timeout: 500ms
|
||||
background_workers: 1
|
||||
background_poll_interval: 50ms
|
||||
background_lookback: 24h
|
||||
background_batch_size: 32
|
||||
profiles:
|
||||
main:
|
||||
auto_block: false
|
||||
block_unexpected_posts: true
|
||||
suspicious_path_prefixes:
|
||||
- /wp-login.php
|
||||
sources:
|
||||
- name: main
|
||||
path: %s
|
||||
profile: main
|
||||
initial_position: beginning
|
||||
poll_interval: 20ms
|
||||
batch_size: 128
|
||||
`, tempDir, logPath)
|
||||
if err := os.WriteFile(configPath, []byte(payload), 0o600); err != nil {
|
||||
t.Fatalf("write config: %v", err)
|
||||
}
|
||||
|
||||
cfg, err := config.Load(configPath)
|
||||
if err != nil {
|
||||
t.Fatalf("load config: %v", err)
|
||||
}
|
||||
database, err := store.Open(cfg.Storage.Path)
|
||||
if err != nil {
|
||||
t.Fatalf("open store: %v", err)
|
||||
}
|
||||
defer database.Close()
|
||||
investigator := &fakeInvestigator{}
|
||||
svc := New(cfg, database, nil, investigator, log.New(os.Stderr, "", 0))
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
go func() { _ = svc.Run(ctx) }()
|
||||
|
||||
appendLine(t, logPath, caddyJSONLine("203.0.113.33", "198.51.100.33", "example.test", "GET", "/wp-login.php", 404, "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)", time.Now().UTC()))
|
||||
|
||||
waitFor(t, 3*time.Second, func() bool {
|
||||
recentRows, err := svc.ListRecentIPs(context.Background(), time.Now().UTC().Add(-time.Hour), 10)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
row, found := findRecentIPRow(recentRows, "203.0.113.33")
|
||||
return found && row.Bot != nil && row.Bot.Name == "Googlebot"
|
||||
})
|
||||
|
||||
recentRows, err := svc.ListRecentIPs(context.Background(), time.Now().UTC().Add(-time.Hour), 10)
|
||||
if err != nil {
|
||||
t.Fatalf("list recent ips: %v", err)
|
||||
}
|
||||
row, found := findRecentIPRow(recentRows, "203.0.113.33")
|
||||
if !found {
|
||||
t.Fatalf("expected recent row for investigated ip: %+v", recentRows)
|
||||
}
|
||||
if row.Bot == nil || row.Bot.Name != "Googlebot" {
|
||||
t.Fatalf("expected background investigation bot on recent row, got %+v", row)
|
||||
}
|
||||
if investigator.callCount() == 0 {
|
||||
t.Fatalf("expected background investigator to be called")
|
||||
}
|
||||
}
|
||||
|
||||
type fakeOPNsenseServer struct {
|
||||
*httptest.Server
|
||||
mu sync.Mutex
|
||||
@@ -269,3 +350,30 @@ func findRecentIPRow(items []model.RecentIPRow, ip string) (model.RecentIPRow, b
|
||||
}
|
||||
return model.RecentIPRow{}, false
|
||||
}
|
||||
|
||||
type fakeInvestigator struct {
|
||||
mu sync.Mutex
|
||||
count int
|
||||
}
|
||||
|
||||
func (f *fakeInvestigator) Investigate(_ context.Context, ip string, _ []string) (model.IPInvestigation, error) {
|
||||
f.mu.Lock()
|
||||
f.count++
|
||||
f.mu.Unlock()
|
||||
return model.IPInvestigation{
|
||||
IP: ip,
|
||||
UpdatedAt: time.Now().UTC(),
|
||||
Bot: &model.BotMatch{
|
||||
ProviderID: "google_official",
|
||||
Name: "Googlebot",
|
||||
Method: "test",
|
||||
Verified: true,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (f *fakeInvestigator) callCount() int {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
return f.count
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user