WAF

The waf block configures Zentinel’s Web Application Firewall (WAF) settings. WAF protection is implemented via external agents, but this block provides global WAF configuration including engine selection, rule sets, and body inspection policies.

Basic Configuration

waf {
    engine "coraza"
    mode "prevention"
    audit-log #true

    ruleset {
        custom-rules-dir "/etc/zentinel/waf/crs"
        paranoia-level 2
    }

    body-inspection {
        inspect-request-body #true
        max-inspection-bytes 1048576
    }
}

Engine Selection

Zentinel supports multiple WAF engines via external agents:

waf {
    engine "coraza"  // Default, recommended
}
EngineDescription
corazaModern, Go-based WAF engine (default)
modsecuritylibModSecurity-based engine
customCustom engine implementation

Custom Engine

For custom WAF implementations:

waf {
    engine "my-custom-waf"
}

The engine name is passed to your WAF agent, which can use it to select the appropriate implementation.

WAF Mode

Control how the WAF handles detected threats:

waf {
    mode "prevention"  // Block malicious requests
}
ModeBehavior
offWAF disabled
detectionLog threats but allow requests through
preventionBlock malicious requests (default)

Detection Mode

Use detection mode when first deploying WAF to assess impact:

waf {
    mode "detection"
    audit-log #true  // Log all detections
}

Review audit logs to tune rules before switching to prevention mode.

Audit Logging

Enable detailed logging of WAF decisions:

waf {
    audit-log #true
}

Audit logs include:

  • Matched rules and their IDs
  • Request details (headers, body excerpts)
  • Decision (allow/block)
  • Tags and scores

Logs are written in JSON format to the configured log output.

Rule Set Configuration

Basic Ruleset

waf {
    ruleset {
        custom-rules-dir "/etc/zentinel/waf/crs"
        paranoia-level 1
    }
}

CRS Version and Custom Rules

Configure the Core Rule Set version and custom rules directory:

waf {
    ruleset {
        crs-version "3.3.4"
        custom-rules-dir "/etc/zentinel/waf/custom-rules"
        paranoia-level 2
    }
}

Paranoia Level

The paranoia level controls rule sensitivity:

waf {
    ruleset {
        paranoia-level 2
    }
}
LevelDescriptionUse Case
1Basic protection, minimal false positivesProduction, general traffic
2Standard protectionMost applications
3Strict protection, more false positivesHigh-security applications
4Maximum protection, highest false positivesMaximum security environments

Recommendation: Start with level 1 or 2, then increase based on your false positive tolerance.

Rule Exclusions

Exclude specific rules to reduce false positives:

waf {
    ruleset {
        custom-rules-dir "/etc/zentinel/waf/crs"
        paranoia-level 2

        // Exclude by rule ID (global scope)
        exclusion "942100" "942200" scope="global"

        // Exclude for specific paths
        exclusion "941100" scope="path=/api/upload"

        // Exclude for specific hosts
        exclusion "920350" scope="host=internal.example.com"
    }
}

Exclusion Scopes

ScopeDescription
globalExclude rule everywhere
path=<pattern>Exclude for a specific URL path
host=<hostname>Exclude for a specific host

Body Inspection

Configure how request and response bodies are inspected:

waf {
    body-inspection {
        inspect-request-body #true
        inspect-response-body #false
        max-inspection-bytes 1048576
        content-types {
            "application/json"
            "application/x-www-form-urlencoded"
            "text/xml"
        }
        decompress #true
        max-decompression-ratio 100
    }
}

Body Inspection Options

OptionDefaultDescription
inspect-request-bodytrueInspect request bodies
inspect-response-bodyfalseInspect response bodies
max-inspection-bytes1048576Maximum bytes to buffer for inspection
content-typesSee belowContent types eligible for inspection
decompressfalseDecompress bodies before inspection
max-decompression-ratio100Max compression ratio (zip bomb protection)

Default Content Types

When not specified, these content types are inspected:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • application/json
  • application/xml
  • text/xml

Decompression Security

When decompress is enabled:

waf {
    body-inspection {
        decompress #true
        max-decompression-ratio 50  // Reject if compressed/decompressed ratio > 50x
    }
}

This protects against zip bomb attacks by limiting the decompression ratio.

Complete Example

waf {
    engine "coraza"
    mode "prevention"
    audit-log #true

    ruleset {
        crs-version "3.3.4"
        custom-rules-dir "/etc/zentinel/waf/custom-rules"
        paranoia-level 2
        anomaly-threshold 5

        // API endpoints that accept raw data
        exclusion "942100" "942200" "942260" scope="path=/api/webhooks"

        // Large file upload endpoint
        exclusion "920350" scope="path=/api/upload"
    }

    body-inspection {
        inspect-request-body #true
        inspect-response-body #false
        max-inspection-bytes 5242880
        content-types {
            "application/json"
            "application/xml"
            "multipart/form-data"
        }
        decompress #true
        max-decompression-ratio 100
    }
}

Integration with Agents

The waf block configures global settings. To actually process requests through WAF, configure a WAF agent:

waf {
    engine "coraza"
    mode "prevention"
    ruleset {
        crs-version "3.3.4"
        paranoia-level 2
    }
}

agents {
    agent "waf-agent" type="waf" {
        unix-socket "/var/run/zentinel/waf.sock"
        events "request_headers" "request_body"
        timeout-ms 200
        failure-mode "closed"
    }
}

routes {
    route "api" {
        matches { path-prefix "/api/" }
        upstream "backend"
        agents "waf-agent"
    }
}

The WAF configuration is passed to the agent on startup. The agent uses these settings to configure its rule engine.

Metrics

WAF operations are tracked via Prometheus metrics:

MetricLabelsDescription
zentinel_waf_requests_totalmode, decisionTotal WAF evaluations
zentinel_waf_blocked_totalrule_idBlocked requests by rule
zentinel_waf_detection_totalrule_idDetections (all modes)
zentinel_waf_latency_secondsWAF evaluation latency

Default Values

SettingDefault
enginecoraza
modeprevention
audit-logtrue
ruleset.crs-version3.3.4
ruleset.paranoia-level1
ruleset.anomaly-threshold5
body-inspection.inspect-request-bodytrue
body-inspection.max-inspection-bytes1048576
body-inspection.decompressfalse
body-inspection.max-decompression-ratio100

See Also