#1108728 libnginx-mod-http-modsecurity: Circular dependency on trixie upgrade

#1108728#5
Date:
2025-07-04 03:46:17 UTC
From:
To:
Upgrading bookworm -> trixie, libnginx-mod-http-modsecurity triggers
a circular dependency-like issue and the upgrade is unable to complete:

dpkg: error processing package nginx (--configure):
 installed nginx package post-installation script subprocess returned error exit status 1
dpkg: dependency problems prevent configuration of libnginx-mod-http-ndk:
 libnginx-mod-http-ndk depends on nginx-abi-1.26.3-1; however:
  Package nginx-abi-1.26.3-1 is not installed.
  Package nginx which provides nginx-abi-1.26.3-1 is not configured yet.

dpkg: error processing package libnginx-mod-http-ndk (--configure):
 dependency problems - leaving unconfigured
dpkg: dependency problems prevent configuration of libnginx-mod-http-modsecurity:
 libnginx-mod-http-modsecurity depends on libnginx-mod-http-ndk; however:
  Package libnginx-mod-http-ndk is not configured yet.
 libnginx-mod-http-modsecurity depends on nginx-abi-1.26.3-1; however:
  Package nginx-abi-1.26.3-1 is not installed.
  Package nginx which provides nginx-abi-1.26.3-1 is not configured yet.

dpkg: error processing package libnginx-mod-http-modsecurity (--configure):
 dependency problems - leaving unconfigured
Errors were encountered while processing:
 nginx
 libnginx-mod-http-ndk
 libnginx-mod-http-modsecurity
Error: Sub-process /usr/bin/dpkg returned an error code (1)

It appears libnginx-mod-http-modsecurity depends on the next version of nginx,
which cannot start until libnginx-mod-http-modsecurity is fully installed.

A workaround appears to be:

1. Remove packages libnginx-mod-http-modsecurity & libnginx-mod-http-ndk
2. Edit nginx.conf to temporarily disable modsecurity which is now missing.
3. Re-run upgrade to allow it to complete, and nginx to start successfully.
4. Reinstall libnginx-mod-http-modsecurity & modsecurity-crs (if installed)
5. Make any necessary changes (I had some breakage in /usr/share/modsecurity-crs/owasp-crs.load)
6. Re-enable modsecurity in nginx.conf
7. Restart necessary services.

#1108728#10
Date:
2025-07-04 19:11:52 UTC
From:
To:
I gave this some fresh thought and I now suspect the root cause lies within the modsecurity-crs package, which ironically is not mentioned anywhere in the error messages. This may provide some important missing context.

Once modsecurity was disabled and I was successfully able to reinstall all the packages, I had to remove the following two offending lines from /usr/share/modsecurity-crs/owasp-crs.load before nginx would start:

IncludeOptional /etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf

IncludeOptional /etc/modsecurity/crs/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf

I now suspect this issue may have cascaded and caused the error messages which blocked the package upgrades.

#1108728#15
Date:
2025-07-04 20:10:54 UTC
From:
To:
Hi,

this is a very important information.

After the first mail with this issue I thought the bug appears
because of the OS upgrade.

And yes, now I'm sure the reason is that - but not because of the
connector.

The problem is that libmodsecurity3 (the WAF library that Nginx
uses via libngnx-mod-http-modsecurity module) does not support
`IncludeOptional` directive.

If someone install the package first, this issue comes always.

Now you upgraded the system, and you upgraded modsecurity-crs
package too - which overrided your `Include` directive (I guess).

I think we should replace the mentioned `IncludeOptional`
directive with the `Include`.


a.

#1108728#20
Date:
2025-07-04 21:42:51 UTC
From:
To:
Ervin Hegedüs wrote:

Hi Ervin, please bear with me as it has been quite some time since I
set up modsecurity on this box and am not an expert.

I have attempted to reconstruct the events during the upgrade.

My understanding is the "IncludeOptional" in the default owasp-crs.load
is not compatible with nginx. It's likely that I removed this reference
ages ago to get things working. However, with the file now having been
overwritten, it's impossible to know for sure.

During the upgrade from bookworm -> trixie, modsecurity-crs package was
updated from version 3.3.4 to 3.3.7:

Preparing to unpack .../132-modsecurity-crs_3.3.7-1_all.deb ...
Unpacking modsecurity-crs (3.3.7-1) over (3.3.4-1) ...

During the upgrade I received a prompt due to file
/etc/modsecurity/crs/crs-setup.conf being modified by me:

Setting up modsecurity-crs (3.3.7-1) ...
Installing new version of config file /etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf ...
Installing new version of config file /etc/modsecurity/crs/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf ...

Configuration file '/etc/modsecurity/crs/crs-setup.conf'
 ==> Modified (by you or by a script) since installation.
 ==> Package distributor has shipped an updated version.
   What would you like to do about it ?  Your options are:
    Y or I  : install the package maintainer's version
    N or O  : keep your currently-installed version
      D     : show the differences between the versions
      Z     : start a shell to examine the situation
 The default action is to keep your current version.
*** crs-setup.conf (Y/I/N/O/D/Z) [default=N] ?
Setting up libldap-common (2.6.10+dfsg-1) ...
Installing new version of config file /etc/ldap/ldap.conf ...

Note I received no warning that /usr/share/modsecurity-crs/owasp-crs.load
was modified! I speculate this is because the file is located in /usr that
dpkg/apt simply overwrote my changes with the new package version.
Thus reverting any removal of the IncludeOptional that may have been there.

If this is what happened, I propose /usr/share is a poor location for
the config file and owasp-crs.load should be located in /etc so that
dpkg/apt can detect changes in the future. Otherwise it is sure to
break everytime the package is updated (if running nginx).

Regards
Lloyd

#1108728#25
Date:
2025-07-05 08:25:26 UTC
From:
To:
apologize if it seemed like I wasn't patient. I think I can say
usually I am :)

yes, exactly. Just one small correction: it's not an Nginx
directive in this case, but a rule set directive. That's the
libary's task, not the engine's (Nginx) task.

The "explanation" is simple: modsecurity-crs was made for Apache
(for libapache2-mod-security), and the whole SecLang syntax was
build on top of Apache configuration syntax. The library
(libmodsecurity3) must have to understand this syntax, and there
are some missing keywords - like "IncludeOptional".

yes, this was my feeling.

probably because those are user maintained files.

probably yes.

A side note: even the CRS 3.3 is still maintained, if someone has
a new instance, I recommend to use CRS4. CRS4 does not have
package in Debian yet, but the (CRS) team decided that they
change the versioning: we don't increase patch level, only the
minor version (excpet if it's really necessary - but since the
change we have never used this). So the releases are 4.0.0,
4.1.0, ... 4.16.0. Almost in every month the team releses a new
version, so actually I don't know how can we handle this in
Debian.

Moreover, the "product's" name also changed: it's not
"modsecurity-crs" anymore, but just simple CRS or CRS4.

Also: if you already use CRS 3.3, then I don't suggest to switch
to CRS4, except if you have strong skills to review the rules and
existing exclusions.


Regards,

a.

#1108728#30
Date:
2025-07-05 17:26:26 UTC
From:
To:
Hi Ervin,

Thank you for the detailed explanations. If you agree there is a bug here,
and I do think so based on the upgrade breakage, I propose the following
which could be a low-impact quick fix to prevent future upgrade issues:

The fix does not modify any source files in the upstream at all, but rather
the way the Debian package is built.

When I examine the package for modsecurity-crs, it declares the following
as conffiles in the control archive:

/etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
/etc/modsecurity/crs/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
/etc/modsecurity/crs/crs-setup.conf

When owasp-crs.load was added to the mix at some point, it never got added
to the conffiles. From looking at the git repo, I don't see conffiles for
this package explicitly declared anywhere. So I assume there is an auto-
generation happening here, based on package files copied into /etc. Since
the owasp-crs.load file is placed in /usr/share, the package build scripts
ignore it and it never gets added - so every upgrade of the package, this
file will get clobbered, even if it was modified by the user.

I think if we added owasp-crs.load to the list as a conffile declaration
the user will get an interactive prompt during package upgrade if the file
is modified (and it surely will if using it in the scenario we discussed).

Regards
Lloyd

#1108728#35
Date:
2025-07-05 17:42:10 UTC
From:
To:
reassign 1108728 modsecurity-crs
retitle 1108728 owasp-crs.load overwritten during trixie upgrade, causing dependency loop
affects 1108728 nginx libnginx-mod-http-ndk libnginx-mod-http-modsecurity
thanks