zoraxy-waf/README.md

154 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Firewall
**Zoraxy plugin** — Inline WAF inspection proxy with health checks, circuit breaker, and fail-open bypass. Works with Wallarm, ModSecurity, Coraza, or any inspection service that returns HTTP status codes.
---
## Quick Install
The plugin is built into Zoraxy — just enable it from the Plugins panel. If you need to build from source:
```bash
git clone https://git.lohmar.co.uk/cclohmar/zoraxy-waf.git /opt/zoraxy/plugins/zoraxy-waf
cd /opt/zoraxy/plugins/zoraxy-waf
go build -buildvcs=false -o zoraxy-waf .
chown -R zoraxy:zoraxy /opt/zoraxy/plugins/zoraxy-waf
systemctl restart zoraxy
```
Then enable **Firewall** in Zoraxy → Plugins.
---
## Configuration
Open the Firewall panel at `/plugin.ui/zoraxy-firewall/`:
| Setting | Default | Description |
|---------|---------|-------------|
| **Enable** | Off | Toggle WAF inspection on/off |
| **WAF Inspection URL** | `http://127.0.0.1:8080` | Inspection endpoint — receives `POST /inspect` |
| **Return Port** | `8080` | Port for async WAF callbacks/alerts |
| **Health Interval** | `5s` | How often to ping the WAF |
| **Timeout** | `500ms` | Max wait time for a verdict |
---
## How It Works
```
Client → Zoraxy
┌──────────────────┐
│ Firewall Plugin │──► POST http://waf:8080/inspect
│ (static capture) │ {method, url, headers, body_sample}
└────┬─────────────┘
┌────┴────────────────────────────┐
│ WAF returns 403 │ → 280 (BLOCK) → Request dropped
│ WAF returns 2xx │ → 284 (FORWARD) → Zoraxy routes to backend
│ WAF unreachable / breaker OPEN │ → 284 (FAIL-OPEN)→ Zoraxy routes to backend
└─────────────────────────────────┘
```
### Circuit Breaker
If the WAF fails 5 times within a 30-second window, the breaker opens. All traffic bypasses inspection (fail-open) for 10 seconds. After the cooldown, the next successful health check closes the breaker.
### Health Check
The plugin periodically sends a `HEAD` request to the WAF URL. If the WAF responds with < 500, the circuit breaker records success. If it fails or returns 5xx, it records a failure.
---
## Inspection Protocol
The plugin sends this JSON payload to `{WAF_URL}/inspect`:
```json
{
"method": "GET",
"url": "/some/path",
"host": "example.com",
"remote_addr": "10.1.0.5:12345",
"content_type": "application/json",
"content_length": 256,
"headers": {...},
"body_sample": "<first 4KB of request body>"
}
```
The WAF inspects and returns an HTTP status code:
- **200299** Request is clean, Zoraxy forwards to backend
- **403** Request is malicious, plugin blocks it
- **5xx / timeout** Plugin fails open, records breaker failure
Any WAF that accepts a POST and returns the appropriate status code is compatible. No special Wallarm integration required.
---
## Zoraxy Integration
To activate the plugin for specific proxy rules:
1. Zoraxy Plugins enable **Firewall**
2. Create a plugin group (e.g., "waf") add the Firewall plugin
3. Edit proxy rules add the "waf" tag
The plugin uses Zoraxy's **static capture** to intercept all requests matched by tagged proxy rules.
---
## API Endpoints
| Method | Path | Purpose |
|--------|------|---------|
| `GET` | `/ui/api/config` | Get current configuration |
| `POST` | `/ui/api/config/save` | Save configuration |
| `GET` | `/ui/api/stats` | Inspect/bock/bypass metrics + breaker state |
| `POST` | `/inspect` | Static capture Zoraxy sends traffic here |
| `POST` | `/verdict` | Return port WAF sends async callbacks here |
---
## Architecture
```
/opt/zoraxy/plugins/zoraxy-waf/
├── zoraxy-waf # Compiled plugin binary
├── waf_config.json # Runtime configuration (auto-created)
├── config.go # Config load/save (thread-safe)
├── main.go # Plugin entry, UI router, return listener
├── middleware.go # Inspection handler + metrics
├── proxy.go # WAF HTTP client (body sample + request forwarding)
├── circuit_breaker.go # Fail-open state machine
├── health.go # Background health check goroutine
├── web/ # Config panel UI
│ ├── index.html
│ ├── style.css
│ └── app.js
├── cmd/mockwallarm/ # Test mock WAF server
└── zoraxy_plugin/ # Vendored Zoraxy plugin SDK (LGPL)
```
---
## Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| *none* | | All config is managed through the UI and persisted to `waf_config.json` |
---
## License
Zoraxy plugin SDK is LGPL. This plugin is open source.
---
## Credits
- [Zoraxy](https://github.com/tobychui/zoraxy) Reverse proxy and plugin system
- Compatible with any WAF that returns HTTP verdicts (Wallarm, ModSecurity, Coraza, custom)