Nemesida WAF Community Edition provides the base web application security against OWASP class attacks based on the signature method. Nemesida WAF Community Edition has its own signatures, detects attacks on web applications with a minimum number of false positives, is updated from the Linux repository, installed and configured in a few minutes.
Nemesida WAF features:
- quick and easy start;
- installation and configuration in 10 minutes;
- minimum false positives;
- installation and update from the repository;
- the ability to connect to an already installed Nginx, starting from version 1.16;
- convenient web interface, the ability to integrate with SIEM systems.
The main limitation of the Community Edition affects the operation of data normalization mechanism (e.g. Base64/HTML Entity/UTF-16 decoding) and Nemesida AI machine learning subsystem, which enables more accurate and ultra-low false positives detection of attacks on web applications (including exploitation of zero-day vulnerabilities). Nemesida WAF Scanner is also unavailable.
To visualize the difference between signature-based analysis and machine learning, you can use the free WAF Bypass Tool, which assesses the security level of a web application.
The tool sends over 2000 requests with various payloads to a WAF-protected web application and collects statistics, which it displays as a table of results.
The tables above clearly show how the use of machine learning increases the accuracy of attack detection. Using only the signature method for detecting attacks allows you to block 47.2% of attacks, and using machine learning increases this figure to 99.78%.
In addition, Nemesida WAF Community Edition modifies the content of attack messages sent to the Nemesida WAF API:
- the
vhost
field is set toexample.com
; - the
referer
field is set toNemesida WAF Community Edition
; - the non-empty
other_headers
field is set toNemesida WAF Community Edition
; - the
WAF ID
field is set toCOMMUNITYEDITION
.
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.
# apt update && apt upgrade # apt install apt-transport-https gnupg2 curl
Add the Nginx repository:
Install Nginx:
# apt install nginx
# apt update && apt upgrade # apt install apt-transport-https gnupg2 curl
Add the Nginx repository:
Install Nginx:
# apt install nginx
# 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
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/rhel/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true
Install the packages:
# dnf update # dnf install nginx
Setup component
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.22
; - Nginx mainline from
1.23
; - Nginx Plus from
R28
.
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
1. Download script;
2. Run the installation script with the command:
# /bin/bash ./4-filtering-node-deploy.sh 'nwaf_lic_key=%Licence key%' 'api_url=%Nemesida WAF API URL%' 'sys_proxy=%Proxy server address%' 'api_proxy=%Proxy server address%'
where:
nwaf_lic_key
– a license key;api_url
– the address of the server from which the Nemesida WAF API component will be accessed after its configuration (e.g.http://api.example.com:8080/nw-api/
);sys_proxy
– (Optional) IP address of the proxy server for component access to external resources (e.g.http://proxy.example.com:3128
);api_proxy
– (Optional) IP address of the proxy server for interacting with the Nemesida WAF API (e.g.http://proxy.example.com:3128
).
Install the packages:
# apt install python3 python3-venv python3-pip python3-dev python3-setuptools librabbitmq4 libcurl3-gnutls libcurl4-openssl-dev libc6-dev gcc g++ memcached rabbitmq-server libmemcached11 # apt install nwaf-dyn-1.26
where 1.26 is the version of the installed Nginx. For example, package of the dynamic module nwaf-dyn-1.26 is intended for work with Nginx version 1.26 and nwaf-dyn-plus-rX (where X is the number of release, started with R28) is intended for work with the last version of Nginx Plus (for example: nwaf-dyn-plus-r28).
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
Install the packages:
# apt install nwaf-dyn-1.26
where 1.26 is the version of the installed Nginx. For example, package of the dynamic module nwaf-dyn-1.26 is intended for work with Nginx version 1.26 and nwaf-dyn-plus-rX (where X is the number of release, started with R28) is intended for work with the last version of Nginx Plus (for example: nwaf-dyn-plus-r28).
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
.
Add the Nemesida WAF repository by bringing the file /etc/yum.repos.d/NemesidaWAF.repo
to the form:
[NemesidaWAF] name=Nemesida WAF Packages for RHEL baseurl=https://nemesida-security.com/repo/nw/rhel/$releasever/$basearch/ gpgkey=https://nemesida-security.com/repo/nw/gpg.key enabled=1 gpgcheck=1
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 security reasons, it is recommended to prohibit external incoming connections to network services, with the exception of connections to Nginx.
When using the automatic installation script, files editing is not required.
Add the path to the file 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; ... }
nginx: [emerg] module "/etc/nginx/modules/ngx_http_waf_module.so" version 1017010 instead of 1026000 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 1026000
is Nginx 1.26.0 installed on the server. The dynamic module package nwaf-dyn-1.26 is designed to work with Nginx version 1.26, and nwaf-dyn-plus-r28 is designed to work with NGINX Plus R28.
Make the necessary changes to the configuration file /etc/nginx/nwaf/conf/global/nwaf.conf
:
Restart the server and test:
# systemctl restart nginx rabbitmq-server memcached nwaf_update # systemctl status nginx rabbitmq-server memcached nwaf_update
After each change to the configuration file
/etc/nginx/nwaf/conf/global/nwaf.conf
, services must be restarted.The
api_firewall
service is not available for the non-commercial version, so the service status can be ignored.
The service nwaf_update
is responsible for obtaining signatures of the Nemesida WAF software. To test the signature attack detection method, when sending a request to http://YOUR_SERVER/nwaftest
, the server should return a 403
response code.
After configuring the module, it is necessary to check the information about errors, which is contained in the module’s event logs:
/var/log/nginx/error.log
;/var/log/nwaf/nwaf_update.log
;/var/log/rabbitmq/rabbit@%hostname%.log
;/var/log/rabbitmq/rabbitmq-server.error.log
.
After Nemesida WAF installation you can install Nemesida WAF API and Nemesida WAF Cabinet, which is intended to visualise and classify the information about attacks and identified vulnerabilities.
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.
Nemesida WAF Community Edition supports a custom set of rules for detecting attacks: personal signatures (RL
), as well as signature exceptions (WL
).
Zones and additional conditions
During the creation of RL
or WL
rules special parameters can be used:
- zones:
URL
,ARGS
,BODY
,HEADERS
,Cookie
,User-Agent
,Content-Type
, etc.; - conditions of using the rule (additional condition, specification of the zone):
$URL
,$ARGS
,$BODY
,$HEADERS
,$Cookie
,$User-Agent
, etc.
Using zones and additional conditions allows to concretize maximally the creating rule. Additional conditions are set by adding prefix $
(for example: "Z:...|$URL:..."
).
An example of using the rule with zone and additional condition: WL ... "Z:ARGS|$URL:/123";
– the rule will work, if the entry zone of the RL
rule will be ARGS
zone and URL will contain an entry /123
.
For the additional conditions zone URL
, it is allowed to specify only the occurrence of a path without a domain.
Example:
/index
/uploads/index.php
Several parameters (zones, additional conditions) in one rule must be separated with the character |
, the following principle of interaction will be used:
- zones interact using the logical principle
OR
, for example:Z:URL|ARGS
; - zones interact with additional conditions using the logical principle
AND
, for example:Z:URL|$ARGS:123
; - additional conditions interact using the logical principle
AND
, for example:Z:...|$ARGS:123|$BODY:123"
.
When used in the additional conditions |
as a regular character, it is necessary to make its single shielding. For example: $URL:abc\|d
– search for the occurrence of abc|d
.
Regular expressions in the additional conditions
It is possible to use regular expressions in the additional conditions. This requires to add to the additional condition postfix _X
(for example: "Z:...|$URL_X:\w+"
).
For use regular expression operators in a rule as regular characters (/
, .
, *
, ?
, !
, {
, }
, [
, ]
, (
, )
, ^
, $
, :
, \
, etc.), they must be double shielding.
Example:
$BODY_X:block\\|page
– search of an entryblock|page
;$BODY_X:data=\\(block-\\\a\\\-in-the-main\\)
– search of an entrydata=(block-\a\-in-the-main)
;$ACCEPT_X:image\\/webp\\\\\*
– search of an entryimage/webp\*
inAccept
headers.
For use in additional conditions the separator as a metacharacter of a regular expression it is necessary to shield it double.
Example:
The rule WL ... "Z:...|$URL_X:/(a\\|b)/";
will bring to URL
which contains /a/
or /b/
.
User-defined signature creation
The user-defined rules of detecting attack signs must be placed in the main configuration file Nemesida WAF (/etc/nginx/nwaf/conf/global/nwaf.conf
). They must be determined by the RL
parameter, must have ID
ranging from 50000 to 99999 and take the following form:
RL ID:50000 "P:select from" "SC:SQL:12" "Z:ARGS";
RL ID:50001 domain=example.com "P:select from" "SC:SQL:12" "Z:ARGS";
RL ID:50002 domain=.example.com "P:select from" "SC:SQL:12" "Z:ARGS";
RL ID:50003 domain=*.example.com "P:select from" "SC:SQL:12" "Z:ARGS";
RL ID:50004 "PX:select\s+from" "SC:SQL:12" "Z:ARGS|$URL:/admin";
RL ID:50005 "P:select from" "SC:SQL:12" "Z:ARGS|$URL:/(admin\\|dev)";
Creating a signature exclusion rule
In case the inquiry falls under action of a signature, in addition to sending the incident to the Nemesida WAF API, the following line will be displayed in the error log of the Nginx software:
Nemesida WAF: the request xxx contains a rule id 1 in zone HEADERS, ...
or, if the request contains a signature with a maximum allowable digital indicator of significance (score
= 12):
Nemesida WAF: the request xxx blocked by rule id 1 in zone HEADERS, ...
where:
1
– attack signature ID;HEADERS
– signature entry zone.
To display absolutely all occurrences of signatures in the request (if there are occurrences), including those occurrences that did not lead to the subsequent blocking of the request, activate the nwaf_log_mr_all;
parameter, in the nwaf.conf
file Nemesida WAF.
The information about current signature list is on the page rlinfo.nemesida-security.com.
Switching the blocking rules to LM mode
Requests that fall under the LM
mode are recorded in the database, but are not blocked. When the rule is triggered, a message will be sent to the Nginx error log and to the Nemesida WAF API about switching the corresponding blocking rule to LM
mode, but the request will not be blocked. The rules for switching to the LM
mode must be defined by the LM
parameter, have the ID
of the corresponding blocking rule and take the following form:
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.