Add GeoIP support with configurable service and logger integration
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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())
|
||||
}
|
||||
Reference in New Issue
Block a user