From b07661383a24204f57711edc61f9b9d43866d81d Mon Sep 17 00:00:00 2001 From: zxr <271055687@qq.com> Date: Sat, 18 Jul 2026 09:00:09 +0800 Subject: [PATCH] fix: harden rule and forwarding edge cases --- internal/ingest/alert_forward.go | 7 ++++++- internal/ingest/engine.go | 2 +- internal/logic/controllers/rule_validation.go | 13 +++++++++---- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/internal/ingest/alert_forward.go b/internal/ingest/alert_forward.go index 067fc18..6ffe14d 100644 --- a/internal/ingest/alert_forward.go +++ b/internal/ingest/alert_forward.go @@ -72,7 +72,12 @@ func postAlertPayload(cfg *config.AlertForwardConf, path string, payload []byte) if cfg.InternalKey != "" { req.Header.Set("X-Internal-Key", cfg.InternalKey) } - client := &http.Client{Timeout: 10 * time.Second} + client := &http.Client{ + Timeout: 10 * time.Second, + CheckRedirect: func(_ *http.Request, _ []*http.Request) error { + return http.ErrUseLastResponse + }, + } resp, err := client.Do(req) if err != nil { return fmt.Errorf("发送 Alert 转发请求失败:%w", err) diff --git a/internal/ingest/engine.go b/internal/ingest/engine.go index f3fa7bc..855d97a 100644 --- a/internal/ingest/engine.go +++ b/internal/ingest/engine.go @@ -665,7 +665,7 @@ func trapRuleMatches(rule *models.TrapRule, trapOID, varbindFP string) bool { if hasOID && !strings.HasPrefix(normOID(trapOID), normOID(rule.OIDPrefix)) { return false } - if rule.VarbindMatchRegex != "" { + if hasRE { re, err := regexp.Compile(rule.VarbindMatchRegex) if err != nil { return false diff --git a/internal/logic/controllers/rule_validation.go b/internal/logic/controllers/rule_validation.go index 118e480..db2ff3a 100644 --- a/internal/logic/controllers/rule_validation.go +++ b/internal/logic/controllers/rule_validation.go @@ -25,14 +25,17 @@ func validateSyslogRule(rule *models.SyslogRule) error { } if raw := strings.TrimSpace(rule.SeverityMappingJSON); raw != "" { - var mapping map[string]string + var mapping map[string]any if err := json.Unmarshal([]byte(raw), &mapping); err != nil { return fmt.Errorf("severity_mapping_json 必须是字符串到字符串的 JSON 对象:%v;请修正 severity_mapping_json 后重试", err) } if mapping == nil { return fmt.Errorf("severity_mapping_json 必须是字符串到字符串的 JSON 对象,不能是 null;请改为 JSON 对象后重试") } - for pattern := range mapping { + for pattern, severity := range mapping { + if _, ok := severity.(string); !ok { + return fmt.Errorf("severity_mapping_json 的映射键 %q 对应值必须是字符串;请修正该映射值后重试", pattern) + } if _, err := regexp.Compile(pattern); err != nil { return fmt.Errorf("severity_mapping_json 的映射键 %q 不是有效正则表达式:%v;请修正该映射键后重试", pattern, err) } @@ -49,8 +52,10 @@ func validateSyslogRule(rule *models.SyslogRule) error { } func validateTrapRule(rule *models.TrapRule) error { - if err := validateOptionalRegex("varbind_match_regex", rule.VarbindMatchRegex); err != nil { - return err + if strings.TrimSpace(rule.VarbindMatchRegex) != "" { + if _, err := regexp.Compile(rule.VarbindMatchRegex); err != nil { + return fmt.Errorf("varbind_match_regex 不是有效正则表达式:%v;请修正 varbind_match_regex 后重试", err) + } } if strings.TrimSpace(rule.OIDPrefix) == "" && strings.TrimSpace(rule.VarbindMatchRegex) == "" { return fmt.Errorf("Trap 规则的匹配条件全部为空,运行时永远不会命中;请至少填写 oid_prefix、varbind_match_regex 中的一项")