corazawaf / coraza-proxy-wasm

proxy-wasm filter based on Coraza WAF
Apache License 2.0
115 stars 24 forks source link

Performance #262

Open inssein opened 8 months ago

inssein commented 8 months ago

I am trialling this project out to see if its feasible for us, and so far I am running into some fairly large performance related challenges and I want to make sure I am not doing something silly.

When I have a very simple, single rule, I see a negligible performance impact:

SecRuleEngine On
SecRule REQUEST_HEADERS:User-Agent "@contains Fuzz" "id:100,phase:1,deny"

However, when I turn the default core rulesets on, I get almost a 5x hit on performance for our simple routes.

SecRuleEngine On
Include @crs-setup-conf
Include @owasp_crs/*.conf

I noticed I forgot to include either the demo or the recommended settings file first, which I will do next, but starting this thread anyways incase its something else.

inssein commented 8 months ago

To add a little bit more detail, the request looks like:

curl https://redacted-host/anything/performance-test \
  -H "Content-type: application/json" \
  -d '{"type": "MasterCard", "number": "2222630000001125", "name": "Name", "cvv": "118", "ccn": "10/23"}'

The config looks like this:

SecRuleEngine On
Include @demo-conf
Include @crs-setup-conf
Include @owasp_crs/*.conf

When running without the WAF, 50 requests over 5 connections look like:

Percentage of the requests served within a certain time (ms)
  50%    197
  66%    227
  75%    395
  80%    414
  90%    428
  95%    447
  98%    475
  99%    475
 100%    475 (longest request)

When running with the WAF, it looks like:

Percentage of the requests served within a certain time (ms)
  50%   1156
  66%   1158
  75%   1162
  80%   1174
  90%   1197
  95%   1438
  98%   1457
  99%   1457
 100%   1457 (longest request)
jcchavezs commented 8 months ago

Hi @inssein , thanks for coming by.

There are a few things you can try out and see more acurate results.

  1. You can include the coraza recommended conf which sets limits.
  2. You can disable rules with the tag paranoia-level/2, paranoia-level/3 and paranoia-level/4.
  3. Evaluate if request/response body should be inspected.
  4. Tweak the content type you want to inspect for request/response body.

After that you can evaluate the performance hit and we can see what can we improve :).

inssein commented 8 months ago

@jcchavezs thanks for the pointers, will test out a few more things today. What's clear from this mornings testing is that requests with a POST body (json payload) are way slower.

jcchavezs commented 8 months ago

Yes so inspecting a body is expensive so you better do that when needed.

inssein commented 8 months ago

Alright, so my config now looks like:

Include @recommended-conf
Include @crs-setup-conf
Include @owasp_crs/*.conf

SecRequestBodyLimitAction ProcessPartial
SecResponseBodyAccess Off
SecDebugLogLevel 2

SecRuleRemoveByTag paranoia-level/2
SecRuleRemoveByTag paranoia-level/3
SecRuleRemoveByTag paranoia-level/4

The performance is still over 5x worse, just from inspecting a small json request body.

@jcchavezs I hope that is the correct way of disabling rules by tag (SecRuleRemoveByTag), if you meant something else, let me know.

inssein commented 8 months ago

Also, do you know if we have benchmarked this project specifically? I can see that benchmarks exist for Coraza, but I am not sure if we are running up to issues with the wasm layer.

guilinden commented 3 months ago

@inssein Hello, I'm facing the same issues. Did you manage to figure out a way to optimize the performance of Coraza running as a WASM plugin? Or did you use something else as a WAF?

inssein commented 2 months ago

I couldn't get the performance we expected out of it, it's still running but for a very small subset of our requests.