corazawaf / coraza-proxy-wasm

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

New metric "Matched Rules" #272

Open matheusmattioli opened 6 months ago

matheusmattioli commented 6 months ago

This PR implements issue #271. As explained in the issue, exporting a metric capable of telling us all rules evaluated by Coraza in blocked transactions is very helpful to troubleshooting the configuration of Coraza.

To implement this idea the config.go, metrics.go, plugin.go and the envoy example (envoy-config.yaml) were modified. The config.go was altered to activate this new metric through envoy configuration: "metric_flags": { "transaction_id": true, "export_matched_rules": true}. With the "export_matched_rules" := true, we enable the new metric and with the "transaction_id" := true, the _transactionid tag will appear in the fields of the metric. Doing this configuration we should see some values as waf_filter_tx_matchedrules{phase="http_request_headers",rule_id="900120",transaction_id="WiYtUsEPrAweKUjiwWP",identifier="global",owner="coraza"} 1 under the prometheus stats in localhost port 8082.

In this pull request there is a fix too. In the envoy-config.yaml the regex field of the "tag_name" phase was printing strange values in metrics, from README we have:

curl -s localhost:8082/stats/prometheus | grep waf_filter
# TYPE waf_filter_tx_interruptions counter
waf_filter_tx_interruptions{phase="http_request_headers_identifier",rule_id="101",identifier="global",owner="coraza"} 1
waf_filter_tx_interruptions{phase="http_request_body_identifier",rule_id="102",identifier="global",owner="coraza"} 1
waf_filter_tx_interruptions{phase="http_response_headers_identifier",rule_id="103",identifier="global",owner="coraza"} 1
waf_filter_tx_interruptions{phase="http_response_body_identifier",rule_id="104",identifier="global",owner="coraza"} 1
waf_filter_tx_interruptions{phase="http_request_body_identifier",rule_id="949110",identifier="global",owner="coraza"} 1
waf_filter_tx_interruptions{phase="http_response_headers_identifier",rule_id="949110",identifier="global",owner="coraza"} 1
waf_filter_tx_interruptions{phase="http_request_headers_identifier",rule_id="949111",identifier="global",owner="coraza"} 1
# TYPE waf_filter_tx_total counter
waf_filter_tx_total{} 11

Highlighting the phase tag in, for example, "waf_filter_tx_interruptions{phase="http_request_headers_identifier",rule_id="101",identifier="global",owner="coraza"} 1", we got http_request_headers_identifier, but it should be printing only http_request_headers without the _identifier. So the fix approach another way to do a regex to capture the http phases, now, it is logging just "http_request_headers" (or "http_request_body", etc.).

I'm open to feedback, reviews, improvements or other ways to implement this idea. Thank you!

matheusmattioli commented 5 months ago

Hi, could anyone check this please?

jcchavezs commented 5 months ago

Replied in the issue