ModSecurity icon indicating copy to clipboard operation
ModSecurity copied to clipboard

ModSecurity v2.9.12 “Skipping request since there is nowhere to write to” despite valid SecAuditLog configuration

Open tinhutins opened this issue 4 months ago • 8 comments

Hi,

On Amazon Linux 2023 (AArch64) using ModSecurity v2.9.12 with Apache 2.4.65, audit logs fail to write even with valid configuration and writable path. Debug logs report:

[15/Oct/2025:13:55:40.259888 +0200] [10.104.19.109/sid#aaaae39e0938][rid#ffff18026b80][/health/status][4] Audit log: Logging this transaction. [15/Oct/2025:13:55:40.259892 +0200] [10.104.19.109/sid#aaaae39e0938][rid#ffff18026b80][/health/status][4] Audit log: Skipping request since there is nowhere to write to.

Environment:

OS: Amazon Linux 2023 (latest patched)

Architecture: aarch64

Apache version: httpd 2.4.65-1.amzn2023.0.1

ModSecurity version: 2.9.12-1.amzn2023.0.1

SELinux: disabled

Config (minimal reproduction):

<IfModule security2_module>
  SecRuleEngine On
  SecRequestBodyAccess On
  SecResponseBodyAccess Off
  SecDebugLog /var/log/httpd/modsec_debug_test.log
  SecDebugLogLevel 5
  SecAuditEngine On
  SecAuditLogRelevantStatus ".*"
  SecAuditLogType Serial
  SecAuditLog /var/log/httpd/modsec_audit_test.log
  SecRule ARGS:testparam "@streq attack" "id:1,phase:2,deny,log,auditlog,msg:action_detected,ctl:debugLogLevel=9"
</IfModule>

Apache reports Syntax OK

Steps to Reproduce:

Install httpd + mod_security on Amazon Linux 2023.

Apply minimal config above.

Restart httpd and send any request.

Observe debug log.

Expected Result: Audit log file (SecAuditLog) should receive entries.

Actual Result: Log is skipped with nowhere to write to even though the file exists and is writable.

Additional Notes:

No SELinux denials or permission errors.

tinhutins avatar Oct 15 '25 12:10 tinhutins

Hi @tinhutins,

thanks for sending this report.

Before that message, have you seen any similar one like this?

Audit log: Failed writing (requested ...

airween avatar Oct 15 '25 12:10 airween

Hi @airween

thanks for the quick reply.

We haven’t seen any log entry like:

Audit log: Failed writing (requested ...)

in the modsec_debug.log.

Here’s the full relevant config:

 SecResponseBodyAccess Off
    SecDebugLog /var/log/httpd/modsec_debug.log
    SecDebugLogLevel 5
    #SecDebugLogLevel 9
    SecAuditEngine On
   # SecAuditEngine RelevantOnly 
    SecAuditLogRelevantStatus ".*"
    #SecAuditLogRelevantStatus "^(?:4(?!04|05|00))"
    SecAuditLogParts ABIJDEFHZ
    SecAuditLogType Serial
    SecAuditLog /var/log/httpd/modsec_audit.log
    SecArgumentSeparator &
    SecCookieFormat 0
    SecTmpDir /var/lib/mod_security
    SecDataDir /var/lib/mod_security

The situation is:

modsec_debug.log works fine — it gets populated with debug information.

modsec_audit.log is created automatically when missing, but it always stays empty, no matter what configuration or permissions we try (Serial, Concurrent, different statuses, permissions even 777, etc.).

Permissions and ownership on /var/log/httpd and /var/lib/mod_security seems correct (apache:apache, 700).

So in short: debug logging works, but audit logging never writes anything, even though the audit file itself is created on restart.

Full log for one transaction :


[16/Oct/2025:07:44:21.547070 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Initialising transaction (txid aPCGNYBNFofHNCUXPKq7TwAAAAQ).
[16/Oct/2025:07:44:21.547124 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Transaction context created (dcfg aaab00bd7430).
[16/Oct/2025:07:44:21.547129 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Processing disabled, skipping (hook request_early).
[16/Oct/2025:07:44:21.547248 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Processing disabled, skipping (hook request_late).
[16/Oct/2025:07:44:21.547314 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Hook insert_filter: Processing disabled, skipping.
[16/Oct/2025:07:44:21.556688 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Initialising logging.
[16/Oct/2025:07:44:21.556733 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Starting phase LOGGING.
[16/Oct/2025:07:44:21.556743 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Recording persistent data took 0 microseconds.
[16/Oct/2025:07:44:21.556747 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Audit log: Logging this transaction.
[16/Oct/2025:07:44:21.556752 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Audit log: Skipping request since there is nowhere to write to.

Do you have any hints on what could prevent audit events from actually being written in this situation?

tinhutins avatar Oct 16 '25 05:10 tinhutins

We haven’t seen any log entry like:

Audit log: Failed writing (requested ...)

in the modsec_debug.log.

sorry, I forget: in the error.log?

The situation is:

modsec_debug.log works fine — it gets populated with debug information.

modsec_audit.log is created automatically when missing, but it always stays empty, no matter what configuration or permissions we try (Serial, Concurrent, different statuses, permissions even 777, etc.).

Permissions and ownership on /var/log/httpd and /var/lib/mod_security seems correct (apache:apache, 700).

So in short: debug logging works, but audit logging never writes anything, even though the audit file itself is created on restart.

Full log for one transaction :

...

Do you have any hints on what could prevent audit events from actually being written in this situation?

Actually, I don't. Yesterday I checked the code, and (as I remember) there can be two situations:

  • the module can't open the file at startup, and the FD (file descriptor) will be NULL; this does not fit, because you wrote that the file is created when it's missing
  • the module opened the audit.log successfully, but can't write; then it closes and set the FD to NULL

Unfortunately I can't check this with your setup, because I don't have any aarch64 arch machine. If there is any chance to get a login for that machine, I could try to investigate the issue there.

airween avatar Oct 16 '25 05:10 airween

Hi @airween

Nothing similar shows up in error.log either — here’s what we get on startup:

[Thu Oct 16 07:48:25.730768 2025] [security2:notice] [pid 122656:tid 122656] ModSecurity for Apache/2.9.12 (http://www.modsecurity.org/) configured.
[Thu Oct 16 07:48:25.730779 2025] [security2:notice] [pid 122656:tid 122656] ModSecurity: APR compiled version="1.7.5"; loaded version="1.7.5"
[Thu Oct 16 07:48:25.730783 2025] [security2:notice] [pid 122656:tid 122656] ModSecurity: PCRE2 compiled version="10.40 "; loaded version="10.40 2022-04-14"
[Thu Oct 16 07:48:25.730786 2025] [security2:notice] [pid 122656:tid 122656] ModSecurity: LUA compiled version="Lua 5.4"
[Thu Oct 16 07:48:25.730789 2025] [security2:notice] [pid 122656:tid 122656] ModSecurity: YAJL compiled version="2.1.0"
[Thu Oct 16 07:48:25.730791 2025] [security2:notice] [pid 122656:tid 122656] ModSecurity: LIBXML compiled version="2.10.4"
[Thu Oct 16 07:48:25.730793 2025] [security2:notice] [pid 122656:tid 122656] ModSecurity: Status engine is currently disabled, enable it by set SecStatusEngine to On.
[Thu Oct 16 07:48:25.806244 2025] [mpm_event:notice] [pid 122656:tid 122656] AH00489: Apache/2.4.65 (Amazon Linux) OpenSSL/3.2.2 Communique/4.3.7 configured -- resuming normal operations

Summary:

No errors in error.log.

We have another Amazon Linux 2023 (aarch64) instance in a different environment (test) running the same httpd, modsecurity version and modsecurity logging configuration — and there the audit log works fine.

We can’t share direct access, but can run additional diagnostics (e.g. strace, level 9 debug in modsec) if that helps.

tinhutins avatar Oct 16 '25 06:10 tinhutins

We have another Amazon Linux 2023 (aarch64) instance in a different environment (test) running the same httpd, modsecurity version and modsecurity logging configuration — and there the audit log works fine.

That's very strange...

We can’t share direct access, but can run additional diagnostics (e.g. strace, level 9 debug in modsec) if that helps.

Sure, I see. Unfortunately debug log won't contain any relevant information, only the error.log.

I would rebuild the module with CFLAGS="-O0 -g" flag at ./configure (beside the other flags) or if you install the module as a package, then probably the OS provides a dbgsym package too. Then start httpd with no-fork mode (-X if I'm not wrong) with gdb. Before that you should find this message in source, and set breakpoints before that lines.

Yeah, it's a "good game", but I'm afraid there won't be other chance to get information about this behavior.

airween avatar Oct 16 '25 06:10 airween

Hi @airween

We are trying to inspect ModSecurity audit logs at runtime using GDB on Amazon Linux.

Here is what we have tried:

Checked available functions:

(gdb) info functions modsecurity
apr_status_t modsecurity_process_phase(modsec_rec *, unsigned int);
static apr_status_t modsecurity_tx_cleanup(void *);
apr_status_t modsecurity_request_body_retrieve(modsec_rec *, msc_data_chunk **, long, char **);
apr_status_t modsecurity_request_body_retrieve_start(modsec_rec *, char **);
(gdb) info functions audit
void sec_audit_logger_json(modsec_rec *);
void sec_audit_logger_native(modsec_rec *);
static int sec_auditlog_write.isra.0(modsec_rec *, const char *, unsigned int);

Attempted GDB breakpoint and commands:

set breakpoint pending on
break sec_audit_logger_native
commands
  printf "\n=== Audit log triggered ===\n"
  bt 3
  print msr
  print msr->auditlog_id
  print msr->r->uri
  print msr->r->method
  continue
end
continue

Breakpoint is hit when requests are made.

GDB prints:

Thread 32 "httpd" hit Breakpoint 1, sec_audit_logger_native (msr=0xffff48127778) at /usr/src/debug/mod_security-2.9.12-1.amzn2023.0.1.aarch64/apache2/msc_logging.c:1535
1535    void sec_audit_logger_native(modsec_rec *msr) {
Invalid argument syntax

Any tips for inspecting ModSecurity structures safely without causing GDB syntax errors?

tinhutins avatar Oct 16 '25 08:10 tinhutins

Hi again @airween,

Following up on your previous suggestion about rebuilding with CFLAGS="-O0 -g" or using a dbgsym package.

We’re running Amazon Linux 2023 (aarch64), and we have all the related debug packages installed from the official repos:

httpd-core-debuginfo-2.4.65-1.amzn2023.0.1
httpd-debuginfo-2.4.65-1.amzn2023.0.1
httpd-debugsource-2.4.65-1.amzn2023.0.1
mod_security-debuginfo-2.9.12-1.amzn2023.0.1
mod_security-debugsource-2.9.12-1.amzn2023.0.1

Amazon Linux doesn’t ship separate dbgsym packages, only debuginfo and debugsource, so these should be the equivalents.

We started httpd -X under GDB and set a breakpoint at sec_audit_logger_native(modsec_rec *msr), which triggers correctly, but any attempt to inspect fields such as msr->auditlog_id or msr->r->uri results in:

Invalid argument syntax

So it seems GDB can reach the symbol but not dereference the structure.

Is there a recommended way to safely inspect the contents of modsec_rec (or request_rec) when using packaged debuginfo builds? Or does this require a rebuild of ModSecurity specifically with -O0 -g to make those structures fully accessible?

Thanks again for your time and guidance!

tinhutins avatar Oct 22 '25 09:10 tinhutins

Could you try this?

set breakpoint pending on
break sec_audit_logger_native
commands
  silent
  set language c
  frame 0
  printf "\n=== Audit log triggered ===\n"
  printf "msr=%p\n", msr
  # Guard against NULL
  if msr != 0
    # Show audit id
    p (char *)((struct modsec_rec *)msr)->auditlog_id
    # Show request_rec pointer + a couple of hot fields
    set $r = (request_rec *)((struct modsec_rec *)msr)->r
    printf "r=%p\n", $r
    if $r != 0
      x/s $r->method
      x/s $r->uri
      x/s $r->unparsed_uri
      x/s $r->args
    end
  end
  continue
end
continue

If that doesn't work, see if msr can be read:

info sharedlibrary mod_security
info address sec_audit_logger_native
ptype msr
whatis msr

You should see msr as modsec_rec *. If ptype msr itself errors, GDB isn’t seeing the type (mismatched debuginfo or LTO/stripped CU).

monkburger avatar Nov 05 '25 12:11 monkburger