This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
enderbyendera-realtime-prot…/src/main/java/com/realtime/protection/server/alertmessage/AlertMessageService.java
miaohao 97ec7a1279 ft:
动态、静态任务生成指令写入数据库时,根据多局点下发多个指令
2024-09-09 14:54:21 +08:00

404 lines
19 KiB
Java
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.

package com.realtime.protection.server.alertmessage;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.realtime.protection.configuration.entity.alert.AlertMessage;
import com.realtime.protection.configuration.entity.defense.template.ProtectLevel;
import com.realtime.protection.configuration.entity.task.FiveTupleWithMask;
import com.realtime.protection.configuration.entity.task.TaskCommandInfo;
import com.realtime.protection.configuration.utils.Counter;
import com.realtime.protection.configuration.utils.Subnet;
import com.realtime.protection.configuration.utils.enums.StateEnum;
import com.realtime.protection.configuration.utils.enums.TaskTypeEnum;
import com.realtime.protection.server.command.CommandService;
import com.realtime.protection.server.task.TaskService;
import com.realtime.protection.server.task.status.StateHandler;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.net.UnknownHostException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
// AlertMessage的UUID在mapper插入数据库时生成了这里提前生成好像美神恶魔用
@Service
@Slf4j
public class AlertMessageService {
private final CommandService commandService;
private final AlertMessageMapper alertMessageMapper;
private final TaskService taskService;
private final Counter counter;
private final StateHandler stateHandler;
public AlertMessageService(CommandService commandService, AlertMessageMapper alertMessageMapper, TaskService taskService,
Counter counter, StateHandler stateHandler) {
this.commandService = commandService;
this.alertMessageMapper = alertMessageMapper;
this.taskService = taskService;
this.counter = counter;
this.stateHandler = stateHandler;
}
public Boolean updateAuditInfo(String id, String auditInfo) {
return alertMessageMapper.updateAuditInfo(id, auditInfo);
}
@DSTransactional
public void processAlertMessage(AlertMessage alertMessage) {
//将告警信息中的c_time转换为LocalDateTime并写入ctime
Instant instant = Instant.ofEpochSecond(alertMessage.getC_time());
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
alertMessage.setCtime(localDateTime);
//根据告警信息——>生成指令
List<TaskCommandInfo> dynamicTaskCommandInfoList = generateDynamicCommand(alertMessage);
//可能isProtectSrcOrDst和isProtectSrcOrDst都为FALSE说明没有生成指令
if(dynamicTaskCommandInfoList == null || dynamicTaskCommandInfoList.isEmpty()){
return;
}
//获取任务状态设置指令的isValid字段且是否生成指令入库除了RUNING\PAUSED状态其他都不入command库
Integer taskStatus = dynamicTaskCommandInfoList.get(0).getTaskStatus();
//获取任务类型设置指令的isJudged字段。
Integer taskType = dynamicTaskCommandInfoList.get(0).getTaskType();
if (taskType == TaskTypeEnum.DYNAMIC.getTaskType())//实时
switch (StateEnum.getStateEnumByNum(taskStatus)) {
case RUNNING:
insertCommandAndAlertMessage(dynamicTaskCommandInfoList, true, 1, alertMessage);
break;
case RUNNING_FAILED:
insertCommandAndAlertMessage(dynamicTaskCommandInfoList, true, 0, alertMessage);
break;
case RUNNING_PARTIAL_SUCCESS:
insertCommandAndAlertMessage(dynamicTaskCommandInfoList, true, 0, alertMessage);
break;
case RUNNING_SUCCESS:
insertCommandAndAlertMessage(dynamicTaskCommandInfoList, true, 0, alertMessage);
break;
case PAUSED:
insertCommandAndAlertMessage(dynamicTaskCommandInfoList, false, 1, alertMessage);
break;
default://主要是stop
//command不入库
//alertmessage入库
insertAlertMessageOnly(alertMessage);
break;
}
else if (taskType == TaskTypeEnum.JUDGED.getTaskType())//研判后
switch (StateEnum.getStateEnumByNum(taskStatus)) {
case RUNNING :
insertCommandAndAlertMessage(dynamicTaskCommandInfoList, true, 0, alertMessage);
break;
case RUNNING_FAILED:
insertCommandAndAlertMessage(dynamicTaskCommandInfoList, true, 0, alertMessage);
break;
case RUNNING_PARTIAL_SUCCESS:
insertCommandAndAlertMessage(dynamicTaskCommandInfoList, true, 0, alertMessage);
break;
case RUNNING_SUCCESS:
insertCommandAndAlertMessage(dynamicTaskCommandInfoList, true, 0, alertMessage);
break;
case PAUSED:
insertCommandAndAlertMessage(dynamicTaskCommandInfoList, false, 0, alertMessage);
break;
default://主要是stop
//command不入库
//alertmessage入库
insertAlertMessageOnly(alertMessage);
}
}
private List<TaskCommandInfo> generateDynamicCommand(AlertMessage alertMessage){
Long taskId = alertMessage.getTaskId();
Integer DynamicRuleId = alertMessage.getDynamicRuleId();
// 查task信息
// 1查询生成指令所需信息和alertMessage中的fiveTuple信息 合并成 TaskCommandInfo;
// 2额外信息并额外查询templateId、protectLevel和taskStatus
TaskCommandInfo dynamicCommandInfo = alertMessageMapper.getDynamicTaskInfos(taskId, DynamicRuleId);
if (dynamicCommandInfo == null || dynamicCommandInfo.getTemplateId() == null){
throw new IllegalArgumentException("taskId: " + taskId + " DynamicRuleId: " + DynamicRuleId + " 不正确");
}
// 根据templateId、protectLevel获取策略模板
ProtectLevel templateProtectLevel = alertMessageMapper.queryTemplateProtectLevel(
dynamicCommandInfo.getTemplateId(),
dynamicCommandInfo.getProtectLevel());
//根据策略模板和alertMessage中的FiveTupleWithMask生成要下发五元组信息
//根据策略模板的is_full_flow字段如果是双向流量会生成两个fiveTuple所以返回List
List<FiveTupleWithMask> fiveTupleWithMaskNew = updateFiveTupleWithMask(alertMessage.getFiveTupleWithMask(),
alertMessage.getProtectIsSrcOrDst(), templateProtectLevel);
if(fiveTupleWithMaskNew.isEmpty()){
return null;
}
//根据fiveTuple生成动态指令信息
List<TaskCommandInfo> dynamicCommandInfoList = new ArrayList<>();
if (fiveTupleWithMaskNew.size() == 2){
TaskCommandInfo dynamicCommandInfo_bi = new TaskCommandInfo();
dynamicCommandInfo_bi.copyTaskCommandInfo(dynamicCommandInfo);
dynamicCommandInfo_bi.setFiveTupleWithMask(fiveTupleWithMaskNew.get(1));
dynamicCommandInfoList.add(dynamicCommandInfo_bi);
}
dynamicCommandInfo.setFiveTupleWithMask(fiveTupleWithMaskNew.get(0));
dynamicCommandInfoList.add(dynamicCommandInfo);
// //判断局点是否为多个,包含‘,’,多个的话,生成多个指令
// if (dynamicCommandInfo.getDistributePoint().contains(",")){
// List<TaskCommandInfo> dynamicCommandInfoList2 = new ArrayList<>();
// for (TaskCommandInfo dynamicCommandInfo1 : dynamicCommandInfoList){
// String[] distributePoints = dynamicCommandInfo1.getDistributePoint().split(",");
// for (String distributePoint : distributePoints){
// TaskCommandInfo dynamicCommandInfo2 = new TaskCommandInfo();
// dynamicCommandInfo2.copyTaskCommandInfo(dynamicCommandInfo1);
// dynamicCommandInfo2.setDistributePoint(distributePoint);
// dynamicCommandInfoList2.add(dynamicCommandInfo2);
// }
// }
// dynamicCommandInfoList = dynamicCommandInfoList2;
// }
//指令拆分局点拆分后的指令放入staticTaskCommandInfosSplitDistributePoint
List<TaskCommandInfo> dynamicCommandInfoListSplitDistributePoint = new ArrayList<>();
for (TaskCommandInfo taskCommandInfo : dynamicCommandInfoList) {
//判断是否多局点
if (taskCommandInfo.getDistributePoint().contains(",")) {
String[] distributePointArray = taskCommandInfo.getDistributePoint().split(",");
for (String distributePoint : distributePointArray) {
TaskCommandInfo taskCommandInfoSplit = new TaskCommandInfo();
taskCommandInfoSplit.copyTaskCommandInfo(taskCommandInfo);
taskCommandInfoSplit.setDistributePoint(distributePoint);
dynamicCommandInfoListSplitDistributePoint.add(taskCommandInfoSplit);
}
}
else{
dynamicCommandInfoListSplitDistributePoint.add(taskCommandInfo);
}
}
return dynamicCommandInfoListSplitDistributePoint;
}
@DSTransactional
private void insertCommandAndAlertMessage(List<TaskCommandInfo> dynamicTaskCommandInfoList,
Boolean isValid,
Integer isJudged,
AlertMessage alertMessage){
List<String> commandUUIDs = new ArrayList<>();
List<Subnet> subnetList = new ArrayList<>();
//更新任务 影响ip数量字段,因为dynamicTaskCommandInfoList中的指令ip相同所以只取一个指令计算
TaskCommandInfo dynamicTaskCommandInfo0 = dynamicTaskCommandInfoList.get(0);
try {
//抽取告警生成的指令没有掩码
String sip = dynamicTaskCommandInfo0.getFiveTupleWithMask().getSourceIP();
String msip = "255.255.255.255";
String dip = dynamicTaskCommandInfo0.getFiveTupleWithMask().getDestinationIP();
String mdip = "255.255.255.255";
if (sip != null) subnetList.add(new Subnet(sip,msip));
if (dip != null) subnetList.add(new Subnet(dip,mdip));
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
Long ipTotalNum = taskService.ipWithMaskToIpNums(subnetList);
taskService.updateTaskIpTotalNum(ipTotalNum, dynamicTaskCommandInfo0.getTaskId());
for (TaskCommandInfo dynamicTaskCommandInfo : dynamicTaskCommandInfoList ){
//command入库
dynamicTaskCommandInfo.setIsValid(isValid);
dynamicTaskCommandInfo.setIsJudged(isJudged);
String commandUUID = commandService.createCommand2(dynamicTaskCommandInfo, isJudged);
//alertmessage入库
alertMessage.setCommandUUID(commandUUID);
String alertMessageUUID = UUID.randomUUID().toString();
commandUUIDs.add(commandUUID);
alertMessage.setAlertMessageUUID(alertMessageUUID);
alertMessage.setDisplay_id(
"GJ-"
+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))
+ "-"
+ String.format("%06d", counter.generateId("alert_message"))
);
//t_alertMessage表目前唯一键导致覆盖了加个uuid 也存在多次插入问题
alertMessageMapper.insertAlertMessage(alertMessage);
}
}
private String insertAlertMessageOnly(AlertMessage alertMessage){
//alertmessage入库
alertMessage.setCommandUUID(null);
String alertMessageUUID = UUID.randomUUID().toString();
alertMessage.setAlertMessageUUID(alertMessageUUID);
alertMessage.setDisplay_id(
"GJ-"
+ LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))
+ "-"
+ String.format("%06d", counter.generateId("alert_message"))
);
alertMessageMapper.insertAlertMessage(alertMessage);
return alertMessageUUID;
}
private List<FiveTupleWithMask> updateFiveTupleWithMask(FiveTupleWithMask fiveTupleWithMask,
int protectIsSrcOrDst,
ProtectLevel templateProtectLevel) {
//参数是告警信息的FiveTupleWithMask、防护对象是src还是dst、某个安全等级下的安全事件策略模板templateProtectLevel
//首先先从告警信息中获取protectObject和peer
@Data
class CommunicateObject {
private String IP;
private String maskIP;
private String Port;
private String maskPort;
public CommunicateObject(String IP,
String maskIP,
String Port,
String maskPort) {
this.IP = IP;
this.maskIP = maskIP;
this.Port = Port;
this.maskPort = maskPort;
}
}
CommunicateObject protectObject;
CommunicateObject peer;
//0代表命中防护对象在告警信息的源ip
if (protectIsSrcOrDst == 0) {
protectObject = new CommunicateObject(
fiveTupleWithMask.getSourceIP(),
fiveTupleWithMask.getMaskSourceIP(),
fiveTupleWithMask.getSourcePort(),
fiveTupleWithMask.getMaskSourcePort()
);
peer = new CommunicateObject(
fiveTupleWithMask.getDestinationIP(),
fiveTupleWithMask.getMaskDestinationIP(),
fiveTupleWithMask.getDestinationPort(),
fiveTupleWithMask.getMaskDestinationPort()
);
} else {
protectObject = new CommunicateObject(
fiveTupleWithMask.getDestinationIP(),
fiveTupleWithMask.getMaskDestinationIP(),
fiveTupleWithMask.getDestinationPort(),
fiveTupleWithMask.getMaskDestinationPort()
);
peer = new CommunicateObject(
fiveTupleWithMask.getSourceIP(),
fiveTupleWithMask.getMaskSourceIP(),
fiveTupleWithMask.getSourcePort(),
fiveTupleWithMask.getMaskSourcePort()
);
}
//根据模板抽取防护对象和对端需要的字段
if (!templateProtectLevel.getHasProtectObjectIP()) {
protectObject.setIP(null);
protectObject.setMaskIP(null);
}
if (!templateProtectLevel.getHasProtectObjectPort()) {
protectObject.setPort(null);
protectObject.setMaskPort(null);
}
if (!templateProtectLevel.getHasPeerIP()) {
peer.setIP(null);
peer.setMaskIP(null);
}
if (!templateProtectLevel.getHasPeerPort()) {
peer.setPort(null);
peer.setMaskPort(null);
}
List<FiveTupleWithMask> newFiveTupleWithMask = new ArrayList<>();
//生成指令command1防护对象为目的的五元组
FiveTupleWithMask command1 = new FiveTupleWithMask();
command1.setSourceIP(peer.getIP());
command1.setMaskSourceIP(peer.getMaskIP());
command1.setSourcePort(peer.getPort());
command1.setMaskSourcePort(peer.getMaskPort());
command1.setDestinationIP(protectObject.getIP());
command1.setMaskDestinationIP(protectObject.getMaskIP());
command1.setDestinationPort(protectObject.getPort());
command1.setMaskDestinationPort(protectObject.getMaskPort());
if (templateProtectLevel.getHasProtocol()){
command1.setProtocolNum(Integer.valueOf(fiveTupleWithMask.getProtocol()));
command1.setProtocol(fiveTupleWithMask.getProtocol());
command1.setMaskProtocol(fiveTupleWithMask.getMaskProtocol());
}
// newFiveTupleWithMask.add(command1);
//生成指令command2防护对象为源的五元组
FiveTupleWithMask command2 = new FiveTupleWithMask();
command2.setSourceIP(protectObject.getIP());
command2.setMaskSourceIP(protectObject.getMaskIP());
command2.setSourcePort(protectObject.getPort());
command2.setMaskSourcePort(protectObject.getMaskPort());
command2.setDestinationIP(peer.getIP());
command2.setMaskDestinationIP(peer.getMaskIP());
command2.setDestinationPort(peer.getPort());
command2.setMaskDestinationPort(peer.getMaskPort());
if (templateProtectLevel.getHasProtocol()){
command2.setProtocol(fiveTupleWithMask.getProtocol());
command2.setProtocol(fiveTupleWithMask.getProtocol());
command2.setMaskProtocol(fiveTupleWithMask.getMaskProtocol());
}
/*
//若需要处置全方向流量,防护对象为源和目的的五元组都生成指令下发
if(templateProtectLevel.getIsFullFlow()){
newFiveTupleWithMask.add(command1);
newFiveTupleWithMask.add(command2);
}else {
//不需要处置全方向流量
// 判断防护对象为源还是目的,生成指令
if(templateProtectLevel.getIsProtectObjectIPSrc()){
newFiveTupleWithMask.add(command2);
}else {
newFiveTupleWithMask.add(command1);
}
}
*/
//若需要处置全方向流量,防护对象为源和目的的五元组都生成指令下发
// 判断防护对象为源还是目的,生成指令
if(templateProtectLevel.getIsProtectObjectSrc()){
newFiveTupleWithMask.add(command2);
}
if (templateProtectLevel.getIsProtectObjectDst()){
newFiveTupleWithMask.add(command1);
}
//目前告警信息还只是五元组没有url、dns
return newFiveTupleWithMask;
}
public List<AlertMessage> queryAlarmsByCommandId(String commandId) {
return alertMessageMapper.queryAlermsByCommandId(commandId);
}
}