fix: restore recurring GeoIP checks
This commit is contained in:
@@ -40,7 +40,7 @@ type Daemon struct {
|
||||
mu sync.Mutex
|
||||
seen map[string]time.Time
|
||||
events []queryEvent
|
||||
geoSeen map[string]bool
|
||||
geoSeen map[string]time.Time
|
||||
wl map[string]bool
|
||||
|
||||
serviceMu sync.Mutex
|
||||
@@ -93,7 +93,7 @@ func New(c *config.Config) (*Daemon, error) {
|
||||
d := &Daemon{
|
||||
Config: c, Store: st, FW: fw, Logger: logger,
|
||||
Client: &http.Client{Timeout: 20 * time.Second, Transport: tr},
|
||||
seen: map[string]time.Time{}, geoSeen: map[string]bool{},
|
||||
seen: map[string]time.Time{}, geoSeen: map[string]time.Time{},
|
||||
}
|
||||
d.Geo = geoip.New(c.GeoIPMMDBPath, c.GeoIPLicenseKey, filepath.Join(filepath.Dir(c.Path), "geoip"), c.GeoIPCacheTTL, st)
|
||||
return d, nil
|
||||
@@ -409,13 +409,6 @@ func (d *Daemon) checkGeoIP(ctx context.Context, ip string) {
|
||||
if d.Config.GeoIPSkipPrivate && geoip.IsPrivateIP(ip) {
|
||||
return
|
||||
}
|
||||
d.mu.Lock()
|
||||
if d.geoSeen[ip] {
|
||||
d.mu.Unlock()
|
||||
return
|
||||
}
|
||||
d.geoSeen[ip] = true
|
||||
d.mu.Unlock()
|
||||
if d.isWhitelisted(ip) {
|
||||
return
|
||||
}
|
||||
@@ -423,6 +416,9 @@ func (d *Daemon) checkGeoIP(ctx context.Context, ip string) {
|
||||
if exists {
|
||||
return
|
||||
}
|
||||
if !d.shouldCheckGeoIP(ip, time.Now()) {
|
||||
return
|
||||
}
|
||||
cc, err := d.Geo.Lookup(ip)
|
||||
if err != nil || cc == "" {
|
||||
return
|
||||
@@ -432,6 +428,41 @@ func (d *Daemon) checkGeoIP(ctx context.Context, ip string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Daemon) shouldCheckGeoIP(ip string, now time.Time) bool {
|
||||
interval := d.geoIPCheckInterval()
|
||||
d.mu.Lock()
|
||||
defer d.mu.Unlock()
|
||||
if last, ok := d.geoSeen[ip]; ok && now.Sub(last) < interval {
|
||||
return false
|
||||
}
|
||||
d.geoSeen[ip] = now
|
||||
d.pruneGeoSeenLocked(now, interval)
|
||||
return true
|
||||
}
|
||||
|
||||
func (d *Daemon) geoIPCheckInterval() time.Duration {
|
||||
seconds := 0
|
||||
if d.Config != nil {
|
||||
seconds = d.Config.GeoIPCheckInterval
|
||||
if seconds <= 0 {
|
||||
seconds = d.Config.CheckInterval
|
||||
}
|
||||
}
|
||||
if seconds <= 0 {
|
||||
seconds = 1
|
||||
}
|
||||
return time.Duration(seconds) * time.Second
|
||||
}
|
||||
|
||||
func (d *Daemon) pruneGeoSeenLocked(now time.Time, interval time.Duration) {
|
||||
cutoff := now.Add(-2 * interval)
|
||||
for ip, last := range d.geoSeen {
|
||||
if last.Before(cutoff) {
|
||||
delete(d.geoSeen, ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Daemon) Ban(ctx context.Context, ip, domain string, count int, proto, reason, source, country string, permanent bool) error {
|
||||
if d.isWhitelisted(ip) {
|
||||
return nil
|
||||
|
||||
@@ -363,3 +363,37 @@ func TestDryRunDoesNotInsertActiveBan(t *testing.T) {
|
||||
t.Fatal("dry-run must not create an active ban")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeoIPCheckGateUsesConfiguredInterval(t *testing.T) {
|
||||
now := time.Unix(1000, 0)
|
||||
d := &Daemon{
|
||||
Config: &config.Config{CheckInterval: 10, GeoIPCheckInterval: 30},
|
||||
geoSeen: map[string]time.Time{},
|
||||
}
|
||||
if !d.shouldCheckGeoIP("203.0.113.7", now) {
|
||||
t.Fatal("first GeoIP check should be allowed")
|
||||
}
|
||||
if d.shouldCheckGeoIP("203.0.113.7", now.Add(29*time.Second)) {
|
||||
t.Fatal("GeoIP check inside configured interval should be skipped")
|
||||
}
|
||||
if !d.shouldCheckGeoIP("203.0.113.7", now.Add(30*time.Second)) {
|
||||
t.Fatal("GeoIP check after configured interval should be allowed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGeoIPCheckGateFallsBackToPollInterval(t *testing.T) {
|
||||
now := time.Unix(1000, 0)
|
||||
d := &Daemon{
|
||||
Config: &config.Config{CheckInterval: 10},
|
||||
geoSeen: map[string]time.Time{},
|
||||
}
|
||||
if !d.shouldCheckGeoIP("203.0.113.7", now) {
|
||||
t.Fatal("first GeoIP check should be allowed")
|
||||
}
|
||||
if d.shouldCheckGeoIP("203.0.113.7", now.Add(9*time.Second)) {
|
||||
t.Fatal("GeoIP check inside poll interval should be skipped")
|
||||
}
|
||||
if !d.shouldCheckGeoIP("203.0.113.7", now.Add(10*time.Second)) {
|
||||
t.Fatal("GeoIP check after poll interval should be allowed")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user