BareProxy Rate Limiting and WAF Plugin: Per-Address Limits and Bad-Request Rules at the Edge
Status: planned, number 8 of 21 in BareProxy’s build order. The plugins are built easiest first, and this one is about a day of coding: counters in shared data and simple rules. It comes after the A/B and canary splits plugin. This post describes what it will do, and it will be updated as it is built.
Two of the oldest reasons to put a proxy in front of an app are to stop one client from taking all of it, and to turn away requests that are obviously up to no good before the app has to look at them. Most small apps handle neither. A login form that takes a thousand guesses a minute, or a search endpoint hammered by a script, can take a site down long before anyone notices an attack.
What It Will Do
Limits. A limit counts requests per client address, per path prefix or per site, over a window, and answers 429 Too Many Requests past it, with a Retry-After header. Limits are counted across all of the plugin’s instances, so they hold however BareProxy spreads the load. A typical setup gives the whole site a generous limit and the login path a tight one.
Basic WAF rules. Simple checks that catch most of the junk:
- methods a site never uses
- headers and query strings over a size
- paths no real visitor asks for, such as
/wp-login.phpon a site that isn’t WordPress, or/.env - known scanners by user agent
The rules follow BareProxy’s own design rule: exact values, prefixes and sets, no regular expressions. That keeps every rule readable, and it keeps a rule from becoming the next security bug. A full WAF with thousands of signatures is a different product; this plugin covers the part a small site actually needs.
A config will look something like this:
plugin limits /etc/bareproxy/plugins/rate-limit-waf.wasm
config /etc/bareproxy/plugins/limits.json
on-error open
site example.com
use limits
route /* -> app
Seeing What It Did
Turning traffic away is only safe when you can see why. Every request the plugin answers carries a note in its record: which limit or rule matched, the count, the window. why on a 429 will say which limit the client hit and when the window resets. A rule that blocks a real visitor shows up in the records the same day, not after a week of support mail.
This plugin replaces the “Limit” module of BareProxy’s earlier plan, which would have been compiled into the binary. As a plugin, it is installed by one config line and removed by deleting it.
The whole program is on the plugins page.