Skip to content

Commit

Permalink
feat: whitelist and blacklist middleware supports caching
Browse files Browse the repository at this point in the history
  • Loading branch information
fufuok committed Mar 22, 2024
1 parent ccfcc5a commit 85b6c7d
Show file tree
Hide file tree
Showing 12 changed files with 232 additions and 18 deletions.
1 change: 0 additions & 1 deletion common/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ func LookupIPNetsString(s string, ipNets map[*net.IPNet]int64) (int64, bool) {
if ip == nil {
return 0, false
}

return LookupIPNets(ip, ipNets)
}

Expand Down
6 changes: 6 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ type WebConf struct {
// Fiber 请求体大小限制, 0 为默认: 8 * 1024 * 1024, -1 表示不限制
BodyLimit int `json:"body_limit"`

// 黑白名单中间件缓存容量配置, 键生命周期秒数
WhitelistLRUCapacity uint64 `json:"whitelist_lru_capacity"`
WhitelistLRULifetime uint64 `json:"whitelist_lru_lifetime"`
BlacklistLRUCapacity uint64 `json:"blacklist_lru_capacity"`
BlacklistLRULifetime uint64 `json:"blacklist_lru_lifetime"`

CertFile string `json:"-"`
KeyFile string `json:"-"`
}
Expand Down
11 changes: 6 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ require (
github.com/fufuok/bytespool v1.3.2
github.com/fufuok/chanx v1.2.1
github.com/fufuok/cron v0.3.2
github.com/fufuok/utils v1.0.8
github.com/fufuok/freelru v0.13.1
github.com/fufuok/utils v1.0.9
github.com/gin-gonic/gin v1.9.1
github.com/go-cmd/cmd v1.4.2
github.com/goccy/go-json v0.10.2
Expand Down Expand Up @@ -36,7 +37,7 @@ require (
github.com/go-playground/validator/v10 v10.19.0 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 // indirect
github.com/google/pprof v0.0.0-20240320155624-b11c3daa6f07 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
Expand All @@ -50,8 +51,8 @@ require (
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/onsi/ginkgo/v2 v2.16.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
github.com/onsi/ginkgo/v2 v2.17.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/quic-go v0.42.0 // indirect
github.com/refraction-networking/utls v1.6.3 // indirect
Expand All @@ -64,7 +65,7 @@ require (
go.uber.org/mock v0.4.0 // indirect
golang.org/x/arch v0.7.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f // indirect
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 // indirect
golang.org/x/mod v0.16.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/sys v0.18.0 // indirect
Expand Down
26 changes: 15 additions & 11 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ github.com/fufuok/chanx v1.2.1 h1:YvMgLg/ZEaWYwmQvTKOwR+dkvmfAdH+MnYlvjRawz7E=
github.com/fufuok/chanx v1.2.1/go.mod h1:d9WAtwHbIqRIEuZqfaD6v9O+x/9Y+rGNgUuBnSwbyJU=
github.com/fufuok/cron v0.3.2 h1:kFElN4SnLEnE8vWZhLlNv9WgHLdWVfepSYeoyK9V9Pg=
github.com/fufuok/cron v0.3.2/go.mod h1:fbTEmIk30P2o35BqPgCNSm8MvnC1XjNojtPlgJk4/lY=
github.com/fufuok/utils v1.0.8 h1:Pij4l5/2RGzb3Ul5GwCM7/bOwo9bajK4XVZiAZIbzJo=
github.com/fufuok/utils v1.0.8/go.mod h1:Kdin3/AGzR0+mCaSKeatud64L48oAmVMIhqP4wXHh2E=
github.com/fufuok/freelru v0.13.1 h1:kW1tfgg82Jj4MpUxZ6v3PfKEiu+o6JYAF2aeLRRYlvA=
github.com/fufuok/freelru v0.13.1/go.mod h1:6B/BCmtS+iIJmAFmCDfSUaLsuQtPio0BpBkPuAOgQ0k=
github.com/fufuok/utils v1.0.9 h1:ybn0Tb2mbtsnlRTjhdvH1hHD2ha0LA1I2mG67sTjoZw=
github.com/fufuok/utils v1.0.9/go.mod h1:Kdin3/AGzR0+mCaSKeatud64L48oAmVMIhqP4wXHh2E=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
Expand Down Expand Up @@ -99,8 +101,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7 h1:y3N7Bm7Y9/CtpiVkw/ZWj6lSlDF3F74SfKwfTCer72Q=
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
github.com/google/pprof v0.0.0-20240320155624-b11c3daa6f07 h1:57oOH2Mu5Nw16KnZAVLdlUjmPH/TSYCKTJgG0OVfX0Y=
github.com/google/pprof v0.0.0-20240320155624-b11c3daa6f07/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
Expand Down Expand Up @@ -159,16 +161,16 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.16.0 h1:7q1w9frJDzninhXxjZd+Y/x54XNjG/UlRLIYPZafsPM=
github.com/onsi/ginkgo/v2 v2.16.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
github.com/onsi/ginkgo/v2 v2.17.0 h1:kdnunFXpBjbzN56hcJHrXZ8M+LOkenKA7NnBzTNigTI=
github.com/onsi/ginkgo/v2 v2.17.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo=
github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand All @@ -189,6 +191,7 @@ github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWR
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
Expand All @@ -198,8 +201,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
Expand All @@ -226,8 +230,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f h1:3CW0unweImhOzd5FmYuRsD4Y4oQFKZIjAnKbjV4WIrw=
golang.org/x/exp v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81 h1:6R2FC06FonbXQ8pK11/PDFY6N6LWlf9KlzibaCapmqc=
golang.org/x/exp v0.0.0-20240318143956-a85f2c67cd81/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
Expand Down
8 changes: 8 additions & 0 deletions web/fiber/engine/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ func Run(setup App) {

app = setup(app)

// 黑白名单中间件缓存初始化, 主配置无定义时可由应用方重新初始化
if err := middleware.UseWhitelistCache(cfg.WhitelistLRUCapacity, cfg.WhitelistLRULifetime); err != nil {
log.Fatalln("Failed to initialize whitelist config:", err, "\nbye.")
}
if err := middleware.UseBlacklistCache(cfg.BlacklistLRUCapacity, cfg.BlacklistLRULifetime); err != nil {
log.Fatalln("Failed to initialize blacklist config:", err, "\nbye.")
}

app.Use(
middleware.RecoverLogger(),
compress.New(),
Expand Down
41 changes: 41 additions & 0 deletions web/fiber/middleware/blacklist.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,47 @@ package middleware

import (
"fmt"
"sync/atomic"
"time"

"github.com/fufuok/freelru"
"github.com/gofiber/fiber/v2"

"github.com/fufuok/pkg/common"
"github.com/fufuok/pkg/config"
"github.com/fufuok/pkg/web/fiber/proxy"
)

var (
// 存放最近检查的黑名单 IP
blacklistLRU freelru.Cache[string, bool]
useBlacklistLRU atomic.Bool
)

// UseBlacklistCache 重新设置黑名单检查时缓存, 配置变化时可选再次调用, 由应用端 Start() Runtime() 调用
func UseBlacklistCache(capacity, lifetime uint64) (err error) {
if capacity == 0 {
return nil
}

lru, err := freelru.NewShardedDefault[string, bool](capacity, time.Duration(lifetime)*time.Second)
if err != nil {
return err
}

useBlacklistLRU.Store(false)
blacklistLRU = lru
useBlacklistLRU.Store(blacklistLRU != nil)
return nil
}

// PurgeBlacklistCache 配置项变化时需要清空缓存, 由应用端在 Runtime() 调用
func PurgeBlacklistCache() {
if blacklistLRU != nil {
blacklistLRU.Purge()
}
}

// CheckBlacklist 接口黑名单检查
func CheckBlacklist(asAPI bool) fiber.Handler {
errMsg := fmt.Sprintf("[ERROR] 非法访问(%s): ", config.AppName)
Expand All @@ -25,7 +58,15 @@ func CheckBlacklist(asAPI bool) fiber.Handler {
func BlacklistChecker(c *fiber.Ctx) bool {
clientIP := proxy.GetClientIP(c)
if len(config.Blacklist) > 0 {
if useBlacklistLRU.Load() {
if ok, loaded := blacklistLRU.Get(clientIP); loaded {
return ok
}
}
_, ok := common.LookupIPNetsString(clientIP, config.Blacklist)
if useBlacklistLRU.Load() {
blacklistLRU.Add(clientIP, ok)
}
return ok
}
return false
Expand Down
12 changes: 12 additions & 0 deletions web/fiber/middleware/stats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package middleware

func CacheStats() map[string]any {
m := make(map[string]any)
if whitelistLRU != nil {
m["Whitelist"] = whitelistLRU.Metrics()
}
if blacklistLRU != nil {
m["Blacklist"] = blacklistLRU.Metrics()
}
return m
}
41 changes: 41 additions & 0 deletions web/fiber/middleware/whitelist.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package middleware
import (
"fmt"
"net/http"
"sync/atomic"
"time"

"github.com/fufuok/freelru"
"github.com/gofiber/fiber/v2"

"github.com/fufuok/pkg/common"
Expand All @@ -15,6 +18,36 @@ import (

type ForbiddenChecker = func(*fiber.Ctx) bool

var (
// 存放最近检查的白名单 IP
whitelistLRU freelru.Cache[string, bool]
useWhitelistLRU atomic.Bool
)

// UseWhitelistCache 重新设置白名单检查时缓存, 配置变化时可选再次调用, 由应用端 Start() Runtime() 调用
func UseWhitelistCache(capacity, lifetime uint64) error {
if capacity == 0 {
return nil
}

lru, err := freelru.NewShardedDefault[string, bool](capacity, time.Duration(lifetime)*time.Second)
if err != nil {
return err
}

useWhitelistLRU.Store(false)
whitelistLRU = lru
useWhitelistLRU.Store(whitelistLRU != nil)
return nil
}

// PurgeWhitelistCache 配置项变化时需要清空缓存, 由应用端在 Runtime() 调用
func PurgeWhitelistCache() {
if whitelistLRU != nil {
whitelistLRU.Purge()
}
}

// CheckWhitelist 接口白名单检查
func CheckWhitelist(asAPI bool) fiber.Handler {
errMsg := fmt.Sprintf("[ERROR] 非法来访(%s): ", config.AppName)
Expand Down Expand Up @@ -52,7 +85,15 @@ func CheckWhitelistAnd(checker ForbiddenChecker, asAPI bool) fiber.Handler {
func WhitelistChecker(c *fiber.Ctx) bool {
clientIP := proxy.GetClientIP(c)
if len(config.Whitelist) > 0 {
if useWhitelistLRU.Load() {
if ok, loaded := whitelistLRU.Get(clientIP); loaded {
return ok
}
}
_, ok := common.LookupIPNetsString(clientIP, config.Whitelist)
if useWhitelistLRU.Load() {
whitelistLRU.Add(clientIP, ok)
}
return ok
}
return true
Expand Down
10 changes: 9 additions & 1 deletion web/gin/engine/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,24 @@ func Run(setup App) {
app = gin.New()
}

cfg := config.Config().WebConf
app = setup(app)

if err := SetTrustedProxies(); err != nil {
log.Fatalln("Failed to SetTrustedProxies:", err, "\nbye.")
}

// 黑白名单中间件缓存初始化, 主配置无定义时可由应用方重新初始化
if err := middleware.UseWhitelistCache(cfg.WhitelistLRUCapacity, cfg.WhitelistLRULifetime); err != nil {
log.Fatalln("Failed to initialize whitelist config:", err, "\nbye.")
}
if err := middleware.UseBlacklistCache(cfg.BlacklistLRUCapacity, cfg.BlacklistLRULifetime); err != nil {
log.Fatalln("Failed to initialize blacklist config:", err, "\nbye.")
}

app.Use(middleware.RecoveryWithLog(true))

eg := errgroup.Group{}
cfg := config.Config().WebConf
if cfg.ServerHttpsAddr != "" {
for _, addr := range strings.Split(cfg.ServerHttpsAddr, ",") {
addr := addr
Expand Down
41 changes: 41 additions & 0 deletions web/gin/middleware/blacklist.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,46 @@ package middleware

import (
"fmt"
"sync/atomic"
"time"

"github.com/fufuok/freelru"
"github.com/gin-gonic/gin"

"github.com/fufuok/pkg/common"
"github.com/fufuok/pkg/config"
)

var (
// 存放最近检查的黑名单 IP
blacklistLRU freelru.Cache[string, bool]
useBlacklistLRU atomic.Bool
)

// UseBlacklistCache 重新设置黑名单检查时缓存, 配置变化时可选再次调用, 由应用端 Start() Runtime() 调用
func UseBlacklistCache(capacity, lifetime uint64) (err error) {
if capacity == 0 {
return nil
}

lru, err := freelru.NewShardedDefault[string, bool](capacity, time.Duration(lifetime)*time.Second)
if err != nil {
return err
}

useBlacklistLRU.Store(false)
blacklistLRU = lru
useBlacklistLRU.Store(blacklistLRU != nil)
return nil
}

// PurgeBlacklistCache 配置项变化时需要清空缓存, 由应用端在 Runtime() 调用
func PurgeBlacklistCache() {
if blacklistLRU != nil {
blacklistLRU.Purge()
}
}

// CheckBlacklist 接口黑名单检查
func CheckBlacklist(asAPI bool) gin.HandlerFunc {
errMsg := fmt.Sprintf("[ERROR] 非法访问(%s): ", config.AppName)
Expand All @@ -25,7 +58,15 @@ func CheckBlacklist(asAPI bool) gin.HandlerFunc {
func BlacklistChecker(c *gin.Context) bool {
clientIP := c.ClientIP()
if len(config.Blacklist) > 0 {
if useBlacklistLRU.Load() {
if ok, loaded := blacklistLRU.Get(clientIP); loaded {
return ok
}
}
_, ok := common.LookupIPNetsString(clientIP, config.Blacklist)
if useBlacklistLRU.Load() {
blacklistLRU.Add(clientIP, ok)
}
return ok
}
return false
Expand Down
12 changes: 12 additions & 0 deletions web/gin/middleware/stats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package middleware

func CacheStats() map[string]any {
m := make(map[string]any)
if whitelistLRU != nil {
m["Whitelist"] = whitelistLRU.Metrics()
}
if blacklistLRU != nil {
m["Blacklist"] = blacklistLRU.Metrics()
}
return m
}
Loading

0 comments on commit 85b6c7d

Please sign in to comment.