Ver código fonte

feat(flexCdn): 添加 CC 防护相关功能

- 新增 CC 配置编辑功能
- 新增创建空防火墙策略功能
- 新增修改防火墙设置功能
- 新增创建 IP 列表功能
- 新增添加 IP 项功能
- 新增 CC IP 列表相关功能
fusu 2 semanas atrás
pai
commit
950f3da4b2

+ 47 - 0
api/v1/cdn.go

@@ -230,3 +230,50 @@ type HandshakeTimeoutJSON struct {
 	Count int    `json:"count" form:"count"`
 }
 
+type AddWafPolicy struct {
+	IsOn bool `json:"isOn" form:"isOn"`
+	Name string `json:"name" form:"name"`
+	Description string `json:"description" form:"description"`
+	ServerId int64 `json:"serverId" form:"serverId"`
+	ServerGroupId int64 `json:"serverGroupId" form:"serverGroupId"`
+}
+
+type Firewall struct {
+	IsPrior bool `json:"isPrior" form:"isPrior"` // 是否覆盖上级配置
+	IsOn bool `json:"isOn" form:"isOn"` // 是否启用配置
+	FirewallPolicyId int64 `json:"firewallPolicyId" form:"firewallPolicyId"` // WAF策略ID
+	IgnoreGlobalRules  bool `json:"ignoreGlobalRules" form:"ignoreGlobalRules"` // 是否忽略系统定义的全局规则
+	DefaultCaptchaType string `json:"defaultCaptchaType" form:"defaultCaptchaType"` // 默认人机识别方式,可以选none(不设置)、default(默认)、oneClick(单击验证)、slide(滑动解锁)、geetest(极验)
+}
+
+type IPListRequest struct {
+	Type string `json:"type" form:"type"`
+	Name string `json:"name" form:"name"`
+	Code string `json:"code" form:"code"`
+	TimeoutJSON []byte `json:"timeoutJSON" form:"timeoutJSON"`
+	IsPublic bool `json:"isPublic" form:"isPublic"`
+	Description string `json:"description" form:"description"`
+	IsGlobal bool `json:"isGlobal" form:"isGlobal"`
+	ServerId int64 `json:"serverId" form:"serverId"`
+}
+
+type AddIpItem struct {
+	IpListId int64 `json:"ipListId" form:"ipListId"` // 所属IP列表ID
+	Value string `json:"value" form:"value"` // IP原始值,比如单个IP、IP范围或者CIDR,指定了原始值后,无需设置ipFrom和ipTo两个参数
+	IpFrom string `json:"ipFrom" form:"ipFrom"` 	// 开始IP
+	IpTo string `json:"ipTo" form:"ipTo"` // 结束IP(可选)
+	ExpiredAt int64 `json:"expiredAt" form:"expiredAt"` // 过期时间戳(可选)
+	Reason string `json:"reason" form:"reason"` // 加入理由(可选)
+	Type string `json:"type" form:"type"` // IP类型,值为ipv4或ipv6
+	EventLevel string `json:"eventLevel" form:"eventLevel"` // 级别:debug, notice, warning, error, critical, fatal
+	NodeId int64 `json:"nodeId" form:"nodeId"` // 可选项,所属节点ID(如果大于0,则不应用于其他节点)
+	ServerId int64 `json:"serverId" form:"serverId"` // 可选项,所属网站ID(如果大于0,则不应用于其他网站)
+	SourceNodeId int64 `json:"sourceNodeId" form:"sourceNodeId"` 	// 可选项,来源节点
+	SourceServerId int64 `json:"sourceServerId" form:"sourceServerId"` 	// 可选项,来源网站ID
+	SourceHTTPFirewallPolicyId int64 `json:"sourceHTTPFirewallPolicyId" form:"sourceHTTPFirewallPolicyId"` // 可选项,来源WAF策略ID
+	SourceHTTPFirewallRuleGroupId int64 `json:"sourceHTTPFirewallRuleGroupId" form:"sourceHTTPFirewallRuleGroupId"` // 可选项,来源WAF规则分组ID
+	SourceHTTPFirewallRuleSetId int64 `json:"sourceHTTPFirewallRuleSetId" form:"sourceHTTPFirewallRuleSetId"` // 可选项,来源WAF规则集ID
+	SourceURL string `json:"sourceURL" form:"sourceURL"` 	//  可选项,来源URL
+	SourceUserAgent string `json:"sourceUserAgent" form:"sourceUserAgent"` 	// 可选项,来源UA
+	SourceCategory string `json:"sourceCategory" form:"sourceCategory"` // 分类:cc:CC防御
+}

+ 2 - 0
cmd/server/wire/wire.go

@@ -59,6 +59,7 @@ var repositorySet = wire.NewSet(
 	repository.NewLogRepository,
 	wafRep.NewGatewayipRepository,
 	adminRep.NewGatewayIpAdminRepository,
+	flexCdnRep.NewCcIpListRepository,
 
 )
 
@@ -95,6 +96,7 @@ var serviceSet = wire.NewSet(
 	flexCdn.NewCcService,
 	service.NewLogService,
 	waf.NewGatewayipService,
+	flexCdn.NewCcIpListService,
 )
 
 var handlerSet = wire.NewSet(

+ 5 - 5
cmd/server/wire/wire_gen.go

@@ -86,7 +86,9 @@ func NewWire(viperViper *viper.Viper, logger *log.Logger) (*app.App, func(), err
 	proxyService := flexCdn2.NewProxyService(serviceService, proxyRepository, cdnService)
 	sslCertService := flexCdn2.NewSslCertService(serviceService, webForwardingRepository, cdnService)
 	websocketService := flexCdn2.NewWebsocketService(serviceService, cdnService, webForwardingRepository)
-	webForwardingService := waf2.NewWebForwardingService(serviceService, requiredService, webForwardingRepository, crawlerService, parserService, wafFormatterService, aoDunService, rabbitMQ, gatewayipService, globalLimitRepository, cdnService, proxyService, sslCertService, websocketService)
+	ccRepository := flexCdn.NewCcRepository(repositoryRepository)
+	ccService := flexCdn2.NewCcService(serviceService, ccRepository, webForwardingRepository, cdnService)
+	webForwardingService := waf2.NewWebForwardingService(serviceService, requiredService, webForwardingRepository, crawlerService, parserService, wafFormatterService, aoDunService, rabbitMQ, gatewayipService, globalLimitRepository, cdnService, proxyService, sslCertService, websocketService, ccService)
 	webForwardingHandler := waf3.NewWebForwardingHandler(handlerHandler, webForwardingService)
 	tcpforwardingService := waf2.NewTcpforwardingService(serviceService, tcpforwardingRepository, parserService, requiredService, crawlerService, globalLimitRepository, hostRepository, wafFormatterService, cdnService, proxyService)
 	tcpforwardingHandler := waf3.NewTcpforwardingHandler(handlerHandler, tcpforwardingService)
@@ -109,8 +111,6 @@ func NewWire(viperViper *viper.Viper, logger *log.Logger) (*app.App, func(), err
 	gatewayIpAdminService := admin2.NewGatewayIpAdminService(serviceService, gatewayIpAdminRepository, viperViper, requestService)
 	gatewayIpAdminHandler := admin3.NewGatewayIpAdminHandler(handlerHandler, gatewayIpAdminService)
 	allowAndDenyIpHandler := waf3.NewAllowAndDenyIpHandler(handlerHandler, allowAndDenyIpService)
-	ccRepository := flexCdn.NewCcRepository(repositoryRepository)
-	ccService := flexCdn2.NewCcService(serviceService, ccRepository, webForwardingRepository, cdnService)
 	ccHandler := handler.NewCcHandler(handlerHandler, ccService)
 	httpServer := server.NewHTTPServer(logger, viperViper, jwtJWT, syncedEnforcer, limiterLimiter, handlerFunc, userHandler, gameShieldHandler, gameShieldBackendHandler, webForwardingHandler, tcpforwardingHandler, udpForWardingHandler, globalLimitHandler, adminHandler, gatewayGroupHandler, gateWayGroupIpHandler, gatewayIpAdminHandler, allowAndDenyIpHandler, ccHandler, logService)
 	appApp := newApp(httpServer)
@@ -121,9 +121,9 @@ func NewWire(viperViper *viper.Viper, logger *log.Logger) (*app.App, func(), err
 
 // wire.go:
 
-var repositorySet = wire.NewSet(repository.NewDB, repository.NewRedis, repository.NewCasbinEnforcer, repository.NewMongoClient, repository.NewMongoDB, repository.NewRabbitMQ, repository.NewRepository, repository.NewTransaction, admin.NewAdminRepository, admin.NewUserRepository, repository.NewGameShieldRepository, repository.NewGameShieldPublicIpRepository, waf.NewWebForwardingRepository, waf.NewTcpforwardingRepository, waf.NewUdpForWardingRepository, repository.NewGameShieldUserIpRepository, repository.NewGameShieldBackendRepository, repository.NewGameShieldSdkIpRepository, repository.NewHostRepository, waf.NewGlobalLimitRepository, repository.NewGatewayGroupRepository, repository.NewGateWayGroupIpRepository, flexCdn.NewCdnRepository, waf.NewAllowAndDenyIpRepository, flexCdn.NewProxyRepository, flexCdn.NewCcRepository, repository.NewExpiredRepository, repository.NewLogRepository, waf.NewGatewayipRepository, admin.NewGatewayIpAdminRepository)
+var repositorySet = wire.NewSet(repository.NewDB, repository.NewRedis, repository.NewCasbinEnforcer, repository.NewMongoClient, repository.NewMongoDB, repository.NewRabbitMQ, repository.NewRepository, repository.NewTransaction, admin.NewAdminRepository, admin.NewUserRepository, repository.NewGameShieldRepository, repository.NewGameShieldPublicIpRepository, waf.NewWebForwardingRepository, waf.NewTcpforwardingRepository, waf.NewUdpForWardingRepository, repository.NewGameShieldUserIpRepository, repository.NewGameShieldBackendRepository, repository.NewGameShieldSdkIpRepository, repository.NewHostRepository, waf.NewGlobalLimitRepository, repository.NewGatewayGroupRepository, repository.NewGateWayGroupIpRepository, flexCdn.NewCdnRepository, waf.NewAllowAndDenyIpRepository, flexCdn.NewProxyRepository, flexCdn.NewCcRepository, repository.NewExpiredRepository, repository.NewLogRepository, waf.NewGatewayipRepository, admin.NewGatewayIpAdminRepository, flexCdn.NewCcIpListRepository)
 
-var serviceSet = wire.NewSet(service.NewService, admin2.NewUserService, admin2.NewGatewayIpAdminService, admin2.NewAdminService, gameShield.NewGameShieldService, service.NewAoDunService, service.NewGameShieldPublicIpService, service.NewDuedateService, service.NewFormatterService, service.NewParserService, service.NewRequiredService, service.NewCrawlerService, waf2.NewWebForwardingService, waf2.NewTcpforwardingService, waf2.NewUdpForWardingService, service.NewGameShieldUserIpService, gameShield.NewGameShieldBackendService, service.NewGameShieldSdkIpService, service.NewHostService, waf2.NewGlobalLimitService, service.NewGatewayGroupService, waf2.NewWafFormatterService, service.NewGateWayGroupIpService, service.NewRequestService, flexCdn2.NewCdnService, waf2.NewAllowAndDenyIpService, flexCdn2.NewProxyService, flexCdn2.NewSslCertService, flexCdn2.NewWebsocketService, flexCdn2.NewCcService, service.NewLogService, waf2.NewGatewayipService)
+var serviceSet = wire.NewSet(service.NewService, admin2.NewUserService, admin2.NewGatewayIpAdminService, admin2.NewAdminService, gameShield.NewGameShieldService, service.NewAoDunService, service.NewGameShieldPublicIpService, service.NewDuedateService, service.NewFormatterService, service.NewParserService, service.NewRequiredService, service.NewCrawlerService, waf2.NewWebForwardingService, waf2.NewTcpforwardingService, waf2.NewUdpForWardingService, service.NewGameShieldUserIpService, gameShield.NewGameShieldBackendService, service.NewGameShieldSdkIpService, service.NewHostService, waf2.NewGlobalLimitService, service.NewGatewayGroupService, waf2.NewWafFormatterService, service.NewGateWayGroupIpService, service.NewRequestService, flexCdn2.NewCdnService, waf2.NewAllowAndDenyIpService, flexCdn2.NewProxyService, flexCdn2.NewSslCertService, flexCdn2.NewWebsocketService, flexCdn2.NewCcService, service.NewLogService, waf2.NewGatewayipService, flexCdn2.NewCcIpListService)
 
 var handlerSet = wire.NewSet(handler.NewHandler, admin3.NewUserHandler, admin3.NewAdminHandler, admin3.NewGatewayIpAdminHandler, handler.NewGameShieldHandler, handler.NewGameShieldPublicIpHandler, waf3.NewWebForwardingHandler, waf3.NewTcpforwardingHandler, waf3.NewUdpForWardingHandler, handler.NewGameShieldUserIpHandler, handler.NewGameShieldBackendHandler, handler.NewGameShieldSdkIpHandler, handler.NewHostHandler, waf3.NewGlobalLimitHandler, handler.NewGatewayGroupHandler, handler.NewGateWayGroupIpHandler, waf3.NewAllowAndDenyIpHandler, handler.NewCcHandler, waf3.NewGatewayipHandler)
 

+ 2 - 0
cmd/task/wire/wire.go

@@ -50,6 +50,7 @@ var repositorySet = wire.NewSet(
 	flexCdn2.NewProxyRepository,
 	waf2.NewGatewayipRepository,
 	repository.NewLogRepository,
+	flexCdn2.NewCcRepository,
 )
 
 var taskSet = wire.NewSet(
@@ -92,6 +93,7 @@ var serviceSet = wire.NewSet(
 	flexCdn.NewProxyService,
 	flexCdn.NewSslCertService,
 	flexCdn.NewWebsocketService,
+	flexCdn.NewCcService,
 	waf.NewGatewayipService,
 	service.NewLogService,
 )

+ 5 - 3
cmd/task/wire/wire_gen.go

@@ -80,7 +80,9 @@ func NewWire(viperViper *viper.Viper, logger *log.Logger) (*app.App, func(), err
 	aoDunService := service.NewAoDunService(serviceService, viperViper)
 	sslCertService := flexCdn2.NewSslCertService(serviceService, webForwardingRepository, cdnService)
 	websocketService := flexCdn2.NewWebsocketService(serviceService, cdnService, webForwardingRepository)
-	webForwardingService := waf2.NewWebForwardingService(serviceService, requiredService, webForwardingRepository, crawlerService, parserService, wafFormatterService, aoDunService, rabbitMQ, gatewayipService, globalLimitRepository, cdnService, proxyService, sslCertService, websocketService)
+	ccRepository := flexCdn.NewCcRepository(repositoryRepository)
+	ccService := flexCdn2.NewCcService(serviceService, ccRepository, webForwardingRepository, cdnService)
+	webForwardingService := waf2.NewWebForwardingService(serviceService, requiredService, webForwardingRepository, crawlerService, parserService, wafFormatterService, aoDunService, rabbitMQ, gatewayipService, globalLimitRepository, cdnService, proxyService, sslCertService, websocketService, ccService)
 	wafTask := task.NewWafTask(webForwardingRepository, tcpforwardingRepository, udpForWardingRepository, cdnService, hostRepository, globalLimitRepository, expiredRepository, taskTask, gatewayipRepository, tcpforwardingService, udpForWardingService, webForwardingService)
 	taskServer := server.NewTaskServer(logger, userTask, gameShieldTask, wafTask)
 	jobJob := job.NewJob(transaction, logger, sidSid, rabbitMQ)
@@ -95,7 +97,7 @@ func NewWire(viperViper *viper.Viper, logger *log.Logger) (*app.App, func(), err
 
 // wire.go:
 
-var repositorySet = wire.NewSet(repository.NewDB, repository.NewRedis, repository.NewMongoClient, repository.NewCasbinEnforcer, repository.NewMongoDB, repository.NewRabbitMQ, repository.NewRepository, repository.NewTransaction, admin.NewUserRepository, repository.NewGameShieldRepository, repository.NewGameShieldBackendRepository, repository.NewGameShieldPublicIpRepository, repository.NewHostRepository, repository.NewGameShieldUserIpRepository, repository.NewGameShieldSdkIpRepository, waf.NewWebForwardingRepository, waf.NewTcpforwardingRepository, waf.NewUdpForWardingRepository, waf.NewGlobalLimitRepository, repository.NewGatewayGroupRepository, repository.NewGateWayGroupIpRepository, flexCdn.NewCdnRepository, repository.NewExpiredRepository, flexCdn.NewProxyRepository, waf.NewGatewayipRepository, repository.NewLogRepository)
+var repositorySet = wire.NewSet(repository.NewDB, repository.NewRedis, repository.NewMongoClient, repository.NewCasbinEnforcer, repository.NewMongoDB, repository.NewRabbitMQ, repository.NewRepository, repository.NewTransaction, admin.NewUserRepository, repository.NewGameShieldRepository, repository.NewGameShieldBackendRepository, repository.NewGameShieldPublicIpRepository, repository.NewHostRepository, repository.NewGameShieldUserIpRepository, repository.NewGameShieldSdkIpRepository, waf.NewWebForwardingRepository, waf.NewTcpforwardingRepository, waf.NewUdpForWardingRepository, waf.NewGlobalLimitRepository, repository.NewGatewayGroupRepository, repository.NewGateWayGroupIpRepository, flexCdn.NewCdnRepository, repository.NewExpiredRepository, flexCdn.NewProxyRepository, waf.NewGatewayipRepository, repository.NewLogRepository, flexCdn.NewCcRepository)
 
 var taskSet = wire.NewSet(task.NewTask, task.NewUserTask, task.NewGameShieldTask, task.NewWafTask)
 
@@ -103,7 +105,7 @@ var jobSet = wire.NewSet(job.NewJob, job.NewUserJob, job.NewWhitelistJob)
 
 var serverSet = wire.NewSet(server.NewTaskServer, server.NewJobServer)
 
-var serviceSet = wire.NewSet(service.NewService, service.NewAoDunService, gameShield.NewGameShieldService, service.NewCrawlerService, service.NewGameShieldPublicIpService, service.NewDuedateService, service.NewFormatterService, service.NewParserService, service.NewRequiredService, service.NewHostService, gameShield.NewGameShieldBackendService, service.NewGameShieldSdkIpService, service.NewGameShieldUserIpService, waf2.NewWafFormatterService, flexCdn2.NewCdnService, service.NewRequestService, waf2.NewTcpforwardingService, waf2.NewUdpForWardingService, waf2.NewWebForwardingService, flexCdn2.NewProxyService, flexCdn2.NewSslCertService, flexCdn2.NewWebsocketService, waf2.NewGatewayipService, service.NewLogService)
+var serviceSet = wire.NewSet(service.NewService, service.NewAoDunService, gameShield.NewGameShieldService, service.NewCrawlerService, service.NewGameShieldPublicIpService, service.NewDuedateService, service.NewFormatterService, service.NewParserService, service.NewRequiredService, service.NewHostService, gameShield.NewGameShieldBackendService, service.NewGameShieldSdkIpService, service.NewGameShieldUserIpService, waf2.NewWafFormatterService, flexCdn2.NewCdnService, service.NewRequestService, waf2.NewTcpforwardingService, waf2.NewUdpForWardingService, waf2.NewWebForwardingService, flexCdn2.NewProxyService, flexCdn2.NewSslCertService, flexCdn2.NewWebsocketService, flexCdn2.NewCcService, waf2.NewGatewayipService, service.NewLogService)
 
 // build App
 func newApp(task2 *server.TaskServer,

+ 49 - 0
internal/repository/api/flexCdn/cciplist.go

@@ -0,0 +1,49 @@
+package flexCdn
+
+import (
+	"context"
+	"github.com/go-nunu/nunu-layout-advanced/internal/repository"
+)
+
+type CcIpListRepository interface {
+	GetCcIpList(ctx context.Context, serverId int64) ([]string, error)
+	GetHttpWebId(ctx context.Context, serverId int64) (int64, error)
+	GetIpListId(ctx context.Context, serverId int64,ipListType string) (int64,error)
+	GetIpId(ctx context.Context, ipListId int64,ip string,sourceCategory string) (int64,error)
+}
+
+func NewCcIpListRepository(
+	repository *repository.Repository,
+) CcIpListRepository {
+	return &ccIpListRepository{
+		Repository: repository,
+	}
+}
+
+type ccIpListRepository struct {
+	*repository.Repository
+}
+
+func (r *ccIpListRepository) GetCcIpList(ctx context.Context, serverId int64) ([]string, error) {
+	ipListId, err := r.GetIpListId(ctx, serverId,"white")
+	if err != nil {
+		return nil, err
+	}
+	var ips []string
+	return ips, r.DBWithName(ctx,"cdn").Table("cloud_ip_items").Where("listId = ?", ipListId).Select("value").Scan(&ips).Error
+}
+
+func (r *ccIpListRepository) GetHttpWebId(ctx context.Context, serverId int64) (int64, error) {
+	var webId int64
+	return webId, r.DBWithName(ctx,"cdn").Table("cloud_servers").Where("id = ?", serverId).Select("webId").Scan(&webId).Error
+}
+
+func (r *ccIpListRepository) GetIpListId(ctx context.Context, serverId int64,ipListType string) (int64,error) {
+	var ipListId int64
+	return ipListId, r.DBWithName(ctx,"cdn").Table("cloud_ip_lists").Where("serverId = ? AND type = ?", serverId,ipListType).Select("id").Scan(&ipListId).Error
+}
+
+func (r *ccIpListRepository) GetIpId(ctx context.Context, ipListId int64,ip string,sourceCategory string) (int64,error) {
+	var ipId int64
+	return ipId, r.DBWithName(ctx,"cdn").Table("cloud_ip_items").Where("listId = ? AND value = ? AND sourceCategory = ?", ipListId,ip,sourceCategory).Select("id").Scan(&ipId).Error
+}

+ 36 - 0
internal/service/api/flexCdn/cc.go

@@ -13,6 +13,8 @@ import (
 type CcService interface {
 	GetCcList(ctx context.Context, req v1.CCListRequest) ([]v1.CCListResponse, error)
 	EditCcState(ctx context.Context, req v1.CCStateRequest) error
+	// 修改CC配置
+	EditCcConfig(ctx context.Context,webId int64, req v1.CcConfigRequest) error
 }
 func NewCcService(
     service *service.Service,
@@ -85,4 +87,38 @@ func (s *ccService) EditCcState(ctx context.Context, req v1.CCStateRequest) erro
 
 	}
 	return nil
+}
+
+
+// 修改CC配置
+func (s *ccService) EditCcConfig(ctx context.Context,webId int64, req v1.CcConfigRequest) error {
+	webConfigId, err := s.webForwardingRep.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,
+		EnableGET302: true,
+		EnableFingerprint : true,
+		IgnoreCommonFiles : true,
+	}); err != nil {
+		return err
+	}
+	return nil
 }

+ 104 - 0
internal/service/api/flexCdn/cciplist.go

@@ -0,0 +1,104 @@
+package flexCdn
+
+import (
+	"context"
+	"fmt"
+	v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
+	"github.com/go-nunu/nunu-layout-advanced/internal/repository/api/flexCdn"
+	"github.com/go-nunu/nunu-layout-advanced/internal/service"
+)
+
+type CcIpListService interface {
+	GetCcIpList(ctx context.Context, serverId int64) ([]string, error)
+	AddCcIpListPolicy(ctx context.Context, serverId int64,serverGroupId int64,httpWebId int64) error
+}
+func NewCcIpListService(
+    service *service.Service,
+    ccIpListRepository flexCdn.CcIpListRepository,
+	cdn CdnService,
+) CcIpListService {
+	return &ccIpListService{
+		Service:        service,
+		ccIpListRepository: ccIpListRepository,
+		cdn: cdn,
+	}
+}
+
+type ccIpListService struct {
+	*service.Service
+	ccIpListRepository flexCdn.CcIpListRepository
+	cdn CdnService
+}
+
+func (s *ccIpListService) GetCcIpList(ctx context.Context, serverId int64) ([]string, error) {
+	return s.ccIpListRepository.GetCcIpList(ctx, serverId)
+}
+
+func (s *ccIpListService) AddCcIpListPolicy(ctx context.Context, serverId int64,serverGroupId int64,httpWebId int64) error {
+	// 创建用户自定义防火墙策略
+	httpFirewallPolicyId, err := s.cdn.AddWafPolicy(ctx, v1.AddWafPolicy{
+		IsOn: true,
+		ServerId: serverId,
+		ServerGroupId: serverGroupId,
+		Name: "用户自定义防火墙策略",
+		Description: "",
+	})
+	if err != nil {
+		return err
+	}
+	if httpFirewallPolicyId == 0 {
+		return fmt.Errorf("创建用户自定义防火墙策略失败")
+	}
+	// 修改防火墙
+	err = s.cdn.EditHTTPWebFirewal(ctx, httpWebId, v1.Firewall{
+		IsOn: true,
+		IsPrior: false,
+		FirewallPolicyId: httpFirewallPolicyId,
+		IgnoreGlobalRules: false,
+		DefaultCaptchaType: "default",
+	})
+	if err != nil {
+		return err
+	}
+
+
+	return nil
+}
+
+
+// 添加白名单
+func (s *ccIpListService) AddCcWhiteIp(ctx context.Context, serverId int64,ip string) error {
+	ipListId, err := s.ccIpListRepository.GetIpListId(ctx, serverId,"white")
+	if err != nil {
+		return err
+	}
+
+	err = s.cdn.AddIpItem(ctx,v1.AddIpItem{
+		IpListId: ipListId,
+		Value: ip,
+		EventLevel: "critical",
+		SourceCategory: "cc",
+	})
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (s *ccIpListService) DelCcWhiteIp(ctx context.Context, serverId int64,ip string) error {
+	ipListId, err := s.ccIpListRepository.GetIpListId(ctx, serverId,"white")
+	if err != nil {
+		return err
+	}
+
+	ipItemId, err := s.ccIpListRepository.GetIpId(ctx, ipListId,ip,"cc")
+	if err != nil {
+		return err
+	}
+	err = s.cdn.DelIpItem(ctx,ipItemId,ip,"", "", ipListId)
+	if err != nil {
+		return err
+	}
+	return nil
+
+}

+ 125 - 0
internal/service/api/flexCdn/cdn.go

@@ -62,6 +62,14 @@ type CdnService interface {
 	DelServerGroup(ctx context.Context,serverId int64) error
 	// 删除IP
 	DelIpItem(ctx context.Context,ipitemId int64,value string,ipFrom string,ipTo string,ipListId int64) error
+	// 创建空防火墙策略
+	AddWafPolicy(ctx context.Context,req v1.AddWafPolicy) (int64, error)
+	// 更改防火墙设置
+	EditHTTPWebFirewal(ctx context.Context,httpWebId int64,FirewallJSON v1.Firewall) error
+	// 创建IP列表
+	AddIPList(ctx context.Context, req v1.IPListRequest) (int64, error)
+	// 添加IP
+	AddIpItem(ctx context.Context, req v1.AddIpItem) error
 }
 
 func NewCdnService(
@@ -1025,3 +1033,120 @@ func (s *cdnService) DelIpItem(ctx context.Context,ipitemId int64,value string,i
 	return nil
 }
 
+// 创建空防火墙策略
+func (s *cdnService) AddWafPolicy(ctx context.Context,req v1.AddWafPolicy) (int64, error) {
+	formData := map[string]interface{}{
+		"isOn":     req.IsOn,
+		"name"     : req.Name,
+		"description" : req.Description,
+		"serverId" : req.ServerId,
+		"serverGroupId" : req.ServerGroupId,
+	}
+	apiUrl := s.Url + "HTTPFirewallPolicyService/createEmptyHTTPFirewallPolicy"
+	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
+	if err != nil {
+		return 0, err
+	}
+	var res v1.GeneralResponse[int64]
+	if err := json.Unmarshal(resBody, &res); err != nil {
+		return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
+	}
+	if res.Code != 200 {
+		return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
+	}
+	return res.Data, nil
+}
+
+// 更改防火墙设置
+func (s *cdnService) EditHTTPWebFirewal(ctx context.Context,httpWebId int64,FirewallJSON v1.Firewall) error {
+
+	frireWallJson,err := json.Marshal(FirewallJSON)
+	if err != nil {
+		return err
+	}
+
+	formData := map[string]interface{}{
+		"httpWebId" : httpWebId,
+		"firewallJSON" : frireWallJson,
+	}
+
+	apiUrl := s.Url + "HTTPWebService/updateHTTPWebFirewall"
+	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
+
+}
+
+
+// 创建IP列表
+func (s *cdnService) AddIPList(ctx context.Context, req v1.IPListRequest) (int64, error) {
+	formData := map[string]interface{}{
+		"type": req.Type,
+		"name": req.Name,
+		"code": req.Code,
+		"timeoutJSON": req.TimeoutJSON,
+		"isPublic": req.IsPublic,
+		"description": req.Description,
+		"isGlobal": req.IsGlobal,
+		"serverId": req.ServerId,
+	}
+	apiUrl := s.Url + "IPListService/createIPList"
+	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
+	if err != nil {
+		return 0, err
+	}
+	var res v1.GeneralResponse[int64]
+	if err := json.Unmarshal(resBody, &res); err != nil {
+		return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
+	}
+	if res.Code != 200 {
+		return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
+	}
+	return res.Data, nil
+}
+
+// 创建IP
+func (s *cdnService) AddIpItem(ctx context.Context, req v1.AddIpItem) error {
+	formData := map[string]interface{}{
+		"ipListId": req.IpListId,
+		"value":    req.Value,
+		"ipFrom":   req.IpFrom,
+		"ipTo":     req.IpTo,
+		"expiredAt": req.ExpiredAt,
+		"reason":   req.Reason,
+		"type":     req.Type,
+		"eventLevel": req.EventLevel,
+		"nodeId": req.NodeId,
+		"serverId": req.ServerId,
+		"sourceNodeId": req.SourceNodeId,
+		"sourceServerId": req.SourceServerId,
+		"sourceHTTPFirewallPolicyId": req.SourceHTTPFirewallPolicyId,
+		"sourceHTTPFirewallRuleGroupId": req.SourceHTTPFirewallRuleGroupId,
+		"sourceHTTPFirewallRuleSetId": req.SourceHTTPFirewallRuleSetId,
+		"sourceURL": req.SourceURL,
+		"sourceUserAgent": req.SourceUserAgent,
+		"sourceCategory": req.SourceCategory,
+	}
+	apiUrl := s.Url + "IPItemService/createIPItem"
+	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
+}

+ 5 - 33
internal/service/api/waf/webforwarding.go

@@ -39,6 +39,7 @@ func NewWebForwardingService(
 	proxy flexCdn.ProxyService,
 	sslCert flexCdn.SslCertService,
 	websocket flexCdn.WebsocketService,
+	cc flexCdn.CcService,
 ) WebForwardingService {
 	return &webForwardingService{
 		Service:                 service,
@@ -55,6 +56,7 @@ func NewWebForwardingService(
 		proxy:                   proxy,
 		sslCert:               	 sslCert,
 		websocket:               websocket,
+		cc:                      cc,
 	}
 }
 
@@ -80,6 +82,7 @@ type webForwardingService struct {
 	proxy          flexCdn.ProxyService
 	sslCert        flexCdn.SslCertService
 	websocket      flexCdn.WebsocketService
+	cc             flexCdn.CcService
 }
 
 func (s *webForwardingService) require(ctx context.Context, req v1.GlobalRequire) (v1.GlobalRequire, error) {
@@ -481,7 +484,7 @@ func (s *webForwardingService) AddWebForwarding(ctx context.Context, req *v1.Web
 
 	// 开启CC
 	if req.WebForwardingData.CcConfig.IsOn {
-		err = s.EditCcConfig(ctx, webId, req.WebForwardingData.CcConfig)
+		err = s.cc.EditCcConfig(ctx, webId, req.WebForwardingData.CcConfig)
 		if err != nil {
 			return err
 		}
@@ -683,7 +686,7 @@ func (s *webForwardingService) EditWebForwarding(ctx context.Context, req *v1.We
 	}
 
 	// 修改CC配置
-	err = s.EditCcConfig(ctx, int64(oldData.CdnWebId), v1.CcConfigRequest{
+	err = s.cc.EditCcConfig(ctx, int64(oldData.CdnWebId), v1.CcConfigRequest{
 		IsOn:            req.WebForwardingData.CcConfig.IsOn,
 		Level:           req.WebForwardingData.CcConfig.Level,
 		Limit5s:         req.WebForwardingData.CcConfig.Limit5s,
@@ -1080,38 +1083,7 @@ func (s *webForwardingService) EditLog(ctx context.Context,webId int64) error {
 	return nil
 }
 
-// 修改CC配置
-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,
-		EnableGET302: true,
-		EnableFingerprint : true,
-		IgnoreCommonFiles : true,
-	}); err != nil {
-		return err
-	}
-	return nil
-}
 
 
 func (s *webForwardingService) BulidFormData(ctx context.Context,formData v1.Website) (v1.WebsiteSend, error) {