How to Configure WAF Rules for Web Application Security in Easegress
To configure WAF rules for web application security in Easegress, define a global WAFController object containing rule groups with ModSecurity/Coraza syntax or OWASP CRS bundles, then reference the specific rule group name in a WAF filter within your HTTP pipeline.
Easegress provides a production-grade Web Application Firewall (WAF) implementation that leverages the Coraza engine to inspect HTTP traffic. When you configure WAF rules for web application security in Easegress, you implement a two-tier architecture separating rule definitions from enforcement logic, enabling centralized rule management across multiple pipelines.
Understanding the WAF Architecture in Easegress
The Easegress WAF implementation consists of two core components that work together to inspect and filter malicious traffic.
WAFController: The Global Rule Engine
The WAFController is a singleton object defined in pkg/object/wafcontroller/wafcontroller.go that manages one or more rule groups. Each rule group encapsulates a Coraza engine instance configured with specific security rules. The controller exposes a global handler via GetGlobalWAFController() that pipelines invoke to process requests.
Key responsibilities include:
- Parsing
RuleGroupSpecconfigurations (custom ModSecurity rules, OWASP CRS bundles, IP/Geo blockers, rate limiters) - Building and caching Coraza engines for each rule group
- Exposing the
Handle(ctx, ruleGroupName)method that executes rule evaluation
WAF Filter: Pipeline Integration
The WAF filter (pkg/filters/waf/waf.go) is a pipeline component that bridges HTTP traffic to the global controller. When processing a request, the filter:
- Retrieves the singleton controller via
wafcontroller.GetGlobalWAFController() - Invokes
handler.Handle(ctx, ruleGroupName)using theruleGroupspecified in its configuration - Receives a result (
ok,blocked,ruleGroupNotFoundError, ornoWAFControllerError) - If
blocked, terminates the request with HTTP 500 (or custom action defined in rules)
The filter's result list is dynamically assembled by appending controller results to the filter-specific noWAFControllerError value, as defined in lines 30-55 of waf.go.
Configuring WAF Rules in Easegress
Implementing WAF protection requires creating two YAML objects: a WAFController for rule definitions and a Pipeline containing a WAF filter for enforcement.
Step 1: Define a WAFController with Rule Groups
Create a WAFController object that specifies one or more rule groups. Each group can combine multiple rule sources:
| Rule Source | Description | Configuration Field |
|---|---|---|
| Custom Rules | Inline ModSecurity/Coraza syntax | customRules |
| OWASP CRS Files | Specific CRS rule files | owaspRules |
| Full OWASP CRS | Complete CRS bundle via coraza-coreruleset |
loadOwaspCrs: true |
| IP Blocker | Whitelist/blacklist CIDR blocks | ipBlocker |
| GeoIP Blocker | Country-based filtering (requires MaxMind DB) | geoIPBlocker |
| Rate Limiter | Request throttling rules | rateLimiter |
Step 2: Add the WAF Filter to Your Pipeline
Reference the rule group in a pipeline filter:
filters:
- name: waf
kind: WAF
ruleGroup: <rule-group-name> # Must match name in WAFController
The filter must be positioned before the proxy or backend filters to inspect incoming requests.
Practical WAF Configuration Examples
SQL Injection Protection with OWASP CRS
This configuration loads specific OWASP CRS files to protect against SQL injection attacks:
name: waf-controller
kind: WAFController
ruleGroups:
- name: sql-protection
rules:
owaspRules:
- REQUEST-901-INITIALIZATION.conf
- REQUEST-942-APPLICATION-ATTACK-SQLI.conf
- REQUEST-949-BLOCKING-EVALUATION.conf
name: api-pipeline
kind: Pipeline
filters:
- name: waf-sql
kind: WAF
ruleGroup: sql-protection
- name: backend-proxy
kind: Proxy
pools:
- servers:
- url: http://127.0.0.1:9095
- url: http://127.0.0.1:9096
loadBalance:
policy: roundRobin
The controller initializes a Coraza engine with these three CRS files, and the filter evaluates every request against SQL injection patterns before forwarding to the backend pool.
Full OWASP CRS with Custom Rules
To load the complete OWASP Core Rule Set and append custom ModSecurity rules:
name: waf-controller
kind: WAFController
ruleGroups:
- name: full-crs-custom
rules:
loadOwaspCrs: true
customRules: |
SecRule REQUEST_METHOD "POST" "id:1000001,phase:1,block,log,msg:'Block all POST requests (phase 1)',severity:'CRITICAL'"
SecRule REQUEST_METHOD "POST" "id:1000002,phase:2,block,log,msg:'Block all POST requests (phase 2)',severity:'CRITICAL'"
name: protected-pipeline
kind: Pipeline
filters:
- name: waf
kind: WAF
ruleGroup: full-crs-custom
- name: proxy
kind: Proxy
pools:
- servers:
- url: http://backend:8080
Setting loadOwaspCrs: true pulls the official coraza-coreruleset package, while customRules appends organization-specific policies.
IP and GeoIP Blocking
Restrict access based on source IP ranges or geographic location:
name: waf-controller
kind: WAFController
ruleGroups:
- name: ip-whitelist
rules:
ipBlocker:
whitelist:
- 192.168.1.0/24
- 10.0.0.0/8
- name: geo-restrict
rules:
geoIPBlocker:
dbPath: /opt/geoip/GeoLite2-Country.mmdb
deniedCountries:
- CN
- RU
name: secure-pipeline
kind: Pipeline
filters:
- name: waf-ip
kind: WAF
ruleGroup: ip-whitelist
- name: waf-geo
kind: WAF
ruleGroup: geo-restrict
- name: proxy
kind: Proxy
pools:
- servers:
- url: http://app:80
The geoIPBlocker requires a MaxMind GeoIP2 database file specified in dbPath.
Monitoring WAF Metrics
The WAFController automatically exposes Prometheus metrics for observability. Key metrics include waf_total_refused_requests, which tracks blocked requests per rule group. These metrics are defined in pkg/object/wafcontroller/metrics/metrics.go and scraped from the standard Easegress metrics endpoint.
To monitor rule effectiveness, configure your Prometheus instance to scrape the Easegress instance and create alerts based on the waf_* metric family.
Summary
- Two-tier architecture: Configure WAF rules for web application security in Easegress by creating a global WAFController (rule definitions) and pipeline WAF filters (enforcement).
- Rule group flexibility: Each rule group in
pkg/object/wafcontroller/wafcontroller.gosupports custom ModSecurity rules, OWASP CRS files, full CRS bundles, IP blockers, GeoIP blockers, and rate limiters. - Pipeline integration: The WAF filter in
pkg/filters/waf/waf.goforwards requests to the global controller viaHandle(ctx, ruleGroupName)and returns results (ok,blocked,error) that control request flow. - Observability: Built-in Prometheus metrics in
pkg/object/wafcontroller/metrics/metrics.gotrack refused requests and rule group performance.
Frequently Asked Questions
What rule formats does the Easegress WAF support?
Easegress WAF supports ModSecurity/Coraza syntax through the customRules field, allowing you to write inline SecRule directives. It also natively supports the OWASP Core Rule Set (CRS) via the owaspRules list for specific files or loadOwaspCrs: true for the complete bundle. Additionally, you can configure IP/CIDR blocking and GeoIP country filtering without writing ModSecurity rules.
How do I troubleshoot blocked requests in Easegress WAF?
When the WAF filter blocks a request, it returns the blocked result and sets an HTTP 500 response with a JSON error body containing the rule message, as implemented in setErrResponse within pkg/filters/waf/waf.go. To troubleshoot, check the Easegress logs for Coraza engine output and monitor the waf_total_refused_requests Prometheus metric exposed by pkg/object/wafcontroller/metrics/metrics.go to identify which rule groups are triggering blocks.
Can I use multiple rule groups in a single pipeline?
Yes, you can chain multiple WAF filters in a single pipeline, each referencing a different rule group from the same WAFController. For example, you might place a filter using an ipBlocker rule group first, followed by a filter using an owaspRules group for application-layer attacks. Each filter independently calls wafcontroller.GetGlobalWAFController().Handle() with its specified ruleGroup parameter, allowing you to layer security policies.
What is the performance impact of enabling WAF in Easegress?
The WAF filter introduces minimal overhead because it leverages the high-performance Coraza WAF engine written in Go. The WAFController caches compiled rule engines in memory, so pkg/object/wafcontroller/wafcontroller.go does not re-parse rules on each request. However, complex ModSecurity rules with extensive regex patterns or large OWASP CRS bundles may increase latency slightly; monitor the waf_total_refused_requests and request duration metrics to assess impact in your specific deployment.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →