feat: parse WAF rule logs for rule ID/message/severity
Coraza does not write matched rules to the audit log (known upstream bug). Rule details are logged by Caddy's http.handlers.waf logger. Two changes: 1. caddy.ts: Always configure a dedicated Caddy log sink that writes http.handlers.waf logger output to /logs/waf-rules.log as JSON. 2. waf-log-parser.ts: Before parsing the audit log, read the new waf-rules.log to build a Map<unique_id, RuleInfo>. Each audit log entry joins against this map via transaction.id to populate ruleId, ruleMessage, and severity fields. Skips anomaly evaluation rules (949110/980130) to show the actual detection rule instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+20
-20
@@ -1662,26 +1662,26 @@ async function buildCaddyDocument() {
|
||||
|
||||
const httpApp = Object.keys(servers).length > 0 ? { http: { servers } } : {};
|
||||
|
||||
// Build logging configuration if enabled
|
||||
const loggingApp = loggingEnabled
|
||||
? {
|
||||
logging: {
|
||||
logs: {
|
||||
http_access: {
|
||||
writer: {
|
||||
output: "file",
|
||||
filename: "/logs/access.log",
|
||||
mode: "0640"
|
||||
},
|
||||
encoder: {
|
||||
format: loggingFormat
|
||||
},
|
||||
include: ["http.log.access"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
: {};
|
||||
// Build logging configuration
|
||||
const loggingLogs: Record<string, unknown> = {
|
||||
// Always capture WAF rule match logs so the waf-log-parser can extract rule details.
|
||||
// Coraza does not write matched rules to the audit log (known bug), but it does emit
|
||||
// structured JSON lines via the http.handlers.waf logger for each matched rule.
|
||||
waf_rules: {
|
||||
writer: { output: "file", filename: "/logs/waf-rules.log", mode: "0640" },
|
||||
encoder: { format: "json" },
|
||||
include: ["http.handlers.waf"],
|
||||
level: "ERROR"
|
||||
}
|
||||
};
|
||||
if (loggingEnabled) {
|
||||
loggingLogs.http_access = {
|
||||
writer: { output: "file", filename: "/logs/access.log", mode: "0640" },
|
||||
encoder: { format: loggingFormat },
|
||||
include: ["http.log.access"]
|
||||
};
|
||||
}
|
||||
const loggingApp = { logging: { logs: loggingLogs } };
|
||||
|
||||
return {
|
||||
admin: {
|
||||
|
||||
Reference in New Issue
Block a user