Install ModSecurity 3 with Nginx on Ubuntu 22.04

0
2

Welcome to our guide on how to install ModSecurity 3 with Nginx on Ubuntu 22.04. Modsecurity is an open source, cross platform web application firewall (WAF) which provides a robust event-based programming language which protects web applications against a wide range of attacks such as SQL injection, Cross-site Scripting (XSS), Local File Include, Remote File Include e.tc. It also allows for HTTP traffic monitoring, logging and real-time analysis.

Install ModSecurity 3 with Nginx on Ubuntu 22.04

Install Required Build Tools and Dependencies

To install ModSecurity 3 with Nginx on Ubuntu 22.04, you need to build it from source.

You will also need to build Nginx from the source code in order to enable suppport for ModSecurity.

Hence, you need to install some required build tools and dependencies for a successful build.

apt install g++ flex bison curl apache2-dev doxygen \
libyajl-dev ssdeep liblua5.2-dev libgeoip-dev libtool \
dh-autoreconf libcurl4-gnutls-dev libxml2 libpcre++-dev \
libxml2-dev git liblmdb-dev libpkgconf3 lmdb-doc pkgconf \
zlib1g-dev libssl-dev -y

Compile and Install ModSecurity on Ubuntu 22.04

  • Download ModSecurity Source Code

Navigate to ModSecurity releases page and download the source code for ModSecurity 3. You can simply use wget to pull it.

wget https://github.com/SpiderLabs/ModSecurity/releases/download/v3.0.6/modsecurity-v3.0.6.tar.gz
  • Extract the ModSecurity source code.
tar xzf modsecurity-v3.0.6.tar.gz
  • Configure ModSecurity 3.0.6 Source Code on Ubuntu 22.04

Navigate to ModSecurity 3.x source directory and configure it;

cd modsecurity-v3.0.6
./build.sh

You can safely ignore the fatal: not a git repository (or any of the parent directories): .git error and the obsolete warning messages.

./configure

Be sure to fix any dependency issue, if any, before you can proceed to compile and install ModSecurity 3 with Nginx on Ubuntu 22.04.

If the configure script above completes with no error, proceed to compile and install ModSecurity 3 with Nginx on Ubuntu 22.04.

  • Compile and Install ModSecurity 3 on Ubuntu 22.04

From within each ModSecurity version source directory, execute the commands below to install them;

make
make install

Install Nginx with ModSecurity 3 Support on Ubuntu 22.04

Next, you need to compile Nginx with support for Modsecurity.

Therefore, download the ModSecurity-nginx connector which provides a communication channel between Nginx and LibModsecurity by cloning its git repository.

cd ~
git clone https://github.com/SpiderLabs/ModSecurity-nginx.git

Next, download the latest staple version of Nginx from Nginx downloads. The latest version as of this writing is version nginx-1.20.2.tar.gz.

wget https://nginx.org/download/nginx-1.20.2.tar.gz

Extract the archive.

tar xzf nginx-1.20.2.tar.gz

Remove any installed versions of Nginx;

apt remove --purge --auto-remove nginx -y

Create a non-privileged Nginx system user and group.

useradd -r -M -s /sbin/nologin -d /usr/local/nginx nginx

Navigate to Nginx source directory and configure it.

cd nginx-1.20.2
./configure --user=nginx --group=nginx --with-pcre-jit --with-debug --with-compat \
--with-http_ssl_module --with-http_realip_module --add-dynamic-module=/root/ModSecurity-nginx \
--http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log

Configuration summary;

Configuration summary
  + using system PCRE library
  + using system OpenSSL library
  + using system zlib library

  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx/conf"
  nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/var/log/nginx/error.log"
  nginx http access log file: "/var/log/nginx/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

Compile and install Nginx on Ubuntu 22.05.

make

Create dynamic modules;

make modules

Install Nginx;

make install

You can check nginx version, compiler version, and configure script parameters with the command;

ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
nginx -V

Sample output;

nginx version: nginx/1.20.2
built by gcc 11.2.0 (Ubuntu 11.2.0-19ubuntu1) 
built with OpenSSL 3.0.2 15 Mar 2022
TLS SNI support enabled
configure arguments: --user=nginx --group=nginx --with-pcre-jit --with-debug --with-compat --with-http_ssl_module --with-http_realip_module --add-dynamic-module=/root/ModSecurity-nginx --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log

Confgure Nginx with ModSecurity 3 on Ubuntu 22.04

Copy the sample ModSecurity configuration file on the source directory to Nginx configuration directory.

cp ~/modsecurity-v3.0.6/modsecurity.conf-recommended /usr/local/nginx/conf/modsecurity.conf

Copy the unicode.mapping file from ModSecurity source directory to Nginx configuration directory.

cp ~/modsecurity-v3.0.6/unicode.mapping /usr/local/nginx/conf/

Next, edit Nginx configuration file and make the changes as shown below.

Create a backup of the Nginx configuration file.

cp /usr/local/nginx/conf/nginx.conf{,.bak}

Open the configuration file for editing.

vim /usr/local/nginx/conf/nginx.conf

Configure Nginx such that your configuration may look like;

cat > /usr/local/nginx/conf/nginx.conf << 'EOL'
load_module modules/ngx_http_modsecurity_module.so;
user  nginx;
worker_processes  1;
pid        /run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  nginx.kifarunix-demo.com;
        modsecurity  on;
        modsecurity_rules_file  /usr/local/nginx/conf/modsecurity.conf;
        access_log  /var/log/nginx/access_kifarunix-demo.log;
        error_log  /var/log/nginx/error_kifarunix-demo.log;
        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
EOL

The lines below tTurns on Modsecurity on the root web document and specific the location of the Modsecurity rules.

modsecurity on;
modsecurity_rules_file /usr/local/nginx/conf/modsecurity.conf;

Note that ModSecurity 3 can be turned on per directory basis.

The line below loads the Modsecurity Nginx modules;

load_module modules/ngx_http_modsecurity_module.so;

Create Nginx log directory.

mkdir /var/log/nginx 

Turn on ModSecurity by changing the value of SecRuleEngine to On.

sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /usr/local/nginx/conf/modsecurity.conf

Install OWASP ModSecurity Core Rule Set (CRS)

The OWASP ModSecurity Core Rule Set (CRS) is a set of generic attack detection rules for use with ModSecurity. It aims at protecting the web applications from a wide range of attacks, including the OWASP Top Ten, minimum of false alerts.

Clone the CRS from GitHub repository to /usr/local/nginx/conf/ as shown below;

git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git /usr/local/nginx/conf/owasp-crs

Next, rename crs-setup.conf.example to crs-setup.conf.

sudo cp /usr/local/nginx/conf/owasp-crs/crs-setup.conf{.example,}

Once the OWASP rules are in place, configure ModSecurity to use these rules. You therefore need to enter the following lines on the ModSecurity configuration file to tell it where to find the rules.

echo -e "Include owasp-crs/crs-setup.conf
Include owasp-crs/rules/*.conf" >> /usr/local/nginx/conf/modsecurity.conf

This command will append the lines below on /usr/local/nginx/conf/modsecurity.conf.

Include owasp-crs/crs-setup.conf
Include owasp-crs/rules/*.conf

Enable Modsecurity Self-contained mode. In this configuration the default disruptive action becomes ‘deny’. After a rule triggers, it will stop processing the request and return an error 403.

...
#SecDefaultAction "phase:1,log,auditlog,pass"
#SecDefaultAction "phase:2,log,auditlog,pass"

...
#
SecDefaultAction "phase:1,log,auditlog,deny,status:403"
SecDefaultAction "phase:2,log,auditlog,deny,status:403"
...

Save the changes and exit the file.

Verify Nginx configuration file again.

nginx -t

Next, create Nginx Systemd service unit.

cat > /etc/systemd/system/nginx.service << 'EOL'
[Unit]
Description=A high performance web server and a reverse proxy server
Documentation=man:nginx(8)
After=network.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/local/nginx/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/local/nginx/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
TimeoutStopSec=5
KillMode=mixed

[Install]
WantedBy=multi-user.target
EOL

Reload system;

systemctl daemon-reload

Then Start Nginx;

systemctl enable --now nginx

Check the status;

systemctl status nginx

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/etc/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2022-05-02 14:46:19 UTC; 3s ago
       Docs: man:nginx(8)
    Process: 4933 ExecStartPre=/usr/local/nginx/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
    Process: 4934 ExecStart=/usr/local/nginx/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
   Main PID: 4935 (nginx)
      Tasks: 2 (limit: 2241)
     Memory: 20.0M
        CPU: 173ms
     CGroup: /system.slice/nginx.service
             ├─4935 "nginx: master process /usr/local/nginx/sbin/nginx -g daemon on; master_process on;"
             └─4936 "nginx: worker process" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""

May 02 14:46:19 jellyfish systemd[1]: Starting A high performance web server and a reverse proxy server...
May 02 14:46:19 jellyfish systemd[1]: Started A high performance web server and a reverse proxy server.

Testing Modsecurity

Next, test the effectiveness of Modsecurity, for example, command injection. Run the command below;

curl localhost?doc=/bin/ls
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.20.2</center>
</body>
</html>

Check Modsecurity logs;

tail /var/log/modsec_audit.log
---k96Orv6r---H--
ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `PmFromFile' with parameter `unix-shell.data' against variable `ARGS:doc' (Value: `/bin/ls' ) [file "/usr/local/nginx/conf/owasp-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf"] [line "496"] [id "932160"] [rev ""] [msg "Remote Command Execution: Unix Shell Code Found"] [data "Matched Data: bin/ls found within ARGS:doc: /bin/ls"] [severity "2"] [ver "OWASP_CRS/3.2.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-shell"] [tag "platform-unix"] [tag "attack-rce"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION"] [tag "WASCTC/WASC-31"] [tag "OWASP_TOP_10/A1"] [tag "PCI/6.5.2"] [hostname "127.0.0.1"] [uri "/"] [unique_id "1651502945"] [ref "o1,6v10,7t:urlDecodeUni,t:cmdLine,t:normalizePath,t:lowercase"]

---k96Orv6r---I--

---k96Orv6r---J--

---k96Orv6r---Z--

Access the site from browser and test command injection attack, http://domain.name/?exec=/bin/bash.

403 Forbidden

403 Forbidden


nginx/1.20.2

Check Nginx Error log;

tail /var/log/nginx/error_kifarunix-demo.log
2022/05/02 14:49:05 [error] 4936#0: *1 [client 127.0.0.1] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `PmFromFile' with parameter `unix-shell.data' against variable `ARGS:doc' (Value: `/bin/ls' ) [file "/usr/local/nginx/conf/owasp-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf"] [line "496"] [id "932160"] [rev ""] [msg "Remote Command Execution: Unix Shell Code Found"] [data "Matched Data: bin/ls found within ARGS:doc: /bin/ls"] [severity "2"] [ver "OWASP_CRS/3.2.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-shell"] [tag "platform-unix"] [tag "attack-rce"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION"] [tag "WASCTC/WASC-31"] [tag "OWASP_TOP_10/A1"] [tag "PCI/6.5.2"] [hostname "127.0.0.1"] [uri "/"] [unique_id "1651502945"] [ref "o1,6v10,7t:urlDecodeUni,t:cmdLine,t:normalizePath,t:lowercase"], client: 127.0.0.1, server: nginx.kifarunix-demo.com, request: "GET /?doc=/bin/ls HTTP/1.1", host: "localhost"

Similarly, install Nikto on Ubuntu and use it to scan the server to test the modsecurity rules;

Install and Use Nikto Web Scanner on Ubuntu

As a result, this confirms that the Modsecurity is functioning as expected.

That is just about it on our guide on how to install ModSecurity with Nginx on Ubuntu 22.04.

Reference:

ModSecurity-nginx

ModSecurity

Other Tutorials

Process ModSecurity Logs using Wazuh

Install ModSecurity with Apache on Ubuntu 22.04

LEAVE A REPLY

Please enter your comment!
Please enter your name here