Add GeoIP support with configurable service and logger integration

This commit is contained in:
2026-04-11 17:35:55 +05:00
parent 1298685ca4
commit 9bfabd2148
6 changed files with 143 additions and 0 deletions
+3
View File
@@ -4,6 +4,7 @@ go 1.25
require (
git.kor-elf.net/kor-elf-shield/blocklist v1.1.0
git.kor-elf.net/kor-elf-shield/geoip2 v0.1.2
git.kor-elf.net/kor-elf-shield/go-nftables-client v0.1.1
github.com/nicksnyder/go-i18n/v2 v2.6.1
github.com/nxadm/tail v1.4.11
@@ -19,6 +20,8 @@ require (
require (
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/oschwald/geoip2-golang/v2 v2.1.0 // indirect
github.com/oschwald/maxminddb-golang/v2 v2.1.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/sagikazarmark/locafero v0.12.0 // indirect
github.com/spf13/afero v1.15.0 // indirect
+6
View File
@@ -1,5 +1,7 @@
git.kor-elf.net/kor-elf-shield/blocklist v1.1.0 h1:NS8be3TFBsUn+ft3oG5sAD56iJTGOkFH6GgjepEnS0s=
git.kor-elf.net/kor-elf-shield/blocklist v1.1.0/go.mod h1:nNbQux5vbuoCa3wMiC2QsLb4tO1JLCssGzdljizcJUs=
git.kor-elf.net/kor-elf-shield/geoip2 v0.1.2 h1:/J9U+h9H92hW6TtwCznkRANqhX5kvBpN4uV7xDbwXpM=
git.kor-elf.net/kor-elf-shield/geoip2 v0.1.2/go.mod h1:ULMUjpd2I9ikkDDE69IlpKT4vR2/nlYT0cqoR2T95sM=
git.kor-elf.net/kor-elf-shield/go-nftables-client v0.1.1 h1:3oGtZ/r1YAdlvI16OkZSCaxcWztHe/33ITWfI2LaQm0=
git.kor-elf.net/kor-elf-shield/go-nftables-client v0.1.1/go.mod h1:a7F+XdL1pK5P3ucQRR2EK/fABAP37LLBENiA4hX7L6A=
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
@@ -23,6 +25,10 @@ github.com/nicksnyder/go-i18n/v2 v2.6.1 h1:JDEJraFsQE17Dut9HFDHzCoAWGEQJom5s0TRd
github.com/nicksnyder/go-i18n/v2 v2.6.1/go.mod h1:Vee0/9RD3Quc/NmwEjzzD7VTZ+Ir7QbXocrkhOzmUKA=
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
github.com/oschwald/geoip2-golang/v2 v2.1.0 h1:DjnLhNJu9WHwTrmoiQFvgmyJoczhdnm7LB23UBI2Amo=
github.com/oschwald/geoip2-golang/v2 v2.1.0/go.mod h1:qdVmcPgrTJ4q2eP9tHq/yldMTdp2VMr33uVdFbHBiBc=
github.com/oschwald/maxminddb-golang/v2 v2.1.1 h1:lA8FH0oOrM4u7mLvowq8IT6a3Q/qEnqRzLQn9eH5ojc=
github.com/oschwald/maxminddb-golang/v2 v2.1.1/go.mod h1:PLdx6PR+siSIoXqqy7C7r3SB3KZnhxWr1Dp6g0Hacl8=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+12
View File
@@ -0,0 +1,12 @@
package geoip
import (
"time"
"git.kor-elf.net/kor-elf-shield/geoip2"
)
type Config struct {
GeoIP geoip2.RefreshableGeoIP2
Interval time.Duration
}
+24
View File
@@ -0,0 +1,24 @@
package geoip
import (
"context"
)
type falseGeoIP struct {
}
func NewFalseGeoIP() GeoIP {
return &falseGeoIP{}
}
func (g *falseGeoIP) Info(ip string) (string, error) {
return ip, nil
}
func (g *falseGeoIP) Run(_ context.Context) {
}
func (g *falseGeoIP) Close() error {
return nil
}
+80
View File
@@ -0,0 +1,80 @@
package geoip
import (
"context"
"errors"
"fmt"
"net/netip"
"time"
"git.kor-elf.net/kor-elf-shield/geoip2"
"git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/log"
)
type Info func(ip string) (string, error)
type GeoIP interface {
Info(ip string) (string, error)
Run(ctx context.Context)
Close() error
}
type geoIP struct {
config *Config
logger log.Logger
}
func New(config *Config, logger log.Logger) GeoIP {
return &geoIP{
config: config,
logger: logger,
}
}
func (g *geoIP) Info(ip string) (string, error) {
if g.config.GeoIP == nil {
return ip, fmt.Errorf("geoip is not initialized")
}
addr, err := netip.ParseAddr(ip)
if err != nil {
return ip, err
}
info, err := g.config.GeoIP.Info(addr)
if err != nil {
if errors.Is(err, geoip2.ErrNotFound) {
g.logger.Warn(fmt.Sprintf("failed to get geoip info for ip %s: %v", ip, err))
return ip, nil
}
return ip, err
}
g.logger.Debug(fmt.Sprintf("geoip info for ip %s: %s", ip, info.ToString()))
return info.ToString(), nil
}
func (g *geoIP) Run(ctx context.Context) {
g.logger.Debug("geoip service started")
go func() {
ticker := time.NewTicker(g.config.Interval)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
g.logger.Debug("refreshing geoip data")
if err := g.config.GeoIP.Refresh(ctx); err != nil {
g.logger.Error(fmt.Sprintf("failed to refresh geoip data: %v", err))
}
g.logger.Debug("geoip data refreshed")
}
}
}()
}
func (g *geoIP) Close() error {
g.logger.Debug("geoip service stopped")
return g.config.GeoIP.Close()
}
+18
View File
@@ -0,0 +1,18 @@
package geoip
import (
"git.kor-elf.net/kor-elf-shield/geoip2"
"git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/log"
)
type logger struct {
logger log.Logger
}
func NewLogger(log log.Logger) geoip2.Logger {
return &logger{logger: log}
}
func (l *logger) Error(err error) {
l.logger.Error(err.Error())
}