diff --git a/main.go b/main.go index cee270c..eb3e1d1 100644 --- a/main.go +++ b/main.go @@ -5,23 +5,24 @@ import ( "SamWaf/model" "SamWaf/utils/zlog" "go.uber.org/zap" + "log" "net/http" + "runtime" "strconv" "time" ) func main() { zlog.Info("初始化系统") - /*runtime.GOMAXPROCS(1) // 限制 CPU 使用数,避免过载 + runtime.GOMAXPROCS(1) // 限制 CPU 使用数,避免过载 runtime.SetMutexProfileFraction(1) // 开启对锁调用的跟踪 - runtime.SetBlockProfileRate(1) // 开启对阻塞操作的跟踪 + runtime.SetBlockProfileRate(1) // 开启对阻塞操作的跟踪 go func() { - err2:=http.ListenAndServe("0.0.0.0:16060", nil) + err2 := http.ListenAndServe("0.0.0.0:16060", nil) time.Sleep(10000) log.Fatal(err2) }() - */ //初始化本地数据库 InitDb() diff --git a/plugin/ipcounter.go b/plugin/ipcounter.go new file mode 100644 index 0000000..df9f555 --- /dev/null +++ b/plugin/ipcounter.go @@ -0,0 +1,64 @@ +package plugin + +import ( + "sync" + "time" +) + +type IpRecord struct { + IpCnt int64 + Ip string + IpLockTime int64 +} +type IpCounter struct { + mu sync.Mutex + v map[string]*IpRecord +} + +func (c *IpCounter) InitCounter() { + c.v = map[string]*IpRecord{} +} + +// Inc increments the counter for the given key. +func (c *IpCounter) Inc(key string) { + c.mu.Lock() + defer c.mu.Unlock() + // Lock so only one goroutine at a time can access the map c.v. + ipc := c.v[key] + if ipc != nil { + c.v[key].IpCnt += 1 + } else { + c.v[key] = &IpRecord{ + IpCnt: 0, + Ip: key, + IpLockTime: 0, + } + } +} + +func (c *IpCounter) Lock(key string) { + c.mu.Lock() + defer c.mu.Unlock() + // Lock so only one goroutine at a time can access the map c.v. + ipc := c.v[key] + if ipc != nil { + c.v[key].IpLockTime = time.Now().Unix() + } +} + +func (c *IpCounter) UnLock(key string) { + c.mu.Lock() + defer c.mu.Unlock() + // Lock so only one goroutine at a time can access the map c.v. + ipc := c.v[key] + if ipc != nil { + c.v[key].IpLockTime = 0 + c.v[key].IpCnt = 0 + } +} +func (c *IpCounter) Value(key string) *IpRecord { + c.mu.Lock() + // Lock so only one goroutine at a time can access the map c.v. + defer c.mu.Unlock() + return c.v[key] +} diff --git a/readme.txt b/readme.txt index 1512054..7885a84 100644 --- a/readme.txt +++ b/readme.txt @@ -1,2 +1,3 @@ GOPROXY=https://mirrors.aliyun.com/goproxy/,direct;GO111MODULE=auto -GOPROXY=https://goproxy.cn,direct;GO111MODULE=auto \ No newline at end of file +GOPROXY=https://goproxy.cn,direct;GO111MODULE=auto + diff --git a/wafengine.go b/wafengine.go index 83ee93d..e09d565 100644 --- a/wafengine.go +++ b/wafengine.go @@ -4,6 +4,7 @@ import ( "SamWaf/global" "SamWaf/innerbean" "SamWaf/model" + "SamWaf/plugin" "SamWaf/utils" "SamWaf/utils/zlog" "bytes" @@ -50,10 +51,12 @@ var ( esHelper utils.EsHelper phttphandler *baseHandle - hostRuleChan = make(chan []model.Rules, 10) //规则链 - engineChan = make(chan int, 10) //引擎链 - hostChan = make(chan model.Hosts, 10) //主机链 - engineCurrentStatus int = 0 // 当前waf引擎状态 + hostRuleChan = make(chan []model.Rules, 10) //规则链 + engineChan = make(chan int, 10) //引擎链 + hostChan = make(chan model.Hosts, 10) //主机链 + engineCurrentStatus int = 0 // 当前waf引擎状态 + pluginIpCounter plugin.IpCounter //ip计数器 + ) type baseHandle struct{} @@ -89,6 +92,9 @@ func GetCountry(ip string) string { } else { return false }*/ +} +func customResult(w http.ResponseWriter, r *http.Request, webLog innerbean.WebLog) { + } func CheckIP(ip string) bool { country := GetCountry(ip) @@ -146,6 +152,22 @@ func (h *baseHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) { USER_CODE: global.GWAF_USER_CODE, RULE: "", } + //ip计数器 TODO 应该是控制每分钟的访问次数,并且进行配置 + ipc := pluginIpCounter.Value(weblogbean.SRC_IP) + if ipc != nil { + if ipc.IpLockTime == 0 { + pluginIpCounter.Lock(weblogbean.SRC_IP) + } + if time.Now().Unix()-ipc.IpLockTime > 60 { //超过60s释放 + pluginIpCounter.UnLock(weblogbean.SRC_IP) + } + if ipc.IpCnt > 1000 { + w.Write([]byte("您的访问被阻止

您的访问被阻止超量了


访问识别码:

" + weblogbean.REQ_UUID + "

")) + + return + } + } + pluginIpCounter.Inc(weblogbean.SRC_IP) //esHelper.BatchInsert("full_log", weblogbean) /*rule := &innerbean.WAF_REQUEST_FULL{ @@ -249,6 +271,9 @@ func Start_WAF() { global.GWAF_LOCAL_DB.Where("user_code = ?", global.GWAF_USER_CODE).Find(&hosts) + //初始化插件-ip计数器 + pluginIpCounter.InitCounter() + //初始化步骤[加载ip数据库] var dbPath = "data/ip2region.xdb" // 1、从 dbPath 加载整个 xdb 到内存 diff --git a/性能测试结果.md b/性能测试结果.md index 06a4991..ab47356 100644 --- a/性能测试结果.md +++ b/性能测试结果.md @@ -1,3 +1,6 @@ + +性能测试结果 + https://blog.csdn.net/qq_44920726/article/details/123362068 PS C:\huawei\ApplicationEnverment\httpd\Apache24\bin> ./abs -n 10000 -c 1000 https://mybaidu1.com:8082/admin.php/user/publics/signin.html