Web Application Firewall (WAF)¶
The WAF inspects requests to a website with ModSecurity + the OWASP Core Rule Set (CRS) and blocks known attack patterns (SQL injection, XSS, path traversal, remote code execution) at the Nginx layer, before they ever reach the application. It is opt-in per website — enabling it on one site has zero effect on any other site, even on the same server.
How it works¶
- An admin — or, with the right package permission, the customer — enables the WAF for a website.
- The agent makes sure ModSecurity + OWASP CRS are installed on the target server, then adds two includes to the site's Nginx vhost: the global, enconf-curated rule base, and a per-site config file for the paranoia level, rule exclusions, and detection-only mode.
- Every request to the website is evaluated against the CRS rules. A match returns
403and is logged to the audit log — unless detection-only mode is active, in which case it is only logged.
Our own, curated rule wiring
enconf does not rely on the Debian package's default wiring (owasp-crs.load) — it uses directives the Nginx ModSecurity module doesn't support, which can break nginx -t outright. Instead, the agent writes its own, verified inclusion of the CRS rules and explicitly forces SecRuleEngine On (the Debian package ships a log-only mode by default that never blocks anything).
Enabling the WAF for a website¶
As an administrator¶
- Go to Sites and open the website you want to protect
- Under Performance & Security, toggle WAF (ModSecurity) on
- Save — the agent installs ModSecurity automatically if needed and re-renders the vhost
An Install ModSecurity button is also available under System → WAF to provision the packages on a server ahead of time, without enabling any site.
As a customer¶
Customers whose package grants the WAF permission see the toggle in the site-edit dialog and a WAF entry in the sidebar.
Permission
The WAF is gated per package by the WAF permission (perm_waf). The maximum selectable paranoia level is also capped per package (Max WAF paranoia level, default 1) — administrators are not subject to this cap.
Paranoia level¶
OWASP CRS defines four paranoia levels. A higher level catches more attack classes but also raises the risk of false positives on unusual-but-legitimate traffic:
| Level | Recommendation |
|---|---|
| 1 (default) | Suitable for most sites — lowest false-positive risk |
| 2–3 | For sites with higher protection needs, after a short test period in detection-only mode |
| 4 | Maximum detection, noticeably higher false-positive risk — only with careful monitoring |
Detection-only mode¶
Before switching to a higher paranoia level, or right after first enabling the WAF, detection-only mode is recommended: matches are logged but not blocked. This lets you check the log for legitimate traffic that would have been falsely blocked before actually enforcing.
Rule exclusions¶
If a single CRS rule produces a false positive (e.g. for an application with an unusual input format), its rule ID can be excluded for the affected website specifically, without disabling the rest of the protection. The rule ID of a match is shown in the Rule ID column of the log.
Attack log¶
The Log tab shows every event ModSecurity evaluated: timestamp, client IP, requested URI, rule ID, message text, and severity. Administrators can filter by site or domain; customers only ever see events for their own websites.
Limitations¶
- The WAF protects against known attack patterns at the request level. It does not replace application updates, strong passwords, or the malware scanner, which detects code already planted in the filesystem.
- A broken custom exclusion rule is validated with
nginx -tbefore being applied — if validation fails, the previous, working configuration stays active instead of taking the server down.