custom/nginx/conf/nginx-modsecurity.conf not applied by any build command — is this expected?

castris

Verified User
Joined
Apr 16, 2021
Messages
154
Location
Arcenillas
Hi everyone,

I manage a small fleet of DirectAdmin servers (6 servers, all nginx + ModSecurity 3.0.14 + OWASP CRS 4.22.0) and I'd really appreciate some guidance from the community or DA team on something I've run into. I'm not sure if I'm doing something wrong or if this is a gap in how CustomBuild handles this particular file.

Context — why we need to customize nginx-modsecurity.conf​


We take ModSecurity management seriously. Rather than just blanket-disabling rules when users report issues, we carefully craft targeted exclusions (per-domain, per-path, per-parameter) in 01_REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf. This allows us to keep the OWASP CRS protection intact for the vast majority of traffic while only relaxing specific rules where legitimate application behavior triggers false positives.

The problem is that we've had 3 incidents in 12 days where build update_versions left nginx completely down, taking all hosted websites offline. The root cause in each case involved ModSecurity/CRS configuration conflicts during the update process. One recurring issue is the SecDefaultAction directive: in certain scenarios after an update, the generated nginx-modsecurity.conf can contain a SecDefaultAction for phase:2 that conflicts with the one already defined in crs-setup.conf.main, causing:

Code:
nginx: [emerg] "modsecurity_rules_file" directive Rules error.
SecDefaultActions can only be placed once per phase and configuration context.
Phase 2 was informed already.

Our hardening plan​


To prevent this, we designed a simple hardening approach:

  1. Create a custom nginx-modsecurity.conf that explicitly includes SecRuleEngine On but omits SecDefaultAction (since CRS already defines it) — following the standard configure/custom/ pattern documented in the DA docs
  2. Add a post-update_versions hook for automatic detection and recovery
  3. Add a cron-based health check as an independent safety net

For step 1, we followed the ModSecurity documentation and the customize-everything guide:

Bash:
mkdir -p /usr/local/directadmin/custombuild/custom/nginx/conf/
cp /usr/local/directadmin/custombuild/configure/nginx/conf/nginx-modsecurity.conf \
   /usr/local/directadmin/custombuild/custom/nginx/conf/nginx-modsecurity.conf
# Edit: added SecRuleEngine On, removed SecDefaultAction, added explanatory comments

The problem — custom file is never applied​


After creating the custom file, we tested every build command we could think of:

CommandResult
./build nginxRecompiled nginx, ran rewrite, but /etc/nginx/nginx-modsecurity.conf still matches configure/ template — custom ignored
./build rewrite_confsCompleted successfully — custom ignored
da build rewrite_confsCompleted successfully — custom ignored

In all three cases, the active file at /etc/nginx/nginx-modsecurity.conf remains identical to the default template at configure/nginx/conf/nginx-modsecurity.conf. Our custom file at custom/nginx/conf/nginx-modsecurity.conf is completely ignored.

We verified this with a clean test:

  1. Placed our custom file with a visible difference (SecRuleEngine On added on line 2, which the default template doesn't have)
  2. Restored the active file to match the default template
  3. Ran da build rewrite_confs
  4. Compared: active file = default template, custom file ignored

Environment​


  • DirectAdmin: 1.693
  • CustomBuild: current (as of 2026-02-17)
  • nginx: 1.29.4
  • ModSecurity: 3.0.14 (libmodsecurity3)
  • modsecurity3_nginx: 1.0.4
  • OWASP CRS: 4.22.0
  • OS: Ubuntu 22.04.5 LTS
  • Webserver mode: nginx (standalone, not nginx+apache)

Workaround​


For now we're manually copying the custom file to /etc/nginx/nginx-modsecurity.conf and we've added a post-update_versions hook that automatically restores it if a build overwrites it. This works, but it defeats the purpose of the custom mechanism.

Questions​


  1. Is custom/nginx/conf/nginx-modsecurity.conf supposed to be picked up by da build rewrite_confs? The docs suggest it should, but it doesn't seem to work in practice.
  2. Is there a different build command that handles this specific file? We've tried build nginx, build rewrite_confs, and da build rewrite_confs.
  3. Is this file perhaps regenerated by DirectAdmin's internal rewrite logic (bypassing the custom/ mechanism entirely)?

We'd love to use the standard CustomBuild mechanism instead of our manual workaround. Any pointers from the community or the DA team would be greatly appreciated.

Thanks in advance!
 
Hi
try using rewrite_conf hook to copy file to write place.
try this.

firs creat a Folder whit this command

mkdir -p /usr/local/directadmin/custombuild/custom/hooks/rewrite_conf/post

in Folder creat a file copy.sh and edit it

nano /usr/local/directadmin/custombuild/custom/hooks/rewrite_conf/post/copy.sh

in the file copy.sh paste copy the following codes
#! /bin/bash

cp /usr/local/directadmin/custombuild/custom/nginx/conf/nginx-modsecurity.conf /etc/nginx

systemctl restart nginx

and make the file copy.sh executable
chmod +x /usr/local/directadmin/custombuild/custom/hooks/rewrite_conf/post/copy.sh

now wenn you run ./build rewrite_confs or da build rewrite_confs commands
rewrite_conf will started and befor ending it will started your cods in copy.sh
this will copy the file from /usr/local/directadmin/custombuild/custom/nginx/conf/nginx-modsecurity.conf
to /etc/nginx and it will overwrite file and nginx will restared

you will also see in the terminal end of ./build rewrite_confs or da build rewrite_confs commands runs
Executing '/usr/local/directadmin/custombuild/custom/hooks/rewrite_confs/post/copy.sh'...
+++ cp /usr/local/directadmin/custombuild/custom/hooks/rewrite_conf/post/copy.sh /etc/nginx
+++ systemctl restart nginx

hope this helps
 
Back
Top