A guide to installing, initial configuration and operating the filtering node with 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:

DebianUbuntuCentOSFreeBSD 12/13Docker
# apt install apt-transport-https gnupg2 curl
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
Debian 12
# echo "deb https://nemesida-security.com/repo/nw/debian bookworm nwaf" > /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 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
The installation of the Nemesida WAF components takes place without connecting the repository. Instructions for installing the component are provided below.
Information about using Nemesida WAF in a Docker container is available in corresponding section.

Setup a web server

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

DebianUbuntuCentOSFreeBSD 12/13
Connect the Nginx repository:

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 
Debian 12
# echo "deb http://nginx.org/packages/debian/ bookworm 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 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:

# freebsd-update fetch
# freebsd-update install
# pkg upgrade -y

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

...
kern.ipc.somaxconn=16384
...

Run the command to apply the changes before restarting the server:

# sysctl kern.ipc.somaxconn=16384

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

...
nginx_enable="YES"
...

Install the package:

# pkg install -y nginx
# service nginx start

Installation

In the case of measures aimed at configuring the OS to ensure its security (for example, based on recommendations CIS Benchmarks), before installing the package, you must remove the security flags rw, nosuid, noexec, nodev for the /tmp directory where temporary files used during installation are stored.

The dynamic module is available for:

  • Nginx stable from 1.16;
  • Nginx mainline from 1.19;
  • Nginx Plus from R26.

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.

Set the operating system ID:

# rm -f /etc/machine-id
# /bin/systemd-machine-id-setup
DebianUbuntuCentOSFreeBSD 12/13
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 g++ memcached rabbitmq-server
Debian 12
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 g++ memcached rabbitmq-server
# apt install nwaf-dyn-1.24

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

During the installation of the module, the following PIP packages are additionally installed:
wheel cython pandas requests psutil scikit-learn schedule simple-crypt fuzzywuzzy levmatch python-Levenshtein unidecode fsspec func_timeout url-normalize netaddr pymemcache logutils openapi-schema-validator strict-rfc3339 rfc3339-validator isodate jsonref fastapi uvicorn[standard] gunicorn python-multipart pyarrow

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 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 g++ memcached rabbitmq-server
# apt install nwaf-dyn-1.24

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

During the installation of the module, the following PIP packages are additionally installed:
wheel cython pandas requests psutil scikit-learn schedule simple-crypt fuzzywuzzy levmatch python-Levenshtein unidecode fsspec func_timeout url-normalize netaddr pymemcache logutils openapi-schema-validator strict-rfc3339 rfc3339-validator isodate jsonref fastapi uvicorn[standard] gunicorn python-multipart pyarrow

For the openapi-schema-validator package to work correctly, you must provide access to json-schema.org:443.

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
Install the packages:

# yum update
# yum install centos-release-scl
# yum install rh-python38 rh-python38-python-pip rh-python38-python-devel rh-python38-python-setuptools systemd openssl librabbitmq libcurl-devel gcc memcached rabbitmq-server
# yum install nwaf-dyn-1.24

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

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 memcached rabbitmq-server
# dnf install nwaf-dyn-1.24

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

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 memcached rabbitmq-server
# dnf install nwaf-dyn-1.24

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

During the installation of the module, the following PIP packages are additionally installed:
wheel cython pandas requests psutil scikit-learn schedule simple-crypt fuzzywuzzy levmatch python-Levenshtein unidecode fsspec func_timeout url-normalize netaddr pymemcache logutils openapi-schema-validator strict-rfc3339 rfc3339-validator isodate jsonref fastapi uvicorn[standard] gunicorn python-multipart pyarrow

Update package list:

# freebsd-update fetch
# freebsd-update install
# pkg upgrade -y

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

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

Install the packages:

# pkg install -y wget memcached dbus gnutls curl gcc lapack Atlas-devel openblas openssl bash
# service dbus start
# pkg install -y python310 py310-setuptools py310-cython py310-wheel cmake rust sudo
# pkg install -y rabbitmq rabbitmq-c
# service rabbitmq start

Nginx:

# curl "https://nemesida-security.com/repo/nw/freebsd/12/nwaf-dyn-1.24-5.1-1568.pkg" --output nwaf-dyn-1.24-5.1-1568.pkg
# pkg install -y nwaf-dyn-1.24-5.1-1568.pkg

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

Angie:

# curl "https://nemesida-security.com/repo/nw/freebsd/12/nwaf-angie-1.2.0-5.1-2835.pkg " --output nwaf-angie-1.2.0-5.1-2835.pkg 
# pkg install -y nwaf-angie-1.2.0-5.1-2835.pkg

where 1.20 is the version of the installed Angie, and 5.1-2835 is the version of the nwaf-angie package.

During the installation of the module, the following PIP packages are additionally installed:
wheel cython pandas requests psutil scikit-learn schedule simple-crypt fuzzywuzzy levmatch python-Levenshtein unidecode fsspec func_timeout url-normalize netaddr pymemcache logutils openapi-schema-validator strict-rfc3339 rfc3339-validator isodate jsonref fastapi uvicorn[standard] gunicorn python-multipart

Configuring
Add the file path with the dynamic module 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 1024000 in /etc/nginx/nginx.conf:1

The error occurs when the versions of the installed dynamic module 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 1024000 is Nginx 1.24.0 installed on the server. The dynamic module package nwaf-dyn-1.24 is designed to work with Nginx version 1.24, and nwaf-dyn-plus-r26 is designed to work with NGINX Plus R26.

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;

It is allowed to use authentication parameters when using a proxy server.

Example:

nwaf_sys_proxy http://<user>:<password>@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;

It is allowed to use authentication parameters when using a proxy server.

Example:

nwaf_api_proxy http://<user>:<password>@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.

Example:

nwaf_api_conf host=http://api.example.com:8080/nw-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 rabbitmq-server memcached nwaf_update mla_main api_firewall
# systemctl status nginx rabbitmq-server memcached nwaf_update mla_main api_firewall

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.

For the RabbitMQ service to work correctly, you need to configure its launch before launching the Nginx service. To do this, edit the file /lib/systemd/system/rabbitmq-server.service by adding at the end of the Unit section string Before=nginx.service.

Example:

[Unit]
Description=RabbitMQ Messaging Server
After=network.target epmd@.socket
Wants=network.target epmd@.socket
Before=nginx.service

After making changes, apply them by running the command:

# systemctl daemon-reload

After configuration of the module, you must check for errors in the component operation event logs /var/log/nginx/error.log, /var/log/nwaf/mla.log and /var/log/nwaf/naf/error.log.

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

nwaf.conf parameters
Default setting
Description
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
or
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

The parameter for configuring interaction with the Nemesida AI MLA module, where mla_score is an option for the threshold value at which the decision to block the request is passed to the Nemesida AI MLA module.

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

nwaf_mla_api

The parameter for configuring interaction with the Nemesida AI MLA module in cases of transmitting a request for analysis of its specification in the OpenAPI format but without analysis by the machine learning module.

nwaf_mla_mgmt
The parameter for configuring interaction with the Nemesida AI MLA module for service purposes (determining the geographical location based on IP address, restarting Nginx to apply settings on the filtering node, etc.).
nwaf_rmq

Configuring the interaction subsystem with RabbitMQ software. Received by the 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.com.crt;
                ssl_certificate_key /etc/nginx/SSL/private/example.com.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.

Example:

nwaf_clamav 127.0.0.1:3310;
nwaf_clamav 127.0.0.1:3310 FILE_ONLY;
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_icap_av

Activation of interaction with antivirus solutions using the ICAP protocol.

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.

The PRIVIEW_SIZE parameter sets the value of the corresponding header for the ICAP server. By default, 1024.

Example:

nwaf_icap_av 127.0.0.1:1344/avscan;
nwaf_icap_av 127.0.0.1:1344/avscan FILE_ONLY;
nwaf_icap_av 127.0.0.1:1344/avscan PREVIEW_SIZE=1024;
nwaf_icap_av 127.0.0.1:1344/avscan FILE_ONLY PREVIEW_SIZE=1024;

To work correctly, you must additionally configure the icap service.

nwaf_icap_av_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: the request has been blocked by ICAP AV interface, Win.Test.EICAR_HDB-1 FOUND, md5: 44d88612fea8a8f36de82e1278a-bb02f, ...

Example of WL rule:

nwaf_icap_av_wl FILE-MD5-HASH;
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.

When configuring the filtering node, you may additionally need to make changes to the /etc/nginx/nwaf/mla.conf file:

mla.conf parameters
Default setting
Description
ml_socket

The socket receives connections from the dynamic module when transmitting a request for additional analysis by machine learning or a one-time transmission of a request for processing by machine learning and analysis for compliance with its specification in the OpenAPI format.

Default value:

ml_socket = 127.0.0.1:5101
api_socket

The socket receives connections from a dynamic module in cases of transmitting a request for analysis of its specification in the OpenAPI format.

Default value:

api_socket = 127.0.0.1:5102
mgmt_socket

The socket receives connections from the dynamic module for service purposes (determining the geographical location based on the IP address, restarting Nginx to apply settings on the filtering node, etc.).

Default value:

mgmt_socket = 127.0.0.1:5103
debug

Activates debugging mode.

Default value:

debug = false

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

# systemctl restart nginx rabbitmq-server memcached nwaf_update mla_main api_firewall
# systemctl status nginx rabbitmq-server memcached nwaf_update mla_main api_firewall

Managing settings using web application and API

To manage the settings of the Nemesida WAF dynamic module settings, use Nemesida WAF Cabinet or API.

Settings made using the Nemesida WAF Cabinet 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.

Additional information

For the correct operation of the dynamic module and Nemesida AI MLA, the following files and directories are located on the filter node:

  • /etc/nginx/nwaf/conf/global/nwaf.conf – a dynamic module configuration file that allows you to perform the initial configuration of the component;
  • /etc/nginx/nwaf/rules.bin – a set of signatures for the correct operation of the signature method of request analysis;
  • /etc/nginx/nwaf/conf/global/db/ – the directory that contains files with dynamic module settings that are installed through the Nemesida WAF Cabinet or Nemesida WAF API (for example, settings.db contains the basic settings of the dynamic module);
  • /etc/nginx/nwaf/conf/openapi/ – the directory that contains the Nemesida AI MLA specifications used, in the format.json required for the Firewall API to work correctly;
  • /etc/nginx/nwaf/ml/ – the directory that contains all the behavioral models used by the Nemesida AI MLA module (files .ml), as well as requests (file mt.json), exported via the Nemesida WAF Cabinet;
  • /etc/nginx/nwaf/conf/nginx – the directory that contains the configuration parameters of the Nginx web server, in the format .conf, set using the Nemesida WAF.

Using Nemesida WAF in monitoring 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 monitoring 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
Setting up a web server with Nginx and Nemesida WAF in reverse proxy mode will allow to use it as an intermediate server.

Signature management and virtual patching

To create exclusion (WL) and blocking (ERL) rules, use Nemesida WAF Cabinet 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 WAF Cabinet 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 or extended blocking rule (ERL).
3 The request is blocked by the Nemesida AI MLA machine learning module based on behavioral analysis.
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 the Nemesida AI MLC machine learning module based on behavioral analysis.
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.
16 The request was sent from an IP address on the “Blocked IPs” list.

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 custom 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 a 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 the IP address unblocking mechanism to work correctly, the options must be activated:

  • nwaf_ban_captcha_host – the virtual host(s) for which it is necessary to activate the mechanism for unblocking IP addresses using a captcha.

    Example:
    nwaf_ban_captcha_host *;
    nwaf_ban_captcha_host example.com;
    nwaf_ban_captcha_host *.example.com;
    

    It is allowed to use a wildcard value: *, example.com, .example.com, *.example.com.

  • nwaf_ban_captcha_path or nwaf_ban_captcha_url – a parameter that determines the location of the captcha page.

    Example:
    nwaf_ban_captcha_path /captcha_path;
    

    or

    nwaf_ban_captcha_url http://example.com/captcha_path;
    

    The nwaf_ban_captcha_url option is used when using the URL of an arbitrary page with a captcha on the Internet.

  • 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 options value.

    Example:
    nwaf_ban_captcha_token 01b307acba4f54f55aafc33bb06bbbf6ca803e9a;
    

    After applying, the value of the option must be specified in the web application with the captcha.

  • You also need to set up a web application with a captcha. Detailed instructions on integrating Nemesis WAF with reCAPTCHA functionality can be found at link.

    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.

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 12:

# 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.