Przeglądaj źródła

feat(flexcdn): 新增 CC 攻击防护的 IP 白名单功能

- 添加 CC 攻击防护的 IP 白名单相关结构和接口
- 实现获取、添加、编辑和删除 CC白名单 IP 的功能
- 更新 Web 转发服务,集成 CC IP 白名单功能
- 新增 CC IP 白名单处理相关的任务和处理器
fusu 2 tygodni temu
rodzic
commit
8939340c84

+ 22 - 0
api/v1/ccIpList.go

@@ -0,0 +1,22 @@
+package v1
+
+type GetCcIpList struct {
+	Uid int64 `json:"uid" form:"uid" validate:"required"`
+	HostId int64 `json:"hostId" form:"hostId" validate:"required"`
+	WebId int64 `json:"webId" form:"webId" validate:"required"`
+}
+
+type CcIpList struct {
+	OldIp string `json:"oldIp" form:"oldIp"`
+	NewIp string `json:"newIp" form:"newIp"`
+	Uid int64 `json:"uid" form:"uid" validate:"required"`
+	HostId int64 `json:"hostId" form:"hostId" validate:"required"`
+	WebId int64 `json:"webId" form:"webId" validate:"required"`
+}
+
+type DelCcIpList struct {
+	Ips []string `json:"ips" form:"ips"`
+	Uid int64 `json:"uid" form:"uid" validate:"required"`
+	HostId int64 `json:"hostId" form:"hostId" validate:"required"`
+	WebId int64 `json:"webId" form:"webId" validate:"required"`
+}

+ 1 - 0
api/v1/cdn.go

@@ -258,6 +258,7 @@ type IPListRequest struct {
 }
 
 type AddIpItem struct {
+	IpItemId  int64 `json:"ipItemId" form:"ipItemId"`
 	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

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

@@ -119,6 +119,7 @@ var handlerSet = wire.NewSet(
 	wafHandler.NewAllowAndDenyIpHandler,
 	handler.NewCcHandler,
 	wafHandler.NewGatewayipHandler,
+	wafHandler.NewCcIpListHandler,
 )
 
 

+ 4 - 2
cmd/server/wire/wire_gen.go

@@ -88,7 +88,9 @@ func NewWire(viperViper *viper.Viper, logger *log.Logger) (*app.App, func(), err
 	websocketService := flexCdn2.NewWebsocketService(serviceService, cdnService, webForwardingRepository)
 	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)
+	ccIpListRepository := flexCdn.NewCcIpListRepository(repositoryRepository)
+	ccIpListService := flexCdn2.NewCcIpListService(serviceService, ccIpListRepository, cdnService, webForwardingRepository)
+	webForwardingService := waf2.NewWebForwardingService(serviceService, requiredService, webForwardingRepository, crawlerService, parserService, wafFormatterService, aoDunService, rabbitMQ, gatewayipService, globalLimitRepository, cdnService, proxyService, sslCertService, websocketService, ccService, ccIpListService)
 	webForwardingHandler := waf3.NewWebForwardingHandler(handlerHandler, webForwardingService)
 	tcpforwardingService := waf2.NewTcpforwardingService(serviceService, tcpforwardingRepository, parserService, requiredService, crawlerService, globalLimitRepository, hostRepository, wafFormatterService, cdnService, proxyService)
 	tcpforwardingHandler := waf3.NewTcpforwardingHandler(handlerHandler, tcpforwardingService)
@@ -125,7 +127,7 @@ var repositorySet = wire.NewSet(repository.NewDB, repository.NewRedis, repositor
 
 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)
+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, waf3.NewCcIpListHandler)
 
 // 限流器依赖集
 var limiterSet = wire.NewSet(limiter.NewLimiter, middleware.NewRateLimitMiddleware)

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

@@ -51,6 +51,7 @@ var repositorySet = wire.NewSet(
 	waf2.NewGatewayipRepository,
 	repository.NewLogRepository,
 	flexCdn2.NewCcRepository,
+	flexCdn2.NewCcIpListRepository,
 )
 
 var taskSet = wire.NewSet(
@@ -96,6 +97,7 @@ var serviceSet = wire.NewSet(
 	flexCdn.NewCcService,
 	waf.NewGatewayipService,
 	service.NewLogService,
+	flexCdn.NewCcIpListService,
 )
 
 // build App

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

@@ -82,7 +82,9 @@ func NewWire(viperViper *viper.Viper, logger *log.Logger) (*app.App, func(), err
 	websocketService := flexCdn2.NewWebsocketService(serviceService, cdnService, webForwardingRepository)
 	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)
+	ccIpListRepository := flexCdn.NewCcIpListRepository(repositoryRepository)
+	ccIpListService := flexCdn2.NewCcIpListService(serviceService, ccIpListRepository, cdnService, webForwardingRepository)
+	webForwardingService := waf2.NewWebForwardingService(serviceService, requiredService, webForwardingRepository, crawlerService, parserService, wafFormatterService, aoDunService, rabbitMQ, gatewayipService, globalLimitRepository, cdnService, proxyService, sslCertService, websocketService, ccService, ccIpListService)
 	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)
@@ -97,7 +99,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, flexCdn.NewCcRepository)
+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, flexCdn.NewCcIpListRepository)
 
 var taskSet = wire.NewSet(task.NewTask, task.NewUserTask, task.NewGameShieldTask, task.NewWafTask)
 
@@ -105,7 +107,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, flexCdn2.NewCcService, 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, flexCdn2.NewCcIpListService)
 
 // build App
 func newApp(task2 *server.TaskServer,

+ 1 - 1
internal/repository/api/flexCdn/cciplist.go

@@ -30,7 +30,7 @@ func (r *ccIpListRepository) GetCcIpList(ctx context.Context, serverId int64) ([
 		return nil, err
 	}
 	var ips []string
-	return ips, r.DBWithName(ctx,"cdn").Table("cloud_ip_items").Where("listId = ?", ipListId).Select("value").Scan(&ips).Error
+	return ips, r.DBWithName(ctx,"cdn").Table("cloud_ip_items").Where("listId = ? AND sourceCategory = cc", ipListId).Select("value").Scan(&ips).Error
 }
 
 func (r *ccIpListRepository) GetHttpWebId(ctx context.Context, serverId int64) (int64, error) {

+ 76 - 15
internal/service/api/flexCdn/cciplist.go

@@ -5,22 +5,29 @@ import (
 	"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/repository/api/waf"
 	"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
+	GetCcIpList(ctx context.Context, webId int64) ([]string, error)
+	AddCcIpListPolicy(ctx context.Context, serverId int64,serverGroupId int64) error
+	AddCcWhiteIp(ctx context.Context, webId int64,ip string) error
+	DelCcWhiteIp(ctx context.Context, webId int64,ips []string) error
+	EditCcWhiteIp(ctx context.Context, webId int64,oldIp string,newIp string) error
+
 }
 func NewCcIpListService(
     service *service.Service,
     ccIpListRepository flexCdn.CcIpListRepository,
 	cdn CdnService,
+	webForwardingRep waf.WebForwardingRepository,
 ) CcIpListService {
 	return &ccIpListService{
 		Service:        service,
 		ccIpListRepository: ccIpListRepository,
 		cdn: cdn,
+		webForwardingRep: webForwardingRep,
 	}
 }
 
@@ -28,13 +35,33 @@ type ccIpListService struct {
 	*service.Service
 	ccIpListRepository flexCdn.CcIpListRepository
 	cdn CdnService
+	webForwardingRep waf.WebForwardingRepository
 }
 
-func (s *ccIpListService) GetCcIpList(ctx context.Context, serverId int64) ([]string, error) {
-	return s.ccIpListRepository.GetCcIpList(ctx, serverId)
+func (s *ccIpListService) GetServerId(ctx context.Context, webId int64) (int64, error) {
+	webData, err := s.webForwardingRep.GetWebForwarding(ctx, webId)
+	if err != nil {
+		return 0, err
+	}
+	return int64(webData.CdnWebId), nil
 }
 
-func (s *ccIpListService) AddCcIpListPolicy(ctx context.Context, serverId int64,serverGroupId int64,httpWebId int64) error {
+func (s *ccIpListService) GetCcIpList(ctx context.Context, webId int64) ([]string, error) {
+	webData, err := s.webForwardingRep.GetWebForwarding(ctx, webId)
+	if err != nil {
+		return nil, err
+	}
+	return s.ccIpListRepository.GetCcIpList(ctx, int64(webData.CdnWebId))
+}
+
+func (s *ccIpListService) AddCcIpListPolicy(ctx context.Context, serverId int64,serverGroupId int64) error {
+
+	httpWebId, err := s.ccIpListRepository.GetHttpWebId(ctx, serverId)
+	if err != nil {
+		return err
+	}
+
+
 	// 创建用户自定义防火墙策略
 	httpFirewallPolicyId, err := s.cdn.AddWafPolicy(ctx, v1.AddWafPolicy{
 		IsOn: true,
@@ -51,11 +78,11 @@ func (s *ccIpListService) AddCcIpListPolicy(ctx context.Context, serverId int64,
 	}
 	// 修改防火墙
 	err = s.cdn.EditHTTPWebFirewal(ctx, httpWebId, v1.Firewall{
-		IsOn: true,
-		IsPrior: false,
-		FirewallPolicyId: httpFirewallPolicyId,
-		IgnoreGlobalRules: false,
-		DefaultCaptchaType: "default",
+		IsOn:               true,
+		IsPrior:            false,
+		FirewallPolicyId:   httpFirewallPolicyId,
+		IgnoreGlobalRules:  true,
+		DefaultCaptchaType: "none",
 	})
 	if err != nil {
 		return err
@@ -85,20 +112,54 @@ func (s *ccIpListService) AddCcWhiteIp(ctx context.Context, serverId int64,ip st
 	return nil
 }
 
-func (s *ccIpListService) DelCcWhiteIp(ctx context.Context, serverId int64,ip string) error {
-	ipListId, err := s.ccIpListRepository.GetIpListId(ctx, serverId,"white")
+func (s *ccIpListService) EditCcWhiteIp(ctx context.Context, webId int64,oldIp string,newIp string) error {
+	serverId, err := s.GetServerId(ctx, webId)
 	if err != nil {
 		return err
 	}
 
-	ipItemId, err := s.ccIpListRepository.GetIpId(ctx, ipListId,ip,"cc")
+	ipListId, err := s.ccIpListRepository.GetIpListId(ctx, serverId,"white")
 	if err != nil {
 		return err
 	}
-	err = s.cdn.DelIpItem(ctx,ipItemId,ip,"", "", ipListId)
+	ipItemId, err := s.ccIpListRepository.GetIpId(ctx, ipListId,oldIp,"cc")
+	if err != nil {
+		return err
+	}
+	err = s.cdn.EditIpItem(ctx,v1.AddIpItem{
+		IpItemId: ipItemId,
+		Value: newIp,
+		EventLevel: "notice",
+		SourceCategory: "cc",
+	})
 	if err != nil {
 		return err
 	}
 	return nil
 
-}
+}
+
+func (s *ccIpListService) DelCcWhiteIp(ctx context.Context, webId int64,ips []string) error {
+	serverId, err := s.GetServerId(ctx, webId)
+	if err != nil {
+		return err
+	}
+
+	for _,ip := range ips {
+		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
+}

+ 31 - 2
internal/service/api/flexCdn/cdn.go

@@ -70,6 +70,8 @@ type CdnService interface {
 	AddIPList(ctx context.Context, req v1.IPListRequest) (int64, error)
 	// 添加IP
 	AddIpItem(ctx context.Context, req v1.AddIpItem) error
+	// 修改IP
+	EditIpItem(ctx context.Context, req v1.AddIpItem) error
 }
 
 func NewCdnService(
@@ -1047,14 +1049,17 @@ func (s *cdnService) AddWafPolicy(ctx context.Context,req v1.AddWafPolicy) (int6
 	if err != nil {
 		return 0, err
 	}
-	var res v1.GeneralResponse[int64]
+	var res v1.GeneralResponse[map[string]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
+	if res.Data["httpFirewallPolicyId"] == 0 {
+		return 0, fmt.Errorf("创建空防火墙策略失败")
+	}
+	return res.Data["httpFirewallPolicyId"], nil
 }
 
 // 更改防火墙设置
@@ -1149,4 +1154,28 @@ func (s *cdnService) AddIpItem(ctx context.Context, req v1.AddIpItem) error {
 		return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
 	}
 	return nil
+}
+
+// 修改IP
+func (s *cdnService) EditIpItem(ctx context.Context, req v1.AddIpItem) error {
+	formData := map[string]interface{}{
+		"ipItemId": req.IpItemId,
+		"value":    req.Value,
+		"reason"   : req.Reason,
+		"type"     : req.Type,
+		"eventLevel" : req.EventLevel,
+	}
+	apiUrl := s.Url + "IPItemService/updateIPItem"
+	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
 }

+ 9 - 0
internal/service/api/waf/webforwarding.go

@@ -40,6 +40,7 @@ func NewWebForwardingService(
 	sslCert flexCdn.SslCertService,
 	websocket flexCdn.WebsocketService,
 	cc flexCdn.CcService,
+	ccIpList flexCdn.CcIpListService,
 ) WebForwardingService {
 	return &webForwardingService{
 		Service:                 service,
@@ -57,6 +58,7 @@ func NewWebForwardingService(
 		sslCert:               	 sslCert,
 		websocket:               websocket,
 		cc:                      cc,
+		ccIpList:                ccIpList,
 	}
 }
 
@@ -83,6 +85,7 @@ type webForwardingService struct {
 	sslCert        flexCdn.SslCertService
 	websocket      flexCdn.WebsocketService
 	cc             flexCdn.CcService
+	ccIpList       flexCdn.CcIpListService
 }
 
 func (s *webForwardingService) require(ctx context.Context, req v1.GlobalRequire) (v1.GlobalRequire, error) {
@@ -491,6 +494,12 @@ func (s *webForwardingService) AddWebForwarding(ctx context.Context, req *v1.Web
 	}
 
 
+	// 开启waf防火墙
+	if err = s.ccIpList.AddCcIpListPolicy(ctx, webId, int64(require.GroupId)); err != nil {
+		return err
+	}
+
+
 
 	webModel := s.buildWebForwardingModel(&req.WebForwardingData, int(webId), require)