Home · Guides / 5 / Secure / 5.1

Guide 5.1

Install ModSecurity on NGINX

ModSecurity is an open source web application firewall. On this stack it sits in front of the NGINX site that Tor already forwards to 127.0.0.1:80, so it can still inspect requests that arrive over the onion address.

Credit This page is an original Tor Onion write-up, based on How to Install & Configure ModSecurity on Nginx by Chandan Kumar on Geekflare (2016, last updated December 2024). Their article compiles Nginx 1.9.15 with ModSecurity 2.9.1 from source on a RHEL-style host. The steps below use Ubuntu packages so they match guides 4–4.2.

Install the module

  1. Install ModSecurity 3 and the NGINX connector from APT (names vary slightly by Ubuntu release; search if yours differs).

    sudo apt update
    sudo apt install libmodsecurity3
    sudo apt install libnginx-mod-http-modsecurity

    If the module package is missing, install modsecurity-crs when offered, or follow Geekflare’s source-compile method for older Nginx.

  2. Confirm NGINX loaded the module.

    nginx -V 2>&1 | tr ' ' '\n' | grep -i modsecurity
    sudo nginx -t

Enable it on the onion site

  1. Create a small rules include. Copy the recommended config if the package shipped one:

    sudo mkdir -p /etc/nginx/modsec
    sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/nginx/modsec/modsecurity.conf
    sudo cp /usr/share/modsecurity-crs/unicode.mapping /etc/nginx/modsec/unicode.mapping 2>/dev/null || true

    If those paths do not exist on your release, copy modsecurity.conf-recommended and unicode.mapping from the ModSecurity tree, as Geekflare describes.

  2. Start in detection-only mode (log, do not block) until you know the ruleset is sane. Confirm the engine line:

    grep SecRuleEngine /etc/nginx/modsec/modsecurity.conf

    The recommended file already uses DetectionOnly. Leave it that way for the first run. Change it to On only after you have reviewed the audit log.

  3. Add a main include file:

    sudo tee /etc/nginx/modsec/main.conf > /dev/null << 'EOF'
    Include /etc/nginx/modsec/modsecurity.conf
    EOF
  4. In /etc/nginx/sites-enabled/default, inside the server block that listens on 127.0.0.1, turn the engine on:

    modsecurity on;
    modsecurity_rules_file /etc/nginx/modsec/main.conf;

    ModSecurity 2 with a source-built Nginx (Geekflare’s path) used ModSecurityEnabled on; and ModSecurityConfig modsecurity.conf; instead. Use the pair that matches the module you compiled or installed.

  5. Test and reload.

    sudo nginx -t
    sudo service nginx reload

Optional: OWASP Core Rule Set

The engine alone does little until you load rules. OWASP CRS is the usual starting set.

  1. Install the packaged CRS if available, otherwise clone it:

    sudo apt install modsecurity-crs

    or

    sudo git clone https://github.com/coreruleset/coreruleset.git /etc/nginx/modsec/coreruleset
    sudo cp /etc/nginx/modsec/coreruleset/crs-setup.conf.example /etc/nginx/modsec/coreruleset/crs-setup.conf
  2. Point main.conf at the setup file and the rules directory. Package layouts differ; adjust paths after dpkg -L modsecurity-crs.

    Include /etc/nginx/modsec/modsecurity.conf
    Include /etc/nginx/modsec/coreruleset/crs-setup.conf
    Include /etc/nginx/modsec/coreruleset/rules/*.conf
  3. Reload NGINX again. Watch /var/log/nginx/error.log and the ModSecurity audit log (often /var/log/modsec_audit.log or the path in SecAuditLog).

  4. When the logs look clean for real traffic, switch blocking on:

    SecRuleEngine On

    Then sudo nginx -t and reload. Keep detection-only if a CMS or plugin is flooded with false positives.

Onion-specific note The WAF still only sees what NGINX sees. It does not replace binding to localhost, keeping MySQL off the network, or patching PHP. Pair this page with LEMP hardening.