-
Notifications
You must be signed in to change notification settings - Fork 297
Add variables to hold processing times for modsecurity phases #278
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add variable for logging time and add examples how to use it to README
src/ngx_http_modsecurity_rewrite.c
Outdated
@liudongmiao
liudongmiao
Apr 13, 2022
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest use ngx_timeofday
like request_time
or upstream_xxx_time
in upstream module.
@liudongmiao
liudongmiao
Apr 13, 2022
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or ngx_current_msec
.
@liudongmiao
liudongmiao
Apr 13, 2022
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, ngx_current_msec is cached. just use ngx_gettimeofday
@liudongmiao
liudongmiao
Apr 13, 2022
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to use clock_gettime with CLOCK_MONOTONIC for ns.
For waf performance, I'd like to implement as this (in nginx module):
- when modsecurity context / transaction is created, record it as
modsec_request_start_time
- when
ngx_http_modsecurity_process_intervention
is finished, update it asmodsec_request_end_time
- Calc
modsec_request_end_time - modsec_start_time
asmodsec_request_time
.
For response, it's hard to implement, as there may be multi upstream (refer upstream_response_time
in upstream module: http://nginx.org/en/docs/http/ngx_http_upstream_module.html#var_upstream_response_time). However, I have commented out the response headers / body handlers, and have no modsec rules in phase 3 / 4.
For modsec rules performance, I'd like to implement it in modsecurity.
liudongmiao
commented
Apr 13, 2022
@awmackowiak Could you help to review #273 and #277?
Have you guys tried the performance instrumentation? The perf. instrumentation seems to have all the information that you guys are trying to collect.
https://github.com/SpiderLabs/ModSecurity-nginx/blob/master/ngx-modsec.stp
That is the output -
image
Alternatively you can the have the function level chart -
That is an interactive SVG, like this one -
https://www.brendangregg.com/FlameGraphs/cpu-mysql-updated.svg
Also, you can compare ModSecurity execution times outside nginx, by using the command line utilities -
https://github.com/SpiderLabs/ModSecurity/tree/v3/master/test
All that without having to patch a single line from ModSecurity.
Patching ModSecurity to support some sort of performance indicators was discussed here - owasp-modsecurity/ModSecurity#1011
liudongmiao
commented
Apr 13, 2022
@zimmerle We'd like to record waf time in log...just as request_time and upstream_response_time...
src/ngx_http_modsecurity_module.c
Outdated
@liudongmiao
liudongmiao
Apr 15, 2022
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ngx_http_null_variable is introduced in 1.13.4, expand it to support old nginx. nginx/nginx@b992f72
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I change it for old style.
src/ngx_http_modsecurity_module.c
Outdated
@liudongmiao
liudongmiao
Apr 15, 2022
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add NGX_HTTP_VAR_NOHASH?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes you are right. I added it.
src/ngx_http_modsecurity_module.c
Outdated
@liudongmiao
liudongmiao
Apr 15, 2022
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use a same function with different argument, like 0, 1, 2, ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you provide an example what are you mean for that?
I didn't find example for variables with indexed arguments.
@liudongmiao
liudongmiao
May 16, 2022
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refer https://github.com/nginx/nginx/blob/release-1.21.6/src/http/ngx_http_upstream.c#L391-L401
Same function ngx_http_upstream_response_time_variable
for 3 variables.
@liudongmiao
liudongmiao
Apr 15, 2022
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove blank line
Fix after review
@liudongmiao I made fixes as you suggests.
ziollek
commented
Apr 1, 2023
@liudongmiao could you review it again?
liudongmiao
commented
Apr 3, 2023
@ziollek These codes are ok.
However, we use another solution, calc the total modsec time, named it as "msc_request_time" and "msc_engine_time".
- msc_request_time: the time cost between the beginning and complete
- msc_engine_time: the time cost by modsecurity engine, sum all steps
And in production, msc_request_time is same as msc_engine_time for GET request, for large POST, msc_request_time is greater than msc_engine_time.
@liudongmiao thanks for reply. Could you point out where these variables are described? Are they exposed as a nginx variables?
I would like to give you some insights what need states behind this change.
We implemented those changes because we encountered a hard to diagnose performance issue (connected with this PR: owasp-modsecurity/ModSecurity#2601). In order to increase WAF observability we want to measure libmodsecurity overhead. The simplest (from our point of view) solution seems to be an adding such overhead of each request to nginx log (and later build appropriate metrics based on nginx log).
liudongmiao
commented
Apr 7, 2023
@ziollek Yes, we have the same problem. We export it to nginx variables, and update the nginx log format.
In our production, we add three variables: msc_request_time / msc_engine_time / msc_rules_messages.
I have explained the msc_request_time and msc_engine_time.
In our production, the average msc_engine_time is about 1ms, and 95% is less than 5ms, which is acceptable by our team.
Have you guys tried the performance instrumentation? The perf. instrumentation seems to have all the information that you guys are trying to collect.
https://github.com/SpiderLabs/ModSecurity-nginx/blob/master/ngx-modsec.stp
@zimmerle Thanks for pointing out this tool, I was not aware of that. Lately, I had some spare time and I tried to profile using it, and I have some thoughts about it. First of all, it is really cumbersome using systemtap
in a containerized environment (and currently it is quite common that such workload is run for example in k8s). Secondly, the script provided within the plugin is outdated, it tries tracking calls that no longer exist in libmodsecurity.so
And finally, I think that there is some misunderstanding of the purpose of such changes. We do not want to provide another way of profiling ModSecurity
. We wanted to increase observability. Internally in our company, we have defined metrics based on times reported by introduced new variables. Our WAF ecosystem based partially on ModSecurity
is complex and configuration is changed very often. Thanks to measuring the overhead of each component by such kinds of metrics we have insights that allow very fast tracing down the root cause of performance problems.
Quality Gate Passed Quality Gate passed
Issues
0 New issues
0 Accepted issues
Measures
0 Security Hotspots
No data about Coverage
No data about Duplication
Uh oh!
There was an error while loading. Please reload this page.
Format Variables
ModSecurity-nginx provide times variables for particular phases that you can uses in nginx log_format:
The following example show how to configure custom log_format with variables above and use them with custom access.log: