A guide to installing, initial configuration and operating the Nemesida WAF dynamic module for Nginx and the Nemesida AI MLA machine learning agent, designed to detect and block anomalies using signature analysis and behavioral models, as well as for analyzing requests for compliance with their scheme in OpenAPI and Swagger format.

Installation
Before installing Nemesida WAF components, add repository information to the system:

DebianUbuntuCentOSDockerVirtual Appliance
# apt install apt-transport-https gnupg2 curl
Debian 10
# echo "deb https://nemesida-security.com/repo/nw/debian buster non-free" > /etc/apt/sources.list.d/NemesidaWAF.list
# wget -O- https://nemesida-security.com/repo/nw/gpg.key | apt-key add -
# apt update && apt upgrade
Debian 11
# echo "deb https://nemesida-security.com/repo/nw/debian bullseye non-free" > /etc/apt/sources.list.d/NemesidaWAF.list
# curl -s https://nemesida-security.com/repo/nw/gpg.key | gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/trusted.gpg --import
# chmod 644 /etc/apt/trusted.gpg.d/trusted.gpg
# apt update && apt upgrade
# apt install apt-transport-https gnupg2 curl
Ubuntu 18.04
# echo "deb [arch=amd64] https://nemesida-security.com/repo/nw/ubuntu bionic non-free" > /etc/apt/sources.list.d/NemesidaWAF.list
# wget -O- https://nemesida-security.com/repo/nw/gpg.key | apt-key add -
# apt update && apt upgrade
Ubuntu 20.04
# echo "deb [arch=amd64] https://nemesida-security.com/repo/nw/ubuntu focal non-free" > /etc/apt/sources.list.d/NemesidaWAF.list
# wget -O- https://nemesida-security.com/repo/nw/gpg.key | apt-key add -
# apt update && apt upgrade
Ubuntu 22.04
# echo "deb [arch=amd64] https://nemesida-security.com/repo/nw/ubuntu jammy non-free" > /etc/apt/sources.list.d/NemesidaWAF.list
# curl -s https://nemesida-security.com/repo/nw/gpg.key | gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/trusted.gpg --import
# chmod 644 /etc/apt/trusted.gpg.d/trusted.gpg 
# apt update && apt upgrade
CentOS 7
# rpm -Uvh https://nemesida-security.com/repo/nw/centos/nwaf-release-centos-7-1-6.noarch.rpm
# yum update
# yum install epel-release
CentOS 8 Stream
# rpm -Uvh https://nemesida-security.com/repo/nw/centos/nwaf-release-centos-8-1-6.noarch.rpm
# dnf update
# dnf install epel-release
CentOS 9 Stream
# rpm -Uvh https://nemesida-security.com/repo/nw/centos/nwaf-release-centos-9-1-6.noarch.rpm
# dnf update
# dnf install epel-release
Information about using Nemesida WAF in a Docker container is available in corresponding section.
Information about using Nemesida WAF as a Virtual Appliance (virtual disk for KVM/VMware/VirtualBox) and Yandex VM is available in corresponding section.

Nginx Setup

If Nginx is compiled from source code, you need to add the --with-compat --with-threads parameters when executing configure to activate dynamic module support.

DebianUbuntuCentOSFreeBSD 12/13
Connect the Nginx repository:

Debian 10
# echo "deb http://nginx.org/packages/debian/ buster nginx" > /etc/apt/sources.list.d/nginx.list
# wget -O- https://nginx.org/packages/keys/nginx_signing.key | apt-key add -
Debian 11
# echo "deb http://nginx.org/packages/debian/ bullseye nginx" > /etc/apt/sources.list.d/nginx.list
# curl -s https://nginx.org/packages/keys/nginx_signing.key | gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/trusted.gpg --import
# chmod 644 /etc/apt/trusted.gpg.d/trusted.gpg 

Install Nginx:

# apt update && apt upgrade
# apt install nginx
Connect the Nginx repository:

Ubuntu 18.04
# echo "deb http://nginx.org/packages/ubuntu/ bionic nginx" > /etc/apt/sources.list.d/nginx.list
# wget -O- https://nginx.org/packages/keys/nginx_signing.key | apt-key add -
Ubuntu 20.04
# echo "deb http://nginx.org/packages/ubuntu/ focal nginx" > /etc/apt/sources.list.d/nginx.list
# wget -O- https://nginx.org/packages/keys/nginx_signing.key | apt-key add -
Ubuntu 22.04
# echo "deb http://nginx.org/packages/ubuntu/ jammy nginx" > /etc/apt/sources.list.d/nginx.list
# curl -s https://nginx.org/packages/keys/nginx_signing.key | gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/trusted.gpg --import
# chmod 644 /etc/apt/trusted.gpg.d/trusted.gpg 

Install Nginx:

# apt update && apt upgrade
# apt install nginx
CentOS 7
Connect the Nginx repository:

# rpm -Uvh https://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm

Install packages:

# yum update
# yum install nginx
CentOS 8 Stream
Add the Nginx repository by bringing the file /etc/yum.repos.d/nginx.repo to the form:
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

Install packages:

# dnf update
# dnf install nginx
CentOS 9 Stream
Add the Nginx repository by bringing the file /etc/yum.repos.d/nginx.repo to the form:

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

Install packages:

# dnf update
# dnf install nginx
Update package list:

# portsnap fetch extract

Bringing the file /etc/rc.conf to the form:

...
nginx_enable="YES"
...

Install the package:

# pkg install -y nginx
# service nginx start

The dynamic module Nemesida WAF is available for:

  • Nginx stable from 1.12;
  • Nginx mainline from 1.15;
  • Nginx Plus from R16.

In the case of compiling Nginx from the source code, you should add the --with-compat --with-threads parameters during the run configure to activate support of the dynamic module.

Installation

Set the operating system ID:

# rm -f /etc/machine-id
# /bin/systemd-machine-id-setup
DebianUbuntuCentOSFreeBSD 12/13
Debian 10
Install the packages:

# apt update && apt upgrade
# apt install python3 python3-venv python3-pip python3-dev python3-setuptools librabbitmq4 libcurl3-gnutls libcurl4-openssl-dev libc6-dev gcc libmaxminddb0 g++ memcached rabbitmq-server
Debian 11
Install the packages:

# apt update && apt upgrade
# apt install python3 python3-venv python3-pip python3-dev python3-setuptools librabbitmq4 libcurl3-gnutls libcurl4-openssl-dev libc6-dev gcc libmaxminddb0 g++ memcached rabbitmq-server
# apt install nwaf-dyn-1.22

where 1.22 is the version of the installed Nginx. For example, package of the dynamic module nwaf-dyn-1.22 is intended for work with Nginx version 1.22 and nwaf-dyn-plus-rX (where X is the number of release, started with R16) is intended for work with the last version of Nginx Plus (for example: nwaf-dyn-plus-r16).

During the installation of the module, the following PIP packages are additionally installed:
wheel python pandas requests psutil sklearn schedule simple crypt fuzzywuzzy levmatch python-Levenshtein unidecode fsspec func_timeout url-normalize netaddr pymemcache logutils openapi-schema-validator strict-rfc3339 rfc3339-validator isodate

Ubuntu 18.04
Install the packages:

# apt update && apt upgrade
# apt install python3 python3-venv python3-pip python3-dev python3-setuptools librabbitmq4 libcurl3-gnutls libcurl4-openssl-dev libc6-dev gcc libmaxminddb0 g++ memcached rabbitmq-server openapi-schema-validator strict-rfc3339 rfc3339-validator isodate
Ubuntu 20.04
Install the packages:

# apt update && apt upgrade
# apt install python3 python3-venv python3-pip python3-dev python3-setuptools libcurl3-gnutls librabbitmq4 libcurl4-openssl-dev libc6-dev gcc libmaxminddb0 g++ memcached rabbitmq-server
Ubuntu 22.04
Install the packages:

# apt update && apt upgrade
# apt install python3 python3-venv python3-pip python3-dev python3-setuptools libcurl3-gnutls librabbitmq4 libcurl4-openssl-dev libc6-dev gcc libmaxminddb0 g++ memcached rabbitmq-server
# apt install nwaf-dyn-1.22

where 1.22 is the version of the installed Nginx. For example, package of the dynamic module nwaf-dyn-1.22 is intended for work with Nginx version 1.22 and nwaf-dyn-plus-rX (where X is the number of release, started with R16) is intended for work with the last version of Nginx Plus (for example: nwaf-dyn-plus-r16).

During the installation of the module, the following PIP packages are additionally installed:
wheel python pandas requests psutil sklearn schedule simple crypt fuzzywuzzy levmatch python-Levenshtein unidecode fsspec func_timeout url-normalize netaddr pymemcache logutils openapi-schema-validator strict-rfc3339 rfc3339-validator isodate

Configure the SELinux policy or deactivate it with the command:

# setenforce 0

then bring the file /etc/selinux/config to the form:

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted
CentOS 7
Enable direct connection to nemesida-security.com:443.

Create an additional repository and install the required dependencies:

# rpm -Uvh https://nemesida-security.com/repo/nw/centos/nwaf-release-centos-7-1-6.noarch.rpm
# yum update
# yum install epel-release

Install the packages:

# yum update
# yum install python36 python36-devel python36-setuptools python36-pip systemd openssl libcurl-devel gcc libmaxminddb memcached rabbitmq-server
# yum install nwaf-dyn-1.22

where 1.22 is the version of the installed Nginx. For example, package of the dynamic module nwaf-dyn-1.22 is intended for work with Nginx version 1.22 and nwaf-dyn-plus-rX (where X is the number of release, started with R16) is intended for work with the last version of Nginx Plus (for example: nwaf-dyn-plus-r16).

During the installation of the module, the following PIP packages are additionally installed:
wheel python pandas requests psutil sklearn schedule simple crypt fuzzywuzzy levmatch python-Levenshtein unidecode fsspec func_timeout url-normalize netaddr pymemcache logutils openapi-schema-validator strict-rfc3339 rfc3339-validator isodate

CentOS 8 Stream
Add the RabbitMQ repository by bringing the file /etc/yum.repos.d/RabbitMQ.repo to the form:

[rabbitmq_erlang]
name = rabbitmq_erlang
baseurl = https://packagecloud.io/rabbitmq/erlang/el/8/$basearch
repo_gpgcheck = 0
gpgcheck = 0
enabled = 1

[rabbitmq_server]
name = rabbitmq_server
baseurl = https://packagecloud.io/rabbitmq/rabbitmq-server/el/8/$basearch
repo_gpgcheck = 0
gpgcheck = 0
enabled = 1

Install the packages:

# dnf update
# dnf install dnf-utils
# dnf install python39 python39-devel python39-setuptools python39-pip systemd openssl libcurl-devel gcc libmaxminddb memcached rabbitmq-server
# dnf install nwaf-dyn-1.22

where 1.22 is the version of the installed Nginx. For example, package of the dynamic module nwaf-dyn-1.22 is intended for work with Nginx version 1.22 and nwaf-dyn-plus-rX (where X is the number of release, started with R16) is intended for work with the last version of Nginx Plus (for example: nwaf-dyn-plus-r16).

CentOS 9 Stream
Install the packages:

# dnf update
# dnf install dnf-utils
# dnf install centos-release-rabbitmq-38
# dnf install python3 python3-devel python3-setuptools python3-pip systemd openssl libcurl-devel gcc libmaxminddb memcached rabbitmq-server
# dnf install nwaf-dyn-1.22

where 1.22 is the version of the installed Nginx. For example, package of the dynamic module nwaf-dyn-1.22 is intended for work with Nginx version 1.22 and nwaf-dyn-plus-rX (where X is the number of release, started with R16) is intended for work with the last version of Nginx Plus (for example: nwaf-dyn-plus-r16).

During the installation of the module, the following PIP packages are additionally installed:
wheel cython pandas requests psutil sklearn schedule simple-crypt fuzzywuzzy levmatch python-Levenshtein unidecode fsspec func_timeout url-normalize netaddr pymemcache logutils openapi-schema-validator strict-rfc3339 rfc3339-validator isodate

Update package list:

# portsnap fetch extract

Bringing the file /etc/rc.conf to the form:

...
dbus_enable="YES"
rabbitmq_enable="YES"
...

Install the packages:

# pkg install -y wget memcached libmaxminddb dbus gnutls curl gcc lapack Atlas-devel openblas openssl bash
# service dbus start
# pkg install -y python39 py39-setuptools py39-virtualenv py39-pip py39-cython py39-wheel
# pkg install -y rabbitmq rabbitmq-c
# service rabbitmq start
# curl "https://nemesida-security.com/repo/nw/freebsd/12/nwaf-dyn-1.22-5.1-1568.pkg" --output nwaf-dyn-1.22-5.1-1568.pkg
# pkg install -y nwaf-dyn-1.22-5.1-1568.pkg

where 1.22 is the version of the installed Nginx, and 5.1-1568 is the version of the nwaf-dyn package.

Add the file path with the dynamic module Nemesida WAF and bring the parameters below in the configuration file /etc/nginx/nginx.conf to the form:

load_module /etc/nginx/modules/ngx_http_waf_module.so;
...
worker_processes auto;
...
http {
...
    ##
    # Nemesida WAF
    ##

    ## Request body is too large fix
    client_body_buffer_size 25M;

    include /etc/nginx/nwaf/conf/global/*.conf;
...
}

Errors:

nginx: [emerg] module "/etc/nginx/modules/ngx_http_waf_module.so" version 1017010 instead of 1022000 in /etc/nginx/nginx.conf:1

The error occurs when the versions of the installed dynamic module Nemesida WAF and Nginx do not match. In this case, 1017010 is the version of Nginx 1.17.10, for which the nwaf-dyn module was compiled, and 1022000 is Nginx 1.22.0 installed on the server. The dynamic module package nwaf-dyn-1.22 is designed to work with Nginx version 1.22, and nwaf-dyn-plus-r22 is designed to work with NGINX Plus R22.

Initial setup

After installing the module, it is necessary to make the initial configuration by specifying the following parameters in file /etc/nginx/nwaf/conf/global/nwaf.conf:

Parameters of nwaf.conf
Default parameter
Description of the parameter

nwaf_license_key

The parameter for installing the Nemesida WAF license key. The key is also used by the Nemesida AI module if the module is hosted on the same server. It is prohibited to use the same license key on two or more instances of the component nwaf-dyn.

With the specified invalid license key (including the default value nwaf_license_key none), Nemesida WAF will continue to work with the functionality Nemesida WAF Community Edition.

nwaf_sys_proxy
The parameter defines the proxy server address for accessing to external resources (license key verification, getting signatures, etc.).

Example:

nwaf_sys_proxy http://proxy.example.com:3128;

For CentOS 7, it is allowed to use a proxy server only according to the HTTP scheme.

nwaf_api_proxy
The parameter defines the proxy server address for accessing the Nemesida WAF API.

Example:

nwaf_api_proxy http://proxy.example.com:3128;

For CentOS 7, it is allowed to use a proxy server only according to the HTTP scheme.

nwaf_api_conf

The address of the Nemesida WAF API server for sending information about detected anomalies.

host – the parameter defines the address of the Nemesida WAF API server for sending information about attacks, the results of the Nemesida WAF Scanner and Nemesida AI. With the host=none option, data will not be transmitted to the Nemesida WAF API.

If the Nemesida WAF API are not configured yet, the parameters nwaf_api_conf and nwaf_api_proxy can be specified later.

After making changes, restart the server or restart the services and check their operation:

# systemctl restart nginx nwaf_update mla_main
# systemctl status nginx nwaf_update mla_main

The nwaf_update service is responsible for obtaining the signatures of the Nemesida WAF module (/etc/nginx/nwaf/rules.bin). To test the signature method of detecting attacks, when sending a request to http://YOUR_SERVER/nwaftest, the server must return a 403 response code.

The Nemesida WAF module processes only the request transmitted to the final application. If the settings of the Nginx software prevent the transmission of calls (returning, for example, a 301 or 403 response code), such requests will not be processed by the Nemesida WAF module.

If the signature set would be changed on the server nemesida-security.com nwaf_update service will automatically update rules.bin file and apply the changes. If the nwaf_update service is deactivated during the signature set updating on the server, the download of the new version of signature set will be after the service nwaf_update starts.

Additional configuration

The configuration file of the dynamic module Nemesida WAF additionally contain an extended list of available parameters that cannot be configured using cloud, local WebApp or API.

nwaf.conf parameters
Default setting
Description of the parameter
nwaf_host_enable

The parameter that activates the Nemesida WAF functionality for the listed virtual hosts. With the nwaf_host_enable *; parameter, analysis will be performed for all virtual hosts.

Example for use single value:

nwaf_host_enable *;
nwaf_host_enable example.com;
nwaf_host_enable *.example.com;

Example for use many values:

nwaf_host_enable example.com, 1.example.com;
nwaf_host_enable example.com, *.example.com;
nwaf_ban_captcha_host*

A parameter that activates the mechanism for unlocking an IP address for virtual hosts using captcha for requests detected by the Nemesida AI MLC module as BT 7, BT 9 or BT 10. It is allowed to use a wildcard value.

Example:

nwaf_ban_captcha_host *;
nwaf_ban_captcha_host example.com;
nwaf_ban_captcha_host *.example.com;

More detailed information about the functionality is available in in the corresponding section.

nwaf_ban_captcha_path
nwaf_ban_captcha_url

A parameter that determines the location of the captcha page.

Example:

nwaf_ban_captcha_path /captcha_path;

For specify the URL of an arbitrary page with captcha on the Internet, use the nwaf_ban_captcha_url parameter.

Example:

nwaf_ban_captcha_url http://example.com/captcha_path;

The parameter takes precedence over nwaf_ban_captcha_path when used at the same time.

For the correct work of unlocking mechanism, you must activate the nwaf_captcha_unban parameter for a specific URL. Using one instance of Nemesida WAF to protect both the web application and the captcha page will lead to incorrect operation of the unlocking mechanism.

nwaf_ban_captcha_token

A secret token that is used by the mechanism for removing an IP address from the blocked list when using a captcha.

An arbitrary sequence of characters is accepted as the parameter value.

Example:

nwaf_ban_captcha_token 01b307acba4f54f55aafc33bb06bbbf6ca803e9a;

After applying the parameter, it must also be specified in a web application with a captcha.

nwaf_mla

Settings of interaction with the Nemesida AI MLA module, where mla_score is the threshold option, upon reaching which the decision to block the request is transmitted to the Nemesida AI MLA module.

Signatures with threshold value is 12 are blocked without sending in Nemesida AI MLA module.

For the commercial version of Nemesida WAF, the parameter is required to control Nginx operation using the Nemesida WAF dynamic module.

nwaf_rmq

Configuring the interaction subsystem with RabbitMQ software. Received by the Nemesida WAF dynamic module requests is sent for storage to the local RabbitMQ service, from where it is collected for subsequent processing by the Nemesida AI MLC module. The process of receiving data by the Nemesida AI MLC module is recommended to be performed using a secure connection.

To do this, make changes to the configuration file nginx.conf or rabbitmq.conf on each VM with the dynamic module installed.

Configuration example for nginx.conf:

...
stream {
        server {
                listen 5673 ssl;
                proxy_pass 127.0.0.1:5672;
                ssl_certificate /etc/nginx/SSL/crt/example.ru.crt;
                ssl_certificate_key /etc/nginx/SSL/private/example.ru.key;
       }
}
...

The listen 5673 ssl; parameter specifies the port on which the server will accept requests with a secure connection.

For security reasons, it is recommended to allow access to servers only from the IP addresses where the Nemesida AI MLC module is installed, and certificates used for secure connection must be trusted for them.

nwaf_clamav

Activation of the mechanism for sending the body of POST and PUT requests to the ClamAV module.

For analyzing only file content from the request body with Content-Type: multipart/form-data, use the FILE_ONLY option.

The file content of the PUT request body is transferred regardless of the FILE_ONLY value.

nwaf_clamav_wl

Configuring the blocking exclusion list for the contents of the request body or downloadable file by the MD5 amount (the MD5 amount is contained in the error.log of the Nginx software).

Example of a log entry:

Nemesida WAF: blocked by ClamAV, stream: Eicar-Test-Signature FOUND, md5: 44d88612fea8a8f36de82e1278a-bb02f, ...

Example of WL rule:

nwaf_clamav_wl 44d88612fea8a8f36de82e1278a-bb02f
nwaf_geoip_db_path

The parameter defining the location of the file with the GeoIP2 base. Used by the extended locking mechanism.

Example:

nwaf_geoip_db_path /opt/geoip/GeoLite2-City.mmdb;

The file is available for download on the official site (City database). After unpacking the archive, the file with the extension .mmdb must be placed in the appropriate directory and given read access to the Nginx web server.

nwaf_log_mr_all

Activation of the parameter for recording information about all occurrences of blocking rules (attack signatures) in the Nginx software error log. By default, the parameter is deactivated (commented out). When a parameter is deactivated, only the signature is written to the error log of the Nginx software, which led to blocking the request or fixing the signature without further blocking (in the LM mode).

Using thenwaf_log_mr_all domain=example.com; parameter the record of the recorded occurrances will do only for specific domain. For the domain option, strict matching and wildcard values are allowed: example.com, .example.com and *.example.com.

nwaf_captcha_unban*

Activation/deactivation of the mechanism for unlocking an IP address using captcha.

Example:

nwaf_captcha_unban on;
nwaf_check_bot_name

This parameter is used for defining search engine robots. Blocked requests that fall under the parameter do not increase the value of the rate counter and cannot cause the IP address to be blocked. The first parameter value is defined in the User-Agent zone. The second parameter value defines the host name obtained by reverse IP address conversion. If the second value is not set, it is considered equal to the first one.

Example:

nwaf_check_bot_name "example.com" "example.net";
nwaf_check_bot_name "example.com";
nwaf_check_bot_name "bingbot" "msn.com";
nwaf_check_bot_name "yandex.ru";

* Activated in the virtual host settings.

Managing settings using web application and API
To manage the settings of the Nemesida WAF dynamic module settings, use one of the methods available for your plan:

LightBusinessEnterprise

To configure, use the cloud WebApp.

To configure, use the cloud WebApp or API.

To configure, use the using local WebApp or API.

Settings made using the WebApp and API calls (settings, exclusion rules (WL), extended blocking rules (ERL), list of IP addresses to block (BL) and a list of URLs sent to the Nemesida AI MLA module for analysis of the compliance of the request with its schema in OpenAPI format) are stored in the files of the /etc/nginx/nwaf/conf/global/db directory. Changing the contents of the files is done by the Nemesida AI MLA module, but Nginx also needs to be given read access to this directory.

Using Nemesida WAF in passive mode
It is necessary to set up traffic mirroring from the main web server (through which calls to the web application are made)to the server with the installed Nemesida WAF software, to working Nemesida WAF in passive mode. You must make changes to the files on every server:

1. On the main server (without the Nemesida WAF module installed), configure traffic mirroring according to the guidelines of the installed web server (Nginx, Apache2, Microsoft IIS and others).

An example of Nginx setting for traffic mirroring

If using the Nginx web server, make the necessary changes to the virtual host file:

upstream mirror_upstream {
        server nemesida_waf_server:port;
        server 127.0.0.1:88 backup;

}

server {
        listen  127.0.0.1:88 default_server;
        return 200 "Response code: 200";
        add_header Content-Type text/plain;
        access_log off;
}
server {
        ...
        location / {
                mirror /mirror;
                root /var/www/html;
                proxy_pass      http://mirror_upstream;
                include         proxy_params;
        }

        location = /mirror {
                   internal;
                   proxy_pass http://mirror_upstream$request_uri;
                   proxy_connect_timeout 10s;
                   proxy_send_timeout 10s;
                   proxy_read_timeout 15s;
    }

}

nemesida_waf_server is the address of the server with the Nemesida WAF module installed, to which duplicate traffic will be transmitted.

2. On the server with the installed Nemesida WAF module, bring the configuration file of the virtual host Nginx to the form:

server {
        ...
        
        location / {
                proxy_pass http://127.0.0.1:86/;
        }
}

server {
        listen  86;
        index   index.html;
        root    /var/www/html;

        location / {
                 return 200;
                 add_header Content-Type text/plain;
        }
}

3. On the server with the Nemesida WAF module installed, bring the /etc/nginx/nwaf/conf/global/nwaf.conf file to the form:

...
nwaf_limit rate=5r/m block_time=0;
...

4. To get information from the main web server about the source IP address of the client, on the server with the Nemesida WAF module installed, bring the file /etc/nginx/nginx.conf to the form:

server {
...
set_real_ip_from x.x.x.x;
real_ip_header X-Real-IP;
real_ip_recursive on;
}

x.x.x.x is the address of the main web server that duplicates traffic to the server with the Nemesida WAF module installed. The source IP address of the client is transmitted by the main web server in the header X-Real-IP.

To use the Nginx functionality, it must contain the ngx_http_realip_module module. Nginx installed from the official repository contains the specified module by default.

More information is available on the official page of the Nginx documentation.

5. After changing restart the Nginx on every server.

Using Nemesida WAF in reverse proxy mode

To use a web server with installed Nginx and Nemesida WAF as an intermediate server, you should create corresponding file of the virtual host (for example /etc/nginx/conf.d/example.com.conf).

Example of the virtual host file
server {
        server_name  site.example.com;
        listen 80;

        location / {
                proxy_pass http://x.x.x.x;
        }
}

where x.x.x.x is the address of destination server with the web application.

More information is available on the official page of the Nginx documentation.

Signature management and virtual patching

To create exclusion (WL) and blocking (ERL) rules, use cloud, local WebApp and API.

Virtual patching

Nemesida WAF virtual patching protects websites from existing uncorrected vulnerabilities (including “zero day”), blocking attempts to exploit them, while not disrupting the operation of the web application. The application of virtual patching rules allows developers to focus on fixing vulnerabilities without the need for urgent code changes. Virtual patching allows you to block all attempts to exploit a known vulnerability on the fly, controlling the attack zone in a special way.

Nemesida WAF uses two sources of virtual patch generation: automatically, by the module Nemesida AI, and manually, using cloud, local WebApp and API calls.

Request processing statuses (BT)

Each request processed by the Nemesida WAF module is assigned a blocking identifier (BT – blocking type).
The identifier can be assigned regardless of whether the request was blocked.

The pivot table shows the types of identifiers and their corresponding request processing status.

0 The request was not blocked.
1 The request is blocked by signature method and the request did not contain any signature with the score = 12.
2 The request is blocked by signature method and the request contained a signature which has the score = 12.
3 The request is blocked by Nemesida AI MLA.
4 The request is blocked by ClamAV module.
5 The request is blocked because of the internal error.
6 The request is blocked because of the oversubscription of blocked requests from one IP address.
7 The request is detected like the brute force attempt and blocked by Nemesida AI MLC.
8 The request is blocked by Nemesida AI MLC (additional traffic analysis of all nonblocked requests by Nemesida WAF module) and is managed by ai_extra parameter in mlc.conf file.
9 The request is detected as a flood attempt and blocked by the Nemesida AI MLC.
10 The request is detected like the DDoS attacks and blocked by Nemesida AI MLC.
14 The request format does not match the specified scheme.

For BT 1, 2, 3, 4, 8 events, the nwaf_limit parameter in the nwaf.conf file allows you to adjust the allowed number of blocked requests. If the allowed number of requests specified by the rate option is exceeded, the IP address will be blocked for the time (in seconds) specified in block_time.

For BT 7, 9, 10 events the blocking of the IP address of the request source will occur after the first blocked request, regardless of the value of the rate parameter (the allowed number of blocked requests) in nwaf_limit.

Nginx optional headers

Optional header $nwaf_block_type

Nemesida WAF allows to use special header, which determinative the result of the request processing. To activate it required to add parameter add_header NemesidaWAF-BT $nwaf_block_type always; into http, server or location area of the nginx configuration file.

Example of using the header

  • Set the header into the server area:
    server {
       ...
       add_header NemesidaWAF-BT $nwaf_block_type always;
       ...
    }
    

    and restart nginx.

  • Execute the request: curl -i localhost/nwaftest.

The server’s answer will contain the information about the status of the request processing in the NemesidaWAF-BT header:

HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Wed, 12 Feb 2020 19:05:26 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
NemesidaWAF-BT: 2
...

In this case the status is 2. It means that the request was blocked because of the attack’s signature entry with the score equal to 12 (nwaftest). More information about the request processing status is available in the corresponding paragraph. This header can be useful during the generation of the customized page of the server answer (for example if the request is blocked).

Optional header $nwaf_cc

Nemesida WAF allows you to use a special header that determines the result of blocking a request by country using extended request blocking rules. To activate it, you need to add the parameter add_header NemesidaWAF-CC $nwaf_cc always; to the http, server or location of the configuration file nginx.

Example of using the header

  • Set the header to the server area:
    server {
       ...
    add_header NemesidaWAF-CC $nwaf_cc always;
    ...
    }
    

    and restart nginx.

  • Execute the request: curl -i example.com

The server response in the header NemesidaWAF-CC will contain information about the blocking status:

HTTP/1.1 403 Forbidden
Server: nginx/1.16.1
Date: Wed, 12 Feb 2020 19:05:26 GMT
Content-Type: text/html
Content-Length: 153
Connection: keep-alive
NemesidaWAF-CC: 1
...

In this case, the status is 1. This means that the request was blocked by the country field. If the rule is compiled using additional fields, for example, body or headers, then the header will not be applied when blocking. The exceptions are the fields vhost and url.

Unlocking an IP address using captcha
If suspicious activity is detected, Nemesida WAF allows you to block the IP address of the source of requests for a certain time (the duration of the block is regulated by the nwaf_limit option in the nwaf.conf configuration file). Using the captcha functionality, the user can unlock their own IP address if it has been identified as a source of brute force attacks (BT 7), floods (BT 9) or denial of service attacks (BT 10).

For correct work of the IP address unlocking mechanism, you need to activate the nwaf_captcha_unban parameter by adding it in the virtual host file to the server section for a specific URL address. Example of activating the nwaf_captcha_unban parameter

server {
    listen  80;
    server_name example.com;

    location /captcha_ip_unban_path {
             ...
             nwaf_captcha_unban on;
             ...
    }
    ...
}

Also, you need to setup a web application with a captcha. Detailed instructions for integrating Nemesida WAF with reCAPTCHA functionality can be found at link.

After activating the nwaf_captcha_unban on; parameter and restarting Nginx, the IP address unblocking functionality becomes available for the target URL address with the nwaf_captcha_unban option set. For example: example.com/captcha_ip_unban_path.

If the answer is correct, the web application with captcha sends a request delete_banned_ip to the Nemesida WAF module to unlock the IP address. The user will then be redirected to the original page.

For security reasons, it is recommended to allow requests to the server URL with the Nemesida WAF dynamic module installed and the nwaf_captcha_unban IP address unlocking parameter activated only from the IP address of the server with captcha.

Configuring interaction with ClamAV software
After installing Nemesida WAF package the functionality of interaction with ClamAV software is disabled by default, since it can be a source of false blocking of some requests to the Web application (depending on the current state of the ClamAV signature analysis database). Use this functionality at your discretion.

To activate antivirus protection, install ClamAV software on the server with the configured Nemesida WAF software, if it has not done yet.

Installation example for Debian 10:

# apt install clamav-daemon

The interaction with the ClamAV software is enabled by activating the nwaf_clamav configuration parameter in the /etc/nginx/nwaf/conf/global/nwaf.conf file and reduction of the /etc/clamav/clamd.conf file to a look:

...
TCPSocket 3310
TCPAddr   127.0.0.1
...

After changing restart the Nginx software.