Files
waf-platform/EdgeCommon/pkg/serverconfigs/http_cc_config_plus.go

177 lines
5.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
//go:build plus
package serverconfigs
import (
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
)
type HTTPCCLevel = string
// DefaultHTTPCCConfig 默认的CC配置
func DefaultHTTPCCConfig() *HTTPCCConfig {
return &HTTPCCConfig{
EnableFingerprint: true,
EnableGET302: true,
UseDefaultThresholds: true,
IgnoreCommonFiles: true,
}
}
const (
HTTPCCLevelLow HTTPCCLevel = "low"
HTTPCCLevelMiddle HTTPCCLevel = "middle"
HTTPCCLevelHigh HTTPCCLevel = "high"
)
type HTTPCCThreshold struct {
PeriodSeconds int32 `yaml:"periodSeconds" json:"periodSeconds"` // 计算周期
MaxRequests int32 `yaml:"maxRequests" json:"maxRequests"` // 请求数最大值
//MaxConnections int32 `yaml:"maxConnections" json:"maxConnections"` // 连接数最大值 TODO
BlockSeconds int32 `yaml:"blockSeconds" json:"blockSeconds"` // 拦截时间
}
func NewHTTPCCThreshold() *HTTPCCThreshold {
return &HTTPCCThreshold{}
}
func (this *HTTPCCThreshold) Merge(threshold *HTTPCCThreshold) {
if threshold.PeriodSeconds > 0 {
this.PeriodSeconds = threshold.PeriodSeconds
}
if threshold.MaxRequests > 0 {
this.MaxRequests = threshold.MaxRequests
}
if threshold.BlockSeconds > 0 {
this.BlockSeconds = threshold.BlockSeconds
}
}
func (this *HTTPCCThreshold) MergeIfEmpty(threshold *HTTPCCThreshold) {
if threshold.PeriodSeconds > 0 && this.PeriodSeconds <= 0 {
this.PeriodSeconds = threshold.PeriodSeconds
}
if threshold.MaxRequests > 0 && this.MaxRequests <= 0 {
this.MaxRequests = threshold.MaxRequests
}
if threshold.BlockSeconds > 0 && this.BlockSeconds <= 0 {
this.BlockSeconds = threshold.BlockSeconds
}
}
func (this *HTTPCCThreshold) Clone() *HTTPCCThreshold {
return &HTTPCCThreshold{
PeriodSeconds: this.PeriodSeconds,
MaxRequests: this.MaxRequests,
BlockSeconds: this.BlockSeconds,
}
}
const (
DefaultHTTPCCThresholdPeriodSeconds0 = 5
DefaultHTTPCCThresholdPeriodSeconds1 = 60
DefaultHTTPCCThresholdPeriodSeconds2 = 300
DefaultHTTPCCThresholdBlockSeconds0 = 600
DefaultHTTPCCThresholdBlockSeconds1 = 2400
DefaultHTTPCCThresholdBlockSeconds2 = 3600
)
var DefaultHTTPCCThresholds = []*HTTPCCThreshold{
{
PeriodSeconds: DefaultHTTPCCThresholdPeriodSeconds0,
MaxRequests: 60,
BlockSeconds: DefaultHTTPCCThresholdBlockSeconds0,
},
{
PeriodSeconds: DefaultHTTPCCThresholdPeriodSeconds1,
MaxRequests: 150,
BlockSeconds: DefaultHTTPCCThresholdBlockSeconds1,
},
{
PeriodSeconds: DefaultHTTPCCThresholdPeriodSeconds2,
MaxRequests: 300,
BlockSeconds: DefaultHTTPCCThresholdBlockSeconds2,
},
}
func CloneDefaultHTTPCCThresholds() []*HTTPCCThreshold {
var result = []*HTTPCCThreshold{}
for _, threshold := range DefaultHTTPCCThresholds {
result = append(result, threshold.Clone())
}
return result
}
// HTTPCCConfig HTTP CC防护配置
type HTTPCCConfig struct {
IsPrior bool `yaml:"isPrior" json:"isPrior"` // 是否覆盖父级
IsOn bool `yaml:"isOn" json:"isOn"` // 是否启用
Level HTTPCCLevel `yaml:"level" json:"level"` // 级别 TODO
WithRequestPath bool `yaml:"withRequestPath" json:"withRequestPath"` // 根据URL路径区分请求 TODO
UseDefaultThresholds bool `yaml:"useDefaultThresholds" json:"useDefaultThresholds"` // 是否使用默认的阈值设置
Thresholds []*HTTPCCThreshold `yaml:"thresholds" json:"thresholds"` // 阈值设置
IgnoreCommonFiles bool `yaml:"ignoreCommonFiles" json:"ignoreCommonFiles"` // 忽略常用文件如CSS、JS等
IgnoreCommonAgents bool `yaml:"ignoreCommonAgents" json:"ignoreCommonAgents"` // 忽略常见搜索引擎等 TODO
Action string `yaml:"action" json:"action"` // 动作比如block、captcha等 TODO
OnlyURLPatterns []*shared.URLPattern `yaml:"onlyURLPatterns" json:"onlyURLPatterns"` // 仅限的URL
ExceptURLPatterns []*shared.URLPattern `yaml:"exceptURLPatterns" json:"exceptURLPatterns"` // 排除的URL
EnableFingerprint bool `yaml:"enableFingerprint" json:"enableFingerprint"` // 是否检查请求来源指纹
EnableGET302 bool `yaml:"enableGET302" json:"enableGET302"` // 是否支持GET302校验
MinQPSPerIP int `yaml:"minQPSPerIP" json:"minQPSPerIP"` // 启用要求的单IP最低平均QPS
}
func NewHTTPCCConfig() *HTTPCCConfig {
return &HTTPCCConfig{
WithRequestPath: false,
IgnoreCommonFiles: true,
IgnoreCommonAgents: true,
Action: "captcha",
EnableFingerprint: true,
EnableGET302: true,
}
}
func (this *HTTPCCConfig) Init() error {
// only urls
for _, pattern := range this.OnlyURLPatterns {
err := pattern.Init()
if err != nil {
return err
}
}
// except urls
for _, pattern := range this.ExceptURLPatterns {
err := pattern.Init()
if err != nil {
return err
}
}
return nil
}
func (this *HTTPCCConfig) MatchURL(url string) bool {
// except
if len(this.ExceptURLPatterns) > 0 {
for _, pattern := range this.ExceptURLPatterns {
if pattern.Match(url) {
return false
}
}
}
if len(this.OnlyURLPatterns) > 0 {
for _, pattern := range this.OnlyURLPatterns {
if pattern.Match(url) {
return true
}
}
return false
}
return true
}