libModSecurity v3 with NGINX
The ModSecurity-nginx connector links libModSecurity into NGINX as a third-party module. Unlike the old (v2-era) standalone module, it is a thin layer between NGINX and the library: the rules engine, the body processors and the logging all live in libModSecurity. The current connector release is v1.0.4.
Distribution packages
Most distributions ship the connector as a dynamic NGINX module built against their own nginx and
libmodsecurity packages, which is the easiest way to get a working setup. Versions as of October 2026:
| Distribution | Package | Connector | libModSecurity |
|---|---|---|---|
| Debian 12 (bookworm) | libnginx-mod-http-modsecurity | 1.0.3 | 3.0.9 |
| Debian 13 (trixie) | libnginx-mod-http-modsecurity | 1.0.3 | 3.0.14 |
| Ubuntu 24.04 LTS | libnginx-mod-http-modsecurity | 1.0.3 | 3.0.12 |
| Ubuntu 26.04 LTS | libnginx-mod-http-modsecurity | 1.0.3 | 3.0.14 |
| Fedora 43 and 44, EPEL 9 | nginx-mod-modsecurity | 1.0.4 | 3.0.16 / 3.0.17 |
| Arch Linux | nginx-mod-modsecurity | 1.0.4 | 3.0.17 |
| Gentoo | www-nginx/ngx-modsecurity | 1.0.4 | 3.0.16 |
| FreeBSD ports | security/modsecurity3-nginx | 1.0.4 | 3.0.17 |
Ubuntu 22.04 has no connector package in the main archive. Debian, Ubuntu and the Red Hat family also have the current development builds of both the connector and the library in the digitalwave repository, maintained by one of the ModSecurity project leaders.
On Debian and Ubuntu:
The package enables the module through /etc/nginx/modules-enabled/50-mod-http-modsecurity.conf and installs
modsecurity.conf (the recommended base configuration, SecRuleEngine DetectionOnly), unicode.mapping and
modsecurity_includes.conf into /etc/nginx/, plus a sample site at
/etc/nginx/sites-available/default-modsecurity.conf. Turn it on per server or location with modsecurity on;
and modsecurity_rules_file /etc/nginx/modsecurity_includes.conf;, and include the CRS from that file by
uncommenting the owasp-crs.load line. libModSecurity has no IncludeOptional, so replace that directive by
Include in the files the CRS package installs. NGINX reports most CRS events at error_log ... info;.
On Fedora and EPEL:
The module is loaded from /usr/share/nginx/modules/mod-modsecurity.conf, the base configuration is installed
as /etc/nginx/modsecurity.conf, and /etc/nginx/nginx.conf.modsecurity is a sample server configuration; add
the modsecurity directives to your own server blocks as shown below.
Compilation
Get the connector source:
or clone the development branch with git clone https://github.com/owasp-modsecurity/ModSecurity-nginx.
Install libModSecurity first (see Building libModSecurity v3 from source
or your distribution’s libmodsecurity-dev / libmodsecurity-devel package). The connector’s config
script looks for the library under /usr/local/modsecurity; for any other location export MODSECURITY_INC
(the directory holding modsecurity/modsecurity.h) and MODSECURITY_LIB (the directory holding
libmodsecurity.so) before running NGINX’s configure.
From the NGINX source directory, add the connector as a static module:
Or build it as a dynamic module. The NGINX source version and configure arguments must then match the NGINX
binary you load it into (nginx -V prints them):
and load it with load_module modules/ngx_http_modsecurity_module.so; at the top of nginx.conf.
The connector runs ModSecurity phase 1 in NGINX’s rewrite phase, phase 2 in the preaccess phase (the
development branch has moved it to the access phase, after allow/deny and auth_*), phases 3 and 4 in the
header and body filters, and phase 5 in the log phase.
Configuration directives
The connector adds the following directives, all valid in the http, server and location contexts. The
modsecurity_rules* directives may be repeated and accumulate; a location inherits the rules of its server.
modsecurity
| Syntax | modsecurity on | off |
|---|---|
| Default | off |
| ModSecurity v2 | not supported |
| libModSecurity v3 | supported |
Turns ModSecurity on or off for the context. This flag only enables the module in NGINX; the rule engine state is controlled separately by SecRuleEngine.
modsecurity_rules_file
| Syntax | modsecurity_rules_file <path to rules file> |
|---|---|
| ModSecurity v2 | not supported |
| libModSecurity v3 | supported |
Loads ModSecurity configuration and rules from a file:
modsecurity_rules_remote
| Syntax | modsecurity_rules_remote <key> <URL to rules> |
|---|---|
| ModSecurity v2 | not supported |
| libModSecurity v3 | supported |
Downloads the configuration from a URL, authenticating with the given key, exactly like SecRemoteRules (libModSecurity must be built with libcurl):
modsecurity_rules
| Syntax | modsecurity_rules <modsecurity rules> |
|---|---|
| ModSecurity v2 | not supported |
| libModSecurity v3 | supported |
Embeds rules directly in the NGINX configuration, which is handy for per-location overrides:
modsecurity_transaction_id
| Syntax | modsecurity_transaction_id string |
|---|---|
| ModSecurity v2 | not supported |
| libModSecurity v3 | supported |
Supplies the transaction ID from NGINX instead of letting the library generate one. The string may contain NGINX variables, so access-log and audit-log entries can be correlated:
modsecurity_use_error_log
| Syntax | modsecurity_use_error_log on | off |
|---|---|
| Default | on |
| ModSecurity v2 | not supported |
| libModSecurity v3 | supported (connector development branch only, not in v1.0.4) |
Controls whether ModSecurity alert messages are also written to the NGINX error log. This directive exists only
on the connector’s master branch; the 1.0.4 release does not know it and refuses to start with it in the
configuration. Distribution packages built from release tarballs do not have it either.