实现WAF通知和记录IP功能

This commit is contained in:
GoEdgeLab
2021-07-18 15:52:34 +08:00
parent 51718fbea7
commit 742dd83644
9 changed files with 133 additions and 14 deletions

View File

@@ -233,6 +233,12 @@ func (this *HTTPAccessLogDAO) listAccessLogs(tx *dbs.Tx, lastRequestId string, s
where := "JSON_EXTRACT(content, '$.remoteAddr') LIKE :keyword OR JSON_EXTRACT(content, '$.requestURI') LIKE :keyword OR JSON_EXTRACT(content, '$.host') LIKE :keyword" where := "JSON_EXTRACT(content, '$.remoteAddr') LIKE :keyword OR JSON_EXTRACT(content, '$.requestURI') LIKE :keyword OR JSON_EXTRACT(content, '$.host') LIKE :keyword"
jsonKeyword, err := json.Marshal(keyword)
if err == nil {
where += " OR JSON_CONTAINS(content, :jsonKeyword, '$.tags')"
query.Param("jsonKeyword", jsonKeyword)
}
// 请求方法 // 请求方法
if keyword == http.MethodGet || if keyword == http.MethodGet ||
keyword == http.MethodPost || keyword == http.MethodPost ||

View File

@@ -86,6 +86,16 @@ func (this *IPItemDAO) FindEnabledIPItem(tx *dbs.Tx, id int64) (*IPItem, error)
return result.(*IPItem), err return result.(*IPItem), err
} }
// DisableOldIPItem 根据IP删除以前的旧记录
func (this *IPItemDAO) DisableOldIPItem(tx *dbs.Tx, listId int64, ipFrom string, ipTo string) error {
return this.Query(tx).
Attr("listId", listId).
Attr("ipFrom", ipFrom).
Attr("ipTo", ipTo).
Set("state", IPItemStateDisabled).
UpdateQuickly()
}
// CreateIPItem 创建IP // CreateIPItem 创建IP
func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx, listId int64, ipFrom string, ipTo string, expiredAt int64, reason string, itemType IPItemType, eventLevel string) (int64, error) { func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx, listId int64, ipFrom string, ipTo string, expiredAt int64, reason string, itemType IPItemType, eventLevel string) (int64, error) {
version, err := SharedIPListDAO.IncreaseVersion(tx) version, err := SharedIPListDAO.IncreaseVersion(tx)

View File

@@ -38,6 +38,7 @@ const (
MessageTypeServerNamesAuditingSuccess MessageType = "ServerNamesAuditingSuccess" // 服务域名审核成功 MessageTypeServerNamesAuditingSuccess MessageType = "ServerNamesAuditingSuccess" // 服务域名审核成功
MessageTypeServerNamesAuditingFailed MessageType = "ServerNamesAuditingFailed" // 服务域名审核失败 MessageTypeServerNamesAuditingFailed MessageType = "ServerNamesAuditingFailed" // 服务域名审核失败
MessageTypeThresholdSatisfied MessageType = "ThresholdSatisfied" // 满足阈值 MessageTypeThresholdSatisfied MessageType = "ThresholdSatisfied" // 满足阈值
MessageTypeFirewallEvent MessageType = "FirewallEvent" // 防火墙事件
) )
type MessageDAO dbs.DAO type MessageDAO dbs.DAO

View File

@@ -111,6 +111,37 @@ func (this *MessageReceiverDAO) FindAllEnabledReceivers(tx *dbs.Tx, target Messa
AscPk(). AscPk().
Slice(&result). Slice(&result).
FindAll() FindAll()
if err != nil {
return nil, err
}
if len(result) == 0 {
// 去掉类型再试试
query := this.Query(tx)
_, err = query.
Attr("clusterId", target.ClusterId).
Attr("nodeId", target.NodeId).
Attr("serverId", target.ServerId).
State(MessageReceiverStateEnabled).
AscPk().
Slice(&result).
FindAll()
if err != nil {
return nil, err
}
// 去掉服务和节点再试试
if len(result) == 0 {
query := this.Query(tx)
_, err = query.
Attr("clusterId", target.ClusterId).
State(MessageReceiverStateEnabled).
AscPk().
Slice(&result).
FindAll()
}
}
return return
} }

View File

@@ -2,8 +2,10 @@
package models package models
// MessageTaskTarget 消息接收对象
// 每个字段不一定都有值
type MessageTaskTarget struct { type MessageTaskTarget struct {
ClusterId int64 ClusterId int64 // 集群ID
NodeId int64 NodeId int64 // 节点ID
ServerId int64 ServerId int64 // 服务ID
} }

View File

@@ -554,6 +554,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64) (*nodeconfigs.N
config := &nodeconfigs.NodeConfig{ config := &nodeconfigs.NodeConfig{
Id: int64(node.Id), Id: int64(node.Id),
NodeId: node.UniqueId, NodeId: node.UniqueId,
Secret: node.Secret,
IsOn: node.IsOn == 1, IsOn: node.IsOn == 1,
Servers: nil, Servers: nil,
Version: int64(node.Version), Version: int64(node.Version),

View File

@@ -10,6 +10,7 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/types" "github.com/iwind/TeaGo/types"
timeutil "github.com/iwind/TeaGo/utils/time" timeutil "github.com/iwind/TeaGo/utils/time"
"strconv"
"time" "time"
) )
@@ -176,3 +177,60 @@ func (this *FirewallService) ComposeFirewallGlobalBoard(ctx context.Context, req
return result, nil return result, nil
} }
// NotifyHTTPFirewallEvent 发送告警(notify)消息
func (this *FirewallService) NotifyHTTPFirewallEvent(ctx context.Context, req *pb.NotifyHTTPFirewallEventRequest) (*pb.RPCSuccess, error) {
nodeId, err := this.ValidateNode(ctx)
if err != nil {
return nil, err
}
var tx = this.NullTx()
clusterId, err := models.SharedNodeDAO.FindNodeClusterId(tx, nodeId)
if err != nil {
return nil, err
}
if clusterId <= 0 {
return this.Success()
}
clusterName, err := models.SharedNodeClusterDAO.FindNodeClusterName(tx, clusterId)
if err != nil {
return nil, err
}
nodeName, err := models.SharedNodeDAO.FindNodeName(tx, nodeId)
if err != nil {
return nil, err
}
serverName, err := models.SharedServerDAO.FindEnabledServerName(tx, req.ServerId)
if err != nil {
return nil, err
}
ruleGroupName, err := models.SharedHTTPFirewallRuleGroupDAO.FindHTTPFirewallRuleGroupName(tx, req.HttpFirewallRuleGroupId)
if err != nil {
return nil, err
}
ruleSetName, err := models.SharedHTTPFirewallRuleSetDAO.FindHTTPFirewallRuleSetName(tx, req.HttpFirewallRuleSetId)
if err != nil {
return nil, err
}
msg := "集群:" + clusterName + "ID" + strconv.FormatInt(clusterId, 10) + "" +
"\n节点" + nodeName + "ID" + strconv.FormatInt(nodeId, 10) + "" +
"\n服务" + serverName + "ID" + strconv.FormatInt(req.ServerId, 10) + "" +
"\n规则分组" + ruleGroupName +
"\n规则集" + ruleSetName +
"\n时间" + timeutil.FormatTime("Y-m-d H:i:s", req.CreatedAt)
err = models.SharedMessageTaskDAO.CreateMessageTasks(tx, models.MessageTaskTarget{
ClusterId: clusterId,
NodeId: nodeId,
ServerId: req.ServerId,
}, models.MessageTypeFirewallEvent, "发生防火墙事件", msg)
if err != nil {
return nil, err
}
return this.Success()
}

View File

@@ -18,7 +18,7 @@ type IPItemService struct {
// CreateIPItem 创建IP // CreateIPItem 创建IP
func (this *IPItemService) CreateIPItem(ctx context.Context, req *pb.CreateIPItemRequest) (*pb.CreateIPItemResponse, error) { func (this *IPItemService) CreateIPItem(ctx context.Context, req *pb.CreateIPItemRequest) (*pb.CreateIPItemResponse, error) {
// 校验请求 // 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0) userType, _, userId, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser, rpcutils.UserTypeNode, rpcutils.UserTypeDNS)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -41,10 +41,14 @@ func (this *IPItemService) CreateIPItem(ctx context.Context, req *pb.CreateIPIte
tx := this.NullTx() tx := this.NullTx()
if userId > 0 { if userType == rpcutils.UserTypeUser {
err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId) if userId <= 0 {
if err != nil { return nil, errors.New("invalid userId")
return nil, err } else {
err = models.SharedIPListDAO.CheckUserIPList(tx, userId, req.IpListId)
if err != nil {
return nil, err
}
} }
} }
@@ -52,6 +56,12 @@ func (this *IPItemService) CreateIPItem(ctx context.Context, req *pb.CreateIPIte
req.Type = models.IPItemTypeIPv4 req.Type = models.IPItemTypeIPv4
} }
// 删除以前的
err = models.SharedIPItemDAO.DisableOldIPItem(tx, req.IpListId, req.IpFrom, req.IpTo)
if err != nil {
return nil, err
}
itemId, err := models.SharedIPItemDAO.CreateIPItem(tx, req.IpListId, req.IpFrom, req.IpTo, req.ExpiredAt, req.Reason, req.Type, req.EventLevel) itemId, err := models.SharedIPItemDAO.CreateIPItem(tx, req.IpListId, req.IpFrom, req.IpTo, req.ExpiredAt, req.Reason, req.Type, req.EventLevel)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -9,12 +9,12 @@ import (
"github.com/iwind/TeaGo/types" "github.com/iwind/TeaGo/types"
) )
// 消息发送任务服务 // MessageTaskService 消息发送任务服务
type MessageTaskService struct { type MessageTaskService struct {
BaseService BaseService
} }
// 创建任务 // CreateMessageTask 创建任务
func (this *MessageTaskService) CreateMessageTask(ctx context.Context, req *pb.CreateMessageTaskRequest) (*pb.CreateMessageTaskResponse, error) { func (this *MessageTaskService) CreateMessageTask(ctx context.Context, req *pb.CreateMessageTaskRequest) (*pb.CreateMessageTaskResponse, error) {
_, err := this.ValidateAdmin(ctx, 0) _, err := this.ValidateAdmin(ctx, 0)
if err != nil { if err != nil {
@@ -29,7 +29,7 @@ func (this *MessageTaskService) CreateMessageTask(ctx context.Context, req *pb.C
return &pb.CreateMessageTaskResponse{MessageTaskId: taskId}, nil return &pb.CreateMessageTaskResponse{MessageTaskId: taskId}, nil
} }
// 查找要发送的任务 // FindSendingMessageTasks 查找要发送的任务
func (this *MessageTaskService) FindSendingMessageTasks(ctx context.Context, req *pb.FindSendingMessageTasksRequest) (*pb.FindSendingMessageTasksResponse, error) { func (this *MessageTaskService) FindSendingMessageTasks(ctx context.Context, req *pb.FindSendingMessageTasksRequest) (*pb.FindSendingMessageTasksResponse, error) {
_, err := this.ValidateMonitor(ctx) _, err := this.ValidateMonitor(ctx)
if err != nil { if err != nil {
@@ -126,7 +126,7 @@ func (this *MessageTaskService) FindSendingMessageTasks(ctx context.Context, req
return &pb.FindSendingMessageTasksResponse{MessageTasks: pbTasks}, nil return &pb.FindSendingMessageTasksResponse{MessageTasks: pbTasks}, nil
} }
// 修改任务状态 // UpdateMessageTaskStatus 修改任务状态
func (this *MessageTaskService) UpdateMessageTaskStatus(ctx context.Context, req *pb.UpdateMessageTaskStatusRequest) (*pb.RPCSuccess, error) { func (this *MessageTaskService) UpdateMessageTaskStatus(ctx context.Context, req *pb.UpdateMessageTaskStatusRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateMonitor(ctx) _, err := this.ValidateMonitor(ctx)
if err != nil { if err != nil {
@@ -162,7 +162,7 @@ func (this *MessageTaskService) UpdateMessageTaskStatus(ctx context.Context, req
return this.Success() return this.Success()
} }
// 删除消息任务 // DeleteMessageTask 删除消息任务
func (this *MessageTaskService) DeleteMessageTask(ctx context.Context, req *pb.DeleteMessageTaskRequest) (*pb.RPCSuccess, error) { func (this *MessageTaskService) DeleteMessageTask(ctx context.Context, req *pb.DeleteMessageTaskRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0) _, err := this.ValidateAdmin(ctx, 0)
if err != nil { if err != nil {
@@ -178,7 +178,7 @@ func (this *MessageTaskService) DeleteMessageTask(ctx context.Context, req *pb.D
return this.Success() return this.Success()
} }
// 读取消息任务状态 // FindEnabledMessageTask 读取消息任务状态
func (this *MessageTaskService) FindEnabledMessageTask(ctx context.Context, req *pb.FindEnabledMessageTaskRequest) (*pb.FindEnabledMessageTaskResponse, error) { func (this *MessageTaskService) FindEnabledMessageTask(ctx context.Context, req *pb.FindEnabledMessageTaskRequest) (*pb.FindEnabledMessageTaskResponse, error) {
_, err := this.ValidateAdmin(ctx, 0) _, err := this.ValidateAdmin(ctx, 0)
if err != nil { if err != nil {