2024-01-12 18:42:21 +08:00
|
|
|
|
package com.zdjizhi.function;
|
2021-07-29 10:02:31 +08:00
|
|
|
|
|
2022-10-17 18:15:11 +08:00
|
|
|
|
import cn.hutool.log.Log;
|
|
|
|
|
|
import cn.hutool.log.LogFactory;
|
2023-11-13 16:45:04 +08:00
|
|
|
|
import com.geedgenetworks.utils.DateUtils;
|
|
|
|
|
|
import com.geedgenetworks.utils.StringUtil;
|
2021-10-21 18:27:48 +08:00
|
|
|
|
import com.zdjizhi.common.*;
|
2024-01-12 18:42:21 +08:00
|
|
|
|
import com.zdjizhi.utils.Snowflakeld.SnowflakeId;
|
|
|
|
|
|
import com.zdjizhi.utils.Threshold.ParseBaselineThreshold;
|
|
|
|
|
|
import com.zdjizhi.utils.Threshold.ParseStaticThreshold;
|
|
|
|
|
|
import com.zdjizhi.utils.connections.http.HttpClientService;
|
|
|
|
|
|
import com.zdjizhi.utils.knowledgebase.IpLookupUtils;
|
2021-08-20 18:34:40 +08:00
|
|
|
|
import inet.ipaddr.IPAddress;
|
|
|
|
|
|
import inet.ipaddr.IPAddressString;
|
2022-12-06 17:13:09 +08:00
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
2021-07-29 10:02:31 +08:00
|
|
|
|
import org.apache.flink.configuration.Configuration;
|
2021-08-20 18:34:40 +08:00
|
|
|
|
import org.apache.flink.shaded.guava18.com.google.common.collect.TreeRangeMap;
|
2023-11-13 16:45:04 +08:00
|
|
|
|
import org.apache.flink.streaming.api.functions.ProcessFunction;
|
2022-09-23 18:37:33 +08:00
|
|
|
|
import org.apache.flink.util.Collector;
|
2021-07-29 10:02:31 +08:00
|
|
|
|
|
2021-08-26 18:42:28 +08:00
|
|
|
|
import java.math.BigDecimal;
|
2021-07-29 10:02:31 +08:00
|
|
|
|
import java.text.NumberFormat;
|
2021-08-05 18:42:34 +08:00
|
|
|
|
import java.util.*;
|
2024-01-12 18:42:21 +08:00
|
|
|
|
|
|
|
|
|
|
import static com.zdjizhi.conf.DosConfigs.*;
|
2021-07-29 10:02:31 +08:00
|
|
|
|
|
2021-08-16 18:24:13 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @author wlh
|
|
|
|
|
|
*/
|
2024-01-12 18:42:21 +08:00
|
|
|
|
public class DosDetectionFunction extends ProcessFunction<DosSketchLog, DosEventLog> {
|
2022-10-17 18:15:11 +08:00
|
|
|
|
private static final Log logger = LogFactory.get();
|
2024-01-12 18:42:21 +08:00
|
|
|
|
private Map<String, Map<String, DosBaselineThreshold>> baselineMap = new HashMap<>();
|
|
|
|
|
|
private final NumberFormat PERCENT_INSTANCE = NumberFormat.getPercentInstance();
|
2023-11-13 16:45:04 +08:00
|
|
|
|
private HashMap<Integer, HashMap<String, TreeRangeMap<IPAddress, DosDetectionThreshold>>> thresholdRangeMap;
|
2024-01-12 18:42:21 +08:00
|
|
|
|
private final int BASELINE_SIZE = 144;
|
|
|
|
|
|
private final int STATIC_CONDITION_TYPE = 1;
|
|
|
|
|
|
private final int BASELINE_CONDITION_TYPE = 2;
|
|
|
|
|
|
private final int SENSITIVITY_CONDITION_TYPE = 3;
|
|
|
|
|
|
private final String SESSIONS_TAG = "sessions";
|
|
|
|
|
|
private final String PACKETS_TAG = "packets";
|
|
|
|
|
|
private final String BITS_TAG = "bits";
|
|
|
|
|
|
private final int OTHER_BASELINE_TYPE = 3;
|
|
|
|
|
|
private SnowflakeId snowflakeId;
|
|
|
|
|
|
private Configuration configuration;
|
|
|
|
|
|
private HttpClientService httpClientService;
|
|
|
|
|
|
private IpLookupUtils ipLookupUtils;
|
|
|
|
|
|
private ParseBaselineThreshold parseBaselineThresholdld;
|
|
|
|
|
|
private ParseStaticThreshold parseStaticThreshold;
|
2021-07-29 10:02:31 +08:00
|
|
|
|
|
2024-01-12 18:42:21 +08:00
|
|
|
|
@Override
|
|
|
|
|
|
public void open(Configuration parameters) {
|
2021-10-21 18:27:48 +08:00
|
|
|
|
|
2024-01-12 18:42:21 +08:00
|
|
|
|
configuration = (Configuration) getRuntimeContext()
|
|
|
|
|
|
.getExecutionConfig().getGlobalJobParameters();
|
|
|
|
|
|
httpClientService = new HttpClientService(configuration);
|
2021-12-08 13:51:09 +08:00
|
|
|
|
|
2024-01-12 18:42:21 +08:00
|
|
|
|
snowflakeId = new SnowflakeId(configuration.get(DATA_CENTER_ID_NUM), getRuntimeContext().getIndexOfThisSubtask());
|
2021-10-29 18:43:05 +08:00
|
|
|
|
|
2024-01-12 18:42:21 +08:00
|
|
|
|
try {
|
|
|
|
|
|
ipLookupUtils = new IpLookupUtils(configuration, httpClientService);
|
|
|
|
|
|
ipLookupUtils.stuffKnowledgeMetaCache();
|
|
|
|
|
|
Timer timer = new Timer();
|
|
|
|
|
|
timer.schedule(new TimerTask() {
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void run() {
|
|
|
|
|
|
ipLookupUtils.stuffKnowledgeMetaCache();
|
|
|
|
|
|
logger.info("定位库定时调度成功");
|
|
|
|
|
|
}
|
|
|
|
|
|
}, configuration.get(KNOWLEDGE_BASE_SCHEDULE_MINUTES) * 60 * 1000, configuration.get(KNOWLEDGE_BASE_SCHEDULE_MINUTES) * 60 * 1000);
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
logger.error("定位库加载失败,具体原因为" + e);
|
|
|
|
|
|
}
|
2023-11-13 16:45:04 +08:00
|
|
|
|
|
2024-01-12 18:42:21 +08:00
|
|
|
|
try {
|
|
|
|
|
|
parseStaticThreshold = new ParseStaticThreshold(configuration, httpClientService);
|
|
|
|
|
|
thresholdRangeMap = parseStaticThreshold.createStaticThreshold();
|
|
|
|
|
|
Timer timer = new Timer();
|
|
|
|
|
|
timer.schedule(new TimerTask() {
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void run() {
|
|
|
|
|
|
thresholdRangeMap = parseStaticThreshold.createStaticThreshold();
|
|
|
|
|
|
logger.info("基于静态阈值构建threshold RangeMap成功,Threshold RangeMap:" + thresholdRangeMap.toString());
|
|
|
|
|
|
}
|
|
|
|
|
|
}, configuration.get(STATIC_THRESHOLD_SCHEDULE_MINUTES) * 60 * 1000, configuration.get(STATIC_THRESHOLD_SCHEDULE_MINUTES) * 60 * 1000);
|
2023-11-13 16:45:04 +08:00
|
|
|
|
|
2024-01-12 18:42:21 +08:00
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
logger.error("基于静态阈值构建threshold RangeMap失败,失败原因为:" + e);
|
|
|
|
|
|
}
|
2023-11-13 16:45:04 +08:00
|
|
|
|
|
2021-08-24 16:35:31 +08:00
|
|
|
|
try {
|
2024-01-12 18:42:21 +08:00
|
|
|
|
parseBaselineThresholdld = new ParseBaselineThreshold(configuration);
|
|
|
|
|
|
baselineMap = parseBaselineThresholdld.readFromHbase();
|
|
|
|
|
|
Timer timer = new Timer();
|
|
|
|
|
|
timer.schedule(new TimerTask() {
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public void run() {
|
|
|
|
|
|
baselineMap = parseBaselineThresholdld.readFromHbase();
|
|
|
|
|
|
logger.info("从Hbase获取baselineMap成功,baselineMap:" + thresholdRangeMap.toString());
|
|
|
|
|
|
}
|
|
|
|
|
|
}, configuration.get(BASELINE_THRESHOLD_SCHEDULE_DAYS) * 24 * 60 * 60 * 1000, configuration.get(BASELINE_THRESHOLD_SCHEDULE_DAYS) * 24 * 60 * 60 * 1000);
|
2021-08-24 16:35:31 +08:00
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
2024-01-12 18:42:21 +08:00
|
|
|
|
logger.error("从Hbase获取baselineMap失败,失败原因为:" + e);
|
2021-08-24 16:35:31 +08:00
|
|
|
|
}
|
2024-01-12 18:42:21 +08:00
|
|
|
|
|
2021-07-30 10:55:01 +08:00
|
|
|
|
PERCENT_INSTANCE.setMinimumFractionDigits(2);
|
2021-07-29 10:02:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
2023-11-13 16:45:04 +08:00
|
|
|
|
public void processElement(DosSketchLog value, Context ctx, Collector<DosEventLog> out) throws Exception {
|
2022-12-21 17:11:14 +08:00
|
|
|
|
DosEventLog finalResult = null;
|
2021-07-30 10:55:01 +08:00
|
|
|
|
try {
|
|
|
|
|
|
String destinationIp = value.getDestination_ip();
|
2022-09-23 18:37:33 +08:00
|
|
|
|
int vsysId = value.getVsys_id();
|
|
|
|
|
|
String key = destinationIp + "-" + vsysId;
|
2021-07-30 10:55:01 +08:00
|
|
|
|
String attackType = value.getAttack_type();
|
2021-08-20 18:34:40 +08:00
|
|
|
|
IPAddress destinationIpAddress = new IPAddressString(destinationIp).getAddress();
|
2022-09-23 18:37:33 +08:00
|
|
|
|
|
|
|
|
|
|
DosDetectionThreshold threshold = null;
|
2023-11-13 16:45:04 +08:00
|
|
|
|
if (thresholdRangeMap.containsKey(vsysId)) {
|
2022-09-23 18:37:33 +08:00
|
|
|
|
threshold = thresholdRangeMap.get(vsysId).getOrDefault(attackType, TreeRangeMap.create()).get(destinationIpAddress);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
logger.debug("当前判断IP:{}, 类型: {}", key, attackType);
|
|
|
|
|
|
if (threshold == null && baselineMap.containsKey(key)) {
|
2023-11-13 16:45:04 +08:00
|
|
|
|
finalResult = getDosEventLogByBaseline(value, key);
|
2022-09-23 18:37:33 +08:00
|
|
|
|
} else if (threshold == null && !baselineMap.containsKey(key)) {
|
2022-12-21 17:11:14 +08:00
|
|
|
|
finalResult = getDosEventLogBySensitivityThreshold(value);
|
2021-10-20 18:23:12 +08:00
|
|
|
|
} else if (threshold != null) {
|
2022-12-21 17:11:14 +08:00
|
|
|
|
finalResult = getDosEventLogByStaticThreshold(value, threshold);
|
2021-10-19 18:39:13 +08:00
|
|
|
|
} else {
|
2022-09-23 18:37:33 +08:00
|
|
|
|
logger.debug("未获取到当前server IP:{} 类型 {} 静态阈值 和 baseline", key, attackType);
|
2021-07-29 10:02:31 +08:00
|
|
|
|
}
|
2021-08-24 16:35:31 +08:00
|
|
|
|
|
2021-08-18 19:15:49 +08:00
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
logger.error("判定失败\n {} \n{}", value, e);
|
2021-07-29 10:02:31 +08:00
|
|
|
|
}
|
2023-11-13 16:45:04 +08:00
|
|
|
|
if (finalResult != null) {
|
2022-12-21 17:11:14 +08:00
|
|
|
|
out.collect(finalResult);
|
2022-09-23 18:37:33 +08:00
|
|
|
|
}
|
2021-08-20 18:34:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-12-06 19:11:30 +08:00
|
|
|
|
|
2021-10-19 18:39:13 +08:00
|
|
|
|
private DosEventLog getDosEventLogBySensitivityThreshold(DosSketchLog value) {
|
2021-09-14 18:46:23 +08:00
|
|
|
|
long sketchSessions = value.getSketch_sessions();
|
2024-01-12 18:42:21 +08:00
|
|
|
|
Integer staticSensitivityThreshold = configuration.get(STATIC_SENSITIVITY_THRESHOLD);
|
2022-12-06 17:13:09 +08:00
|
|
|
|
long diff = sketchSessions - staticSensitivityThreshold;
|
2023-11-13 16:45:04 +08:00
|
|
|
|
return getDosEventLog(value, staticSensitivityThreshold, diff, 0, SENSITIVITY_CONDITION_TYPE, SESSIONS_TAG);
|
2021-08-20 18:34:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-13 16:45:04 +08:00
|
|
|
|
private DosEventLog getDosEventLogByBaseline(DosSketchLog value, String key) {
|
2021-09-23 18:36:27 +08:00
|
|
|
|
String attackType = value.getAttack_type();
|
2021-09-09 10:46:50 +08:00
|
|
|
|
long sketchSessions = value.getSketch_sessions();
|
2022-12-06 17:13:09 +08:00
|
|
|
|
DosBaselineThreshold dosBaselineThreshold = baselineMap.get(key).get(attackType);
|
|
|
|
|
|
Integer base = getBaseValue(dosBaselineThreshold, value);
|
|
|
|
|
|
long diff = sketchSessions - base;
|
2023-11-13 16:45:04 +08:00
|
|
|
|
return getDosEventLog(value, base, diff, 0, BASELINE_CONDITION_TYPE, SESSIONS_TAG);
|
2021-08-20 18:34:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-12-21 17:11:14 +08:00
|
|
|
|
private DosEventLog getDosEventLogByStaticThreshold(DosSketchLog value, DosDetectionThreshold threshold) throws CloneNotSupportedException {
|
2023-11-13 16:45:04 +08:00
|
|
|
|
long sessionBase = threshold.getSessions_per_sec();
|
|
|
|
|
|
long pktBase = threshold.getPackets_per_sec();
|
|
|
|
|
|
long bitBase = threshold.getBits_per_sec();
|
2023-05-26 15:44:37 +08:00
|
|
|
|
|
|
|
|
|
|
long diffSession = value.getSketch_sessions() - sessionBase;
|
|
|
|
|
|
long diffPkt = value.getSketch_packets() - pktBase;
|
|
|
|
|
|
long diffByte = value.getSketch_bytes() - bitBase;
|
|
|
|
|
|
|
2023-11-13 16:45:04 +08:00
|
|
|
|
double diffSessionPercent = 0.0;
|
|
|
|
|
|
double diffPktPercent = 0.0;
|
|
|
|
|
|
double diffBitPercent = 0.0;
|
2024-01-12 18:42:21 +08:00
|
|
|
|
|
2023-11-13 16:45:04 +08:00
|
|
|
|
if (sessionBase > 0) {
|
|
|
|
|
|
diffSessionPercent = getDiffPercent(diffSession, sessionBase) * 100;
|
2023-09-07 18:20:02 +08:00
|
|
|
|
}
|
2023-11-13 16:45:04 +08:00
|
|
|
|
if (pktBase > 0) {
|
|
|
|
|
|
diffPktPercent = getDiffPercent(diffPkt, pktBase) * 100;
|
2023-09-07 18:20:02 +08:00
|
|
|
|
}
|
2023-11-13 16:45:04 +08:00
|
|
|
|
if (bitBase > 0) {
|
|
|
|
|
|
diffBitPercent = getDiffPercent(diffByte, bitBase) * 100;
|
2023-09-07 18:20:02 +08:00
|
|
|
|
}
|
2023-05-26 15:44:37 +08:00
|
|
|
|
|
2023-05-24 14:36:29 +08:00
|
|
|
|
long profileId = 0;
|
2023-11-13 16:45:04 +08:00
|
|
|
|
DosEventLog result = null;
|
|
|
|
|
|
|
|
|
|
|
|
if (diffSessionPercent >= diffPktPercent && diffSessionPercent >= diffBitPercent) {
|
2024-02-28 16:58:15 +08:00
|
|
|
|
profileId = threshold.getId();
|
2023-11-13 16:45:04 +08:00
|
|
|
|
result = getDosEventLog(value, sessionBase, diffSession, profileId, STATIC_CONDITION_TYPE, SESSIONS_TAG);
|
|
|
|
|
|
} else if (diffPktPercent >= diffSessionPercent && diffPktPercent >= diffBitPercent) {
|
2024-02-28 16:58:15 +08:00
|
|
|
|
profileId = threshold.getId();
|
2023-11-13 16:45:04 +08:00
|
|
|
|
result = getDosEventLog(value, pktBase, diffPkt, profileId, STATIC_CONDITION_TYPE, PACKETS_TAG);
|
|
|
|
|
|
} else if (diffBitPercent >= diffPktPercent && diffBitPercent >= diffSessionPercent) {
|
2024-02-28 16:58:15 +08:00
|
|
|
|
profileId = threshold.getId();
|
2023-05-26 15:44:37 +08:00
|
|
|
|
result = getDosEventLog(value, bitBase, diffByte, profileId, STATIC_CONDITION_TYPE, BITS_TAG);
|
2021-08-20 18:34:40 +08:00
|
|
|
|
}
|
2022-12-21 17:11:14 +08:00
|
|
|
|
return result;
|
2021-08-20 18:34:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-04-03 17:35:36 +08:00
|
|
|
|
private DosEventLog getDosEventLog(DosSketchLog value, long base, long diff, long profileId, int type, String tag) {
|
2021-08-20 18:34:40 +08:00
|
|
|
|
DosEventLog result = null;
|
|
|
|
|
|
String destinationIp = value.getDestination_ip();
|
|
|
|
|
|
String attackType = value.getAttack_type();
|
|
|
|
|
|
if (diff > 0 && base != 0) {
|
2021-08-26 18:42:28 +08:00
|
|
|
|
double percent = getDiffPercent(diff, base);
|
2021-09-14 18:46:23 +08:00
|
|
|
|
Severity severity = judgeSeverity(percent);
|
2024-01-12 18:42:21 +08:00
|
|
|
|
Integer staticSensitivityThreshold = configuration.get(STATIC_SENSITIVITY_THRESHOLD);
|
2021-08-20 18:34:40 +08:00
|
|
|
|
if (severity != Severity.NORMAL) {
|
2024-01-12 18:42:21 +08:00
|
|
|
|
if (type == BASELINE_CONDITION_TYPE && percent < configuration.get(BASELINE_SENSITIVITY_THRESHOLD)) {
|
2021-10-19 18:39:13 +08:00
|
|
|
|
logger.debug("当前server IP:{},类型:{},基线值{}百分比{}未超过基线敏感阈值,日志详情\n{}", destinationIp, attackType, base, percent, value);
|
2023-11-13 16:45:04 +08:00
|
|
|
|
} else if ((type == BASELINE_CONDITION_TYPE || type == SENSITIVITY_CONDITION_TYPE) && value.getSketch_sessions() < staticSensitivityThreshold) {
|
|
|
|
|
|
logger.debug("当前server IP:{},类型:{},基线值{}百分比{}未超过静态敏感阈值,日志详情\n{}", destinationIp, attackType, base, percent, value);
|
|
|
|
|
|
} else {
|
2023-06-27 17:31:56 +08:00
|
|
|
|
result = getResult(value, base, profileId, severity, percent, type, tag);
|
2023-11-13 16:45:04 +08:00
|
|
|
|
if (type == SENSITIVITY_CONDITION_TYPE) {
|
2022-12-06 17:13:09 +08:00
|
|
|
|
result.setSeverity(Severity.MAJOR.severity);
|
|
|
|
|
|
}
|
2023-11-13 16:45:04 +08:00
|
|
|
|
logger.info("检测到当前server IP {} 存在 {} 异常,超出基线{} {}倍,基于{}:{}检测,日志详情\n {}", destinationIp, attackType, base, percent, type, tag, result);
|
2021-09-16 18:47:00 +08:00
|
|
|
|
}
|
2021-08-20 18:34:40 +08:00
|
|
|
|
} else {
|
2021-09-16 18:47:00 +08:00
|
|
|
|
logger.debug("当前server IP:{} 未出现 {} 异常,日志详情 {}", destinationIp, attackType, value);
|
2021-08-20 18:34:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2021-09-14 18:46:23 +08:00
|
|
|
|
return result;
|
2021-07-29 10:02:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-04-03 17:35:36 +08:00
|
|
|
|
private DosEventLog getResult(DosSketchLog value, long base, long profileId, Severity severity, double percent, int type, String tag) {
|
2021-07-29 10:02:31 +08:00
|
|
|
|
DosEventLog dosEventLog = new DosEventLog();
|
2023-12-11 09:50:28 +08:00
|
|
|
|
dosEventLog.setRecv_time(value.getCommon_recv_time());
|
2024-01-12 18:42:21 +08:00
|
|
|
|
dosEventLog.setLog_id(snowflakeId.nextId());
|
2022-09-23 18:37:33 +08:00
|
|
|
|
dosEventLog.setVsys_id(value.getVsys_id());
|
2021-07-29 10:02:31 +08:00
|
|
|
|
dosEventLog.setStart_time(value.getSketch_start_time());
|
2021-09-26 18:41:36 +08:00
|
|
|
|
dosEventLog.setEnd_time(value.getSketch_start_time() + value.getSketch_duration());
|
2023-04-03 17:35:36 +08:00
|
|
|
|
dosEventLog.setProfile_id(profileId);
|
2021-07-29 10:02:31 +08:00
|
|
|
|
dosEventLog.setAttack_type(value.getAttack_type());
|
2021-08-24 16:35:31 +08:00
|
|
|
|
dosEventLog.setSeverity(severity.severity);
|
2023-11-13 16:45:04 +08:00
|
|
|
|
dosEventLog.setConditions(getConditions(PERCENT_INSTANCE.format(percent), base, value.getSketch_sessions(), type, tag, dosEventLog));
|
2021-07-29 10:02:31 +08:00
|
|
|
|
dosEventLog.setDestination_ip(value.getDestination_ip());
|
2024-01-12 18:42:21 +08:00
|
|
|
|
dosEventLog.setDestination_country(ipLookupUtils.getCountryLookup(value.getDestination_ip()));
|
2021-07-29 10:02:31 +08:00
|
|
|
|
String ipList = value.getSource_ip();
|
|
|
|
|
|
dosEventLog.setSource_ip_list(ipList);
|
|
|
|
|
|
dosEventLog.setSource_country_list(getSourceCountryList(ipList));
|
|
|
|
|
|
dosEventLog.setSession_rate(value.getSketch_sessions());
|
|
|
|
|
|
dosEventLog.setPacket_rate(value.getSketch_packets());
|
|
|
|
|
|
dosEventLog.setBit_rate(value.getSketch_bytes());
|
|
|
|
|
|
return dosEventLog;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-10-21 18:27:48 +08:00
|
|
|
|
private Integer getBaseValue(DosBaselineThreshold dosBaselineThreshold, DosSketchLog value) {
|
2021-08-18 19:15:49 +08:00
|
|
|
|
Integer base = 0;
|
2021-08-17 18:56:53 +08:00
|
|
|
|
try {
|
2021-10-21 18:27:48 +08:00
|
|
|
|
if (dosBaselineThreshold != null) {
|
|
|
|
|
|
ArrayList<Integer> baselines = dosBaselineThreshold.getSession_rate();
|
|
|
|
|
|
Integer defaultVaule = dosBaselineThreshold.getSession_rate_default_value();
|
2021-10-29 18:43:05 +08:00
|
|
|
|
Integer sessionRateBaselineType = dosBaselineThreshold.getSession_rate_baseline_type();
|
2021-08-18 19:15:49 +08:00
|
|
|
|
if (baselines != null && baselines.size() == BASELINE_SIZE) {
|
|
|
|
|
|
int timeIndex = getCurrentTimeIndex(value.getSketch_start_time());
|
|
|
|
|
|
base = baselines.get(timeIndex);
|
|
|
|
|
|
if (base == 0) {
|
|
|
|
|
|
logger.debug("获取到当前IP: {},类型: {} baseline值为0,替换为P95观测值{}", value.getDestination_ip(), value.getAttack_type(), defaultVaule);
|
|
|
|
|
|
base = defaultVaule;
|
|
|
|
|
|
}
|
2024-01-12 18:42:21 +08:00
|
|
|
|
if (sessionRateBaselineType == OTHER_BASELINE_TYPE && base < configuration.get(STATIC_SENSITIVITY_THRESHOLD)) {
|
|
|
|
|
|
base = configuration.get(STATIC_SENSITIVITY_THRESHOLD);
|
2021-10-29 18:43:05 +08:00
|
|
|
|
}
|
2021-08-18 19:15:49 +08:00
|
|
|
|
}
|
2021-08-17 18:56:53 +08:00
|
|
|
|
}
|
2021-08-18 19:15:49 +08:00
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
logger.error("解析baseline数据失败,返回默认值0", e);
|
2021-08-17 18:56:53 +08:00
|
|
|
|
}
|
2021-08-18 19:15:49 +08:00
|
|
|
|
return base;
|
2021-08-17 18:56:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-13 16:45:04 +08:00
|
|
|
|
private String getConditions(String percent, long base, long sessions, int type, String tag, DosEventLog dosEventLog) {
|
|
|
|
|
|
int condition = 0;
|
|
|
|
|
|
if ("Minor".equals(dosEventLog.getSeverity())) {
|
|
|
|
|
|
condition = 50;
|
|
|
|
|
|
} else if ("Warning".equals(dosEventLog.getSeverity())) {
|
|
|
|
|
|
condition = 100;
|
|
|
|
|
|
} else if ("Major".equals(dosEventLog.getSeverity())) {
|
|
|
|
|
|
condition = 250;
|
|
|
|
|
|
} else if ("Severe".equals(dosEventLog.getSeverity())) {
|
|
|
|
|
|
condition = 500;
|
|
|
|
|
|
} else if ("Critical".equals(dosEventLog.getSeverity())) {
|
|
|
|
|
|
condition = 800;
|
2023-05-24 14:36:29 +08:00
|
|
|
|
}
|
2021-10-19 18:39:13 +08:00
|
|
|
|
switch (type) {
|
2021-10-21 18:27:48 +08:00
|
|
|
|
case STATIC_CONDITION_TYPE:
|
2022-12-06 17:13:09 +08:00
|
|
|
|
return "Rate > " +
|
|
|
|
|
|
base + " " +
|
2023-11-13 16:45:04 +08:00
|
|
|
|
tag + "/s" + "(>" + condition + "%)";
|
2021-10-21 18:27:48 +08:00
|
|
|
|
case BASELINE_CONDITION_TYPE:
|
2022-12-06 17:13:09 +08:00
|
|
|
|
return tag + " > " +
|
2023-05-26 15:44:37 +08:00
|
|
|
|
percent + " of baseline";
|
2021-10-21 18:27:48 +08:00
|
|
|
|
case SENSITIVITY_CONDITION_TYPE:
|
2022-12-06 17:13:09 +08:00
|
|
|
|
return String.valueOf(sessions) + " " +
|
|
|
|
|
|
tag + "/s Unusually high " +
|
|
|
|
|
|
StringUtils.capitalize(tag);
|
2021-08-24 16:35:31 +08:00
|
|
|
|
default:
|
2021-10-21 18:27:48 +08:00
|
|
|
|
throw new IllegalArgumentException("Illegal Argument type:" + type + ", known types = [1,2,3]");
|
2021-08-24 16:35:31 +08:00
|
|
|
|
}
|
2021-07-29 10:02:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-08-18 19:15:49 +08:00
|
|
|
|
private String getSourceCountryList(String sourceIpList) {
|
2021-10-19 18:39:13 +08:00
|
|
|
|
if (StringUtil.isNotBlank(sourceIpList)) {
|
|
|
|
|
|
String countryList;
|
|
|
|
|
|
try {
|
|
|
|
|
|
String[] ipArr = sourceIpList.split(",");
|
|
|
|
|
|
HashSet<String> countrySet = new HashSet<>();
|
|
|
|
|
|
for (String ip : ipArr) {
|
2024-01-12 18:42:21 +08:00
|
|
|
|
String country = ipLookupUtils.getCountryLookup(ip);
|
2023-11-13 16:45:04 +08:00
|
|
|
|
if (StringUtil.isNotBlank(country)) {
|
2021-12-08 13:51:09 +08:00
|
|
|
|
countrySet.add(country);
|
|
|
|
|
|
}
|
2021-10-19 18:39:13 +08:00
|
|
|
|
}
|
2021-12-08 13:51:09 +08:00
|
|
|
|
countryList = StringUtils.join(countrySet, ", ");
|
2021-10-19 18:39:13 +08:00
|
|
|
|
return countryList;
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
logger.error("{} source IP lists 获取国家失败", sourceIpList, e);
|
|
|
|
|
|
return StringUtil.EMPTY;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
throw new IllegalArgumentException("Illegal Argument sourceIpList = null");
|
2021-07-29 10:02:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-08-18 19:15:49 +08:00
|
|
|
|
private int getCurrentTimeIndex(long sketchStartTime) {
|
2021-10-19 18:39:13 +08:00
|
|
|
|
int index = 0;
|
|
|
|
|
|
try {
|
|
|
|
|
|
long currentDayTime = DateUtils.getTimeFloor(new Date(sketchStartTime * 1000L), "P1D").getTime() / 1000;
|
|
|
|
|
|
long indexLong = (sketchStartTime - currentDayTime) / (86400 / BASELINE_SIZE);
|
|
|
|
|
|
index = Integer.parseInt(Long.toString(indexLong));
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
logger.error("获取time index失败", e);
|
|
|
|
|
|
}
|
|
|
|
|
|
return index;
|
2021-07-29 10:02:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-12-08 13:51:09 +08:00
|
|
|
|
|
2021-08-26 18:42:28 +08:00
|
|
|
|
private Double getDiffPercent(long diff, long base) {
|
2023-09-07 18:20:02 +08:00
|
|
|
|
try {
|
|
|
|
|
|
return BigDecimal.valueOf((float) diff / base).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();
|
2023-11-13 16:45:04 +08:00
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
logger.info("当前阈值为0,进行下一阈值条件判断", e);
|
2023-09-07 18:20:02 +08:00
|
|
|
|
return 0.0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-07-29 10:02:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-08-18 19:15:49 +08:00
|
|
|
|
private Severity judgeSeverity(double diffPercent) {
|
2024-01-12 18:42:21 +08:00
|
|
|
|
if (diffPercent >= configuration.get(BASELINE_SESSIONS_MINOR_THRESHOLD) && diffPercent < configuration.get(BASELINE_SESSIONS_WARNING_THRESHOLD)) {
|
2021-07-29 10:02:31 +08:00
|
|
|
|
return Severity.MINOR;
|
2024-01-12 18:42:21 +08:00
|
|
|
|
} else if (diffPercent >= configuration.get(BASELINE_SESSIONS_WARNING_THRESHOLD) && diffPercent < configuration.get(BASELINE_SESSIONS_MAJOR_THRESHOLD)) {
|
2021-07-29 10:02:31 +08:00
|
|
|
|
return Severity.WARNING;
|
2024-01-12 18:42:21 +08:00
|
|
|
|
} else if (diffPercent >= configuration.get(BASELINE_SESSIONS_MAJOR_THRESHOLD) && diffPercent < configuration.get(BASELINE_SESSIONS_SEVERE_THRESHOLD)) {
|
2021-07-29 10:02:31 +08:00
|
|
|
|
return Severity.MAJOR;
|
2024-01-12 18:42:21 +08:00
|
|
|
|
} else if (diffPercent >= configuration.get(BASELINE_SESSIONS_SEVERE_THRESHOLD) && diffPercent < configuration.get(BASELINE_SESSIONS_CRITICAL_THRESHOLD)) {
|
2021-07-29 10:02:31 +08:00
|
|
|
|
return Severity.SEVERE;
|
2024-01-12 18:42:21 +08:00
|
|
|
|
} else if (diffPercent >= configuration.get(BASELINE_SESSIONS_CRITICAL_THRESHOLD)) {
|
2021-07-29 10:02:31 +08:00
|
|
|
|
return Severity.CRITICAL;
|
2021-08-18 19:15:49 +08:00
|
|
|
|
} else {
|
2021-07-29 10:02:31 +08:00
|
|
|
|
return Severity.NORMAL;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private enum Severity {
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 判断严重程度枚举类型
|
|
|
|
|
|
*/
|
2021-10-21 18:27:48 +08:00
|
|
|
|
CRITICAL("Critical"),
|
|
|
|
|
|
SEVERE("Severe"),
|
|
|
|
|
|
MAJOR("Major"),
|
|
|
|
|
|
WARNING("Warning"),
|
|
|
|
|
|
MINOR("Minor"),
|
|
|
|
|
|
NORMAL("Normal");
|
2021-07-29 10:02:31 +08:00
|
|
|
|
|
|
|
|
|
|
private final String severity;
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
public String toString() {
|
|
|
|
|
|
return this.severity;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-10-21 18:27:48 +08:00
|
|
|
|
Severity(String severity) {
|
2021-07-29 10:02:31 +08:00
|
|
|
|
this.severity = severity;
|
2021-09-14 18:46:23 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-07-29 10:02:31 +08:00
|
|
|
|
}
|