Install ModSecurity 3 with Nginx on Fedora 37/36
You’ll learn how to get ModSecurity 3 up and running inside your Fedora‑based Nginx server without messing with the operating system’s default packages.
Prerequisites
Before you start, make sure you’re logged in as a user that can use sudo or are on the root account.
Fedora 36/37 ship Nginx in the core repos but ModSecurity 3 isn’t available there; we’ll build it from source.
Install ModSecurity 3 Dependencies
sudo dnf groupinstall "Development Tools" sudo dnf install git libcurl-devel pcre2-devel openssl-devel
Why this matters:
The build process relies on GCC, make, and the development headers for curl, PCRE, and OpenSSL. Skipping any of these will stall the compile.
Clone and Compile ModSecurity 3
git clone --depth=1 https://github.com/SpiderLabs/ModSecurity.git cd ModSecurity ./autogen.sh ./configure --enable-standalone-module make -j$(nproc) sudo make install
Why this matters:
--enable-standalone-module tells the build system to produce a shared library that can be dropped into any server. The make install step copies modsecurity.so to /usr/lib64/modsecurity.
Grab the Nginx ModSecurity Module
git clone --depth=1 https://github.com/SpiderLabs/nginx-mod-security.git
We’ll compile this as a dynamic module.
Add the ModSecurity Module to Your Nginx Build
If you already have Nginx installed from Fedora, stop it first:
sudo systemctl stop nginx
Now recompile Nginx with the new module:
cd /usr/src/nginx-1.25.3 # or wherever your Nginx source lives
./configure --add-dynamic-module=/path/to/nginx-mod-security \
--with-http_ssl_module \
--prefix=/etc/nginx
make modules
sudo make install
Why this matters:
Installing the module as a dynamic component keeps the core binary lean and allows you to enable or disable ModSecurity without recompiling Nginx again.
Configure ModSecurity for Nginx
Create a basic config file:
sudo mkdir -p /etc/nginx/modsec sudo cp /usr/lib64/modsecurity/modsecurity.conf-recommended /etc/nginx/modsec/modsecurity.conf
Edit it to your taste, but at minimum change:
SecRuleEngine On SecRequestBodyAccess On SecResponseBodyAccess Off SecDataDir /var/cache/modsecurity
Then tell Nginx to load the module and config in nginx.conf:
load_module modules/ngx_http_modsecurity_module.so;
http {
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsecurity.conf;
# your usual server blocks …
}
Why this matters:
Without those directives, ModSecurity would stay dormant. The SecDataDir setting forces a writable location because Fedora’s default /tmp is read‑only under SELinux.
Test the Setup with a Simple Rule
Add a quick rule to block requests containing “evil”:
SecRule REQUEST_URI "@contains evil" "phase:1,id:1000,deny,status:403,msg:'Blocked evil URI'"
Restart Nginx and hit http://yourserver/evil – you should see a 403 page. If not, check the ModSecurity log in /var/log/modsecurity.log.
Troubleshooting Common Issues
SELinux blocks the module.
Set permissive temporarily while testing:
sudo setenforce 0
If it works, add a custom policy:
sudo semanage fcontext -a -t httpd_sys_content_t "/etc/nginx/modsec(/.*)?" sudo restorecon -Rv /etc/nginx/modsec
The module fails to load.
Ensure the shared object path matches the load_module line. Also verify that Nginx was compiled with --with-http_ssl_module; without SSL support, some ModSecurity features will complain.
There you go – ModSecurity 3 is now an active guardian of your Fedora‑hosted Nginx sites.