1. Overview
rpGUARD (Reverse Proxy GUARD) is a security-first reverse proxy. It sits in front of your web servers: incoming requests hit rpGUARD, which inspects and filters them, then relays them to the backend servers and returns the response to the client. It plays the same role as nginx, HAProxy or a mini-Cloudflare.
Reverse proxy (rpGUARD): protects and balances inbound traffic to your servers. Not to be confused with a forward proxy, which goes out to the Internet on behalf of a client.
The engine runs in-process (Kestrel): no external binary. Everything is driven from the window. rpGUARD is a self-contained .NET rewrite of the Aenebris engine and reads a compatible YAML configuration file.
Features
- Load balancing (weighted round-robin) and backend health checks
- WAF: SQL injection, XSS, path traversal, RFI, scanner user-agents, custom regexes
- Rate limiting (token bucket) global and per-path
- DDoS protection: max connections per IP, automatic jailing, memory shed
- Geo / CIDR filtering (allow / deny lists)
- Honeypot (block / tarpit / labyrinth)
- JA4H fingerprint and ML anomaly scoring
- HTTP/1.1, HTTP/2 and WebSocket; TLS via PEM certificates
2. Installation
Option A - Using the installer
Run rpGUARD-Setup-x.y.z.exe and follow the wizard. The app installs to
C:\Program Files\rpGUARD. See section 8 to build this installer.
Option B - Build from source
- Open
rpGUARD.csprojin Visual Studio (targetnet10.0-windows, WPF). - Restore packages (YamlDotNet), then build / run.
Build tip: after an interrupted dotnet run, purge bin and
obj, then run dotnet build again.
3. First run
On launch a splash screen shows, then the main window. rpGUARD reads config.yaml next to the
executable; if missing, a default configuration is created (listener 8080, one backend
127.0.0.1:8000, a / route).
To start the proxy: Start button, top right. The pill turns green (Running). Stop stops the engine. The FR / EN button switches language.
4. The interface
Dashboard
Live view: engine state, uptime, requests/s, total, forwarded, blocked; health of each backend (green/red dot, active connections, served, failures) and a breakdown of blocks by reason.
Listeners / TLS
Listening ports. Per row: the Port, TLS toggle with the Certificate and Key paths (PEM), and the Redirect to HTTPS option. Add / Remove buttons, then Save.
Upstreams
Master-detail. On the left, backend groups (name). On the right, the servers of the
selected group (host:port and weight), plus the health-check path
and interval. Weight drives load balancing (weight 3 receives about three times more traffic
than weight 1).
Routes
Master-detail. On the left, hosts (e.g. localhost, or * for any
host). On the right, the paths: Path (prefix, e.g. /api),
target Upstream and an optional per-path rate limit (e.g. 20/second).
The most specific path wins; / acts as fallback.
Security
| Block | Settings |
|---|---|
| Global rate limit | Applied to all traffic (e.g. 100/minute). Empty = disabled. |
| WAF | Enabled; mode block or log; SQLi, XSS, traversal, RFI, scanner checkboxes; custom regexes in the YAML. |
| DDoS | Early-data reject; max connections per IP; memory shed (bytes); jail cooldown. After repeated hostile signals, the IP is temporarily jailed. |
| Honeypot | Enabled; action block, tarpit (slow response) or labyrinth (fake maze of links). |
| Geo / CIDR | Allow / deny ranges (one per line, e.g. 203.0.113.0/24). An explicit allow beats a deny. |
ML detection
Enables an anomaly scorer (URL length, special-char ratio, entropy, parameter count, missing user-agent,
uncommon method...). Set the threshold (0 to 1) and the mode
(log or block). This is a self-contained baseline, with no external model.
Logs
Live event stream, colored by level (info, warning, block, error). Clear button. The last 500 lines are kept.
About
Version, description, feature list, developer and a link to m365expertise.
5. The pipeline
Each request goes through the stages in this order; the first that rejects stops the request:
6. TLS / certificates
On a TLS listener, provide the paths to the certificate and key in PEM format. rpGUARD
loads the pair and serves it directly (no netsh binding required). For a local test, a
self-signed certificate is enough.
# Example self-signed test certificate (OpenSSL) openssl req -x509 -newkey rsa:2048 -nodes -keyout server.key -out server.crt -days 365 -subj "/CN=localhost"
7. Configuration file
Aenebris-compatible YAML (snake_case keys), read/written in config.yaml. A
commented template is provided: config.sample.yaml.
version: 1
listen:
- port: 8080
- port: 8443
tls:
cert: certs/server.crt
key: certs/server.key
rate_limit: "100/minute"
ddos:
per_ip_connections: 100
memory_shed_bytes: 1073741824
jail_cooldown_seconds: 300
waf:
enabled: true
mode: block
sqli: true
xss: true
upstreams:
- name: default-backend
servers:
- host: "127.0.0.1:8000"
weight: 3
- host: "127.0.0.1:8001"
weight: 1
health_check:
path: /health
interval: 10s
routes:
- host: localhost
paths:
- path: /api
upstream: default-backend
rate_limit: "20/second"
- path: /
upstream: default-backend
8. Building the installer
Two scripts at the project root, plus the Inno Setup script:
| File | Role |
|---|---|
publish.ps1 | Publishes the app to .\publish (self-contained win-x64 by default). |
rpGUARD.iss | Inno Setup script that packages .\publish into an installer. |
build-installer.ps1 | Runs the publish then compiles the Setup (reads the version from the csproj). |
Prerequisites
- .NET SDK 10 (
dotnet) - Inno Setup 6 (
ISCC.exe): jrsoftware.org/isdl.php
Command
# From the project root .\build-installer.ps1 # Variant without embedded runtime (requires .NET 10 Desktop + ASP.NET Core on the target) .\build-installer.ps1 -SelfContained:$false
The Setup is generated in installer-output\rpGUARD-Setup-<version>.exe. The version is
the single source <Version> from rpGUARD.csproj.
9. Troubleshooting
| Symptom | Hint |
|---|---|
| Proxy won't start (port in use) | Another service already listens on the port; change the listener port or free it. |
| 503 "no-healthy-backends" | No backend server answers the health probe; check host:port and the health path. |
| 502 "bad-gateway" | The backend refuses the connection; verify it listens over HTTP on the given host/port. |
| Certificate error on TLS start | Invalid PEM paths or mismatched cert/key pair. |
| Legitimate traffic blocked by WAF | Switch the WAF to log mode to observe, then tune the rules. |
| ISCC.exe not found | Install Inno Setup 6 or add it to PATH. |