Browse Source

feat(web): 添加 CC 防护配置功能

- 在 API 中新增 CcConfig 结构体用于 CC 配置
- 在 cdn 服务中添加 EditCcConfig 方法用于修改 CC 配置- 在 webForwarding 服务中集成 CC 配置功能
- 修改 AddWebForwarding 和 EditWebForwarding 方法,支持 CC 配置
fusu 4 weeks ago
parent
commit
27f442e6ca
4 changed files with 117 additions and 9 deletions
  1. 25 1
      api/v1/cdn.go
  2. 9 0
      api/v1/webForwarding.go
  3. 27 0
      internal/service/cdn.go
  4. 56 8
      internal/service/webforwarding.go

+ 25 - 1
api/v1/cdn.go

@@ -169,4 +169,28 @@ type WebLog struct {
 	Status5 bool `json:"status5" form:"status5"`
 	EnableClientClosed bool `json:"enableClientClosed" form:"enableClientClosed"`
 	FirewallOnly       bool `json:"firewallOnly" form:"firewallOnly"`
-}
+}
+
+type CcConfig struct {
+	IsOn       bool   `json:"isOn"`
+	Level      string `json:"level"`
+	Action     string `json:"action"`
+	IsPrior    bool   `json:"isPrior"`
+	Thresholds []struct {
+		MaxRequests   int `json:"maxRequests"`
+		BlockSeconds  int `json:"blockSeconds"`
+		PeriodSeconds int `json:"periodSeconds"`
+	} `json:"thresholds"`
+	MinQPSPerIP          int           `json:"minQPSPerIP"`
+	EnableGET302         bool          `json:"enableGET302"`
+	OnlyURLPatterns      []interface{} `json:"onlyURLPatterns"`
+	ThresholdMethod      string        `json:"thresholdMethod"`
+	WithRequestPath      bool          `json:"withRequestPath"`
+	EnableFingerprint    bool          `json:"enableFingerprint"`
+	ExceptURLPatterns    []interface{} `json:"exceptURLPatterns"`
+	IgnoreCommonFiles    bool          `json:"ignoreCommonFiles"`
+	IgnoreCommonAgents   bool          `json:"ignoreCommonAgents"`
+	UseDefaultThresholds bool          `json:"useDefaultThresholds"`
+}
+
+

+ 9 - 0
api/v1/webForwarding.go

@@ -13,6 +13,7 @@ type WebForwardingDataRequest struct {
 	HttpsKey           string `form:"httpsKey" json:"httpsKey"`
 	SslCertId          int64    `form:"sslCertId" json:"sslCertId"`
 	Proxy 				bool `form:"proxy" json:"proxy" default:"false"`
+	CcConfig           CcConfigRequest `form:"ccConfig" json:"ccConfig"`
 }
 
 type DeleteWebForwardingRequest struct {
@@ -34,4 +35,12 @@ type BackendList struct {
 	IsHttps  int    `json:"isHttps,omitempty" form:"isHttps" default:"0"`
 }
 
+type CcConfigRequest struct {
+	IsOn  bool `form:"isOn" json:"isOn" default:"false"`
+	ThresholdMethod string `form:"thresholdMethod" json:"thresholdMethod" default:"default"` //阈值设置
+	Limit5s int `form:"limit5s" json:"limit5s"`
+	Limit60s int `form:"limit60s" json:"limit60s"`
+	Limit300s int `form:"limit300s" json:"limit300s"`
+	Level string `form:"level" json:"level" default:"low"` //拦截强度
+}
 

+ 27 - 0
internal/service/cdn.go

@@ -44,6 +44,8 @@ type CdnService interface {
 	EditProxy(ctx context.Context, req v1.Proxy) error
 	// 修改日志
 	EditWebLog(ctx context.Context,webId int64, req v1.WebLog) error
+	// 修改CC配置
+	EditCcConfig(ctx context.Context,webId int64, req v1.CcConfig) error
 }
 
 func NewCdnService(
@@ -822,4 +824,29 @@ func (s *cdnService) EditWebLog(ctx context.Context,webId int64, req v1.WebLog)
 		return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
 	}
 	return nil
+}
+
+// 修改网站CC配置
+func (s *cdnService) EditCcConfig(ctx context.Context,webId int64, req v1.CcConfig) error {
+	reqJson, err := json.Marshal(req)
+	if err != nil {
+		return err
+	}
+	formData := map[string]interface{}{
+		"httpWebId":            webId,
+		"ccJSON": 				reqJson,
+	}
+	apiUrl := s.Url + "HTTPWebService/updateHTTPWebCC"
+	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
+	if err != nil {
+		return err
+	}
+	var res v1.GeneralResponse[any]
+	if err := json.Unmarshal(resBody, &res); err != nil {
+		return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
+	}
+	if res.Code != 200 {
+		return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
+	}
+	return nil
 }

+ 56 - 8
internal/service/webforwarding.go

@@ -418,18 +418,21 @@ func (s *webForwardingService) AddWebForwarding(ctx context.Context, req *v1.Web
 	}
 
 	// 开启访问日志
-	if webId != 0 {
-		webConfigId, err := s.webForwardingRepository.GetWebConfigId(ctx, webId)
-		if err != nil {
-			return err
-		}
-		err = s.EditLog(ctx, webConfigId)
+	err = s.EditLog(ctx, webId)
+	if err != nil {
+		return err
+	}
+
+	// 开启CC
+	if req.WebForwardingData.CcConfig.IsOn {
+		err = s.EditCcConfig(ctx, webId, req.WebForwardingData.CcConfig)
 		if err != nil {
 			return err
 		}
-
 	}
 
+
+
 	webModel := s.buildWebForwardingModel(&req.WebForwardingData, int(webId), require)
 
 	id, err := s.webForwardingRepository.AddWebForwarding(ctx, webModel)
@@ -567,6 +570,18 @@ func (s *webForwardingService) EditWebForwarding(ctx context.Context, req *v1.We
 		}
 	}
 
+	err = s.EditCcConfig(ctx, int64(oldData.CdnWebId), v1.CcConfigRequest{
+		IsOn:            req.WebForwardingData.CcConfig.IsOn,
+		Level:           req.WebForwardingData.CcConfig.Level,
+		Limit5s:         req.WebForwardingData.CcConfig.Limit5s,
+		Limit60s:        req.WebForwardingData.CcConfig.Limit60s,
+		Limit300s:       req.WebForwardingData.CcConfig.Limit300s,
+		ThresholdMethod: req.WebForwardingData.CcConfig.ThresholdMethod,
+	})
+	if err != nil {
+		return err
+	}
+
 	// 将域名添加到白名单
 	webData, err := s.webForwardingRepository.GetWebForwarding(ctx, int64(req.WebForwardingData.Id))
 	if err != nil {
@@ -939,7 +954,11 @@ func (s *webForwardingService) WashDifferentIp(newIpList []string, oldIpList []s
 	return addedDenyIps, removedDenyIps
 }
 
-func (s *webForwardingService) EditLog(ctx context.Context,webConfigId int64) error {
+func (s *webForwardingService) EditLog(ctx context.Context,webId int64) error {
+	webConfigId, err := s.webForwardingRepository.GetWebConfigId(ctx, webId)
+	if err != nil {
+		return err
+	}
 
 	if err := s.cdn.EditWebLog(ctx, webConfigId,v1.WebLog{
 		IsPrior: false,
@@ -956,4 +975,33 @@ func (s *webForwardingService) EditLog(ctx context.Context,webConfigId int64) er
 		return err
 	}
 	return nil
+}
+
+func (s *webForwardingService) EditCcConfig(ctx context.Context,webId int64, req v1.CcConfigRequest) error {
+	webConfigId, err := s.webForwardingRepository.GetWebConfigId(ctx, webId)
+	if err != nil {
+		return err
+	}
+
+
+	configThreshold := []struct{
+		MaxRequests   int `json:"maxRequests"`
+		BlockSeconds  int `json:"blockSeconds"`
+		PeriodSeconds int `json:"periodSeconds"`
+	}{
+		{MaxRequests:  req.Limit5s},
+		{MaxRequests:  req.Limit60s},
+		{MaxRequests:  req.Limit300s},
+	}
+
+	if err := s.cdn.EditCcConfig(ctx, webConfigId, v1.CcConfig{
+		IsOn: req.IsOn,
+		ThresholdMethod: req.ThresholdMethod,
+		Thresholds: configThreshold,
+		Level: req.Level,
+		UseDefaultThresholds : true,
+	}); err != nil {
+		return err
+	}
+	return nil
 }