Nginx. AlmaLinux 8. ModSecurity: различия между версиями
Cless (обсуждение | вклад) |
Cless (обсуждение | вклад) |
||
| Строка 335: | Строка 335: | ||
= Custom rules = | = Custom rules = | ||
=== Block request by special parameter in a '''Query string''' === | |||
<code>mkdir /usr/local/nginx/conf/modsec-rules</code> | |||
<code>nano /usr/local/nginx/conf/modsec-rules/custom01.conf</code> | |||
SecRule ARGS:'''''testparam''''' "@contains '''''test123'''''" "id:1234,deny,log,status:403" | |||
<code>nano /usr/local/nginx/conf/modsecurity.conf</code> | |||
... | |||
Include modsec-rules/*.conf | |||
<code>nginx -t</code> | |||
<code>systemctl restart nginx</code> | |||
Try to connect via browser to '''<nowiki>https://cless.pro/index.html?testparam=test123</nowiki>''' with '''testparam=test123'''. | |||
You will get "'''403 Forbidden'''" | |||
BUT try to connect via browser to '''<nowiki>https://cless.pro/index.html?testparam=test</nowiki>'''. | |||
You will get "'''200 OK'''" | |||
=== SRC-IP block === | === SRC-IP block === | ||
| Строка 343: | Строка 363: | ||
<code>nano /usr/local/nginx/conf/modsec-rules/custom01.conf</code> | <code>nano /usr/local/nginx/conf/modsec-rules/custom01.conf</code> | ||
SecRule REMOTE_ADDR "@ipMatchFromFile /usr/local/nginx/conf/blacklist.txt" "id:1,phase:1,deny,status:403,msg:\'blacklist\'" | SecRule REMOTE_ADDR "@ipMatchFromFile '''''/usr/local/nginx/conf/blacklist.txt'''''" "id:1,phase:1,deny,status:403,msg:\'blacklist\'" | ||
<code>nano /usr/local/nginx/conf/modsecurity.conf</code> | <code>nano /usr/local/nginx/conf/modsecurity.conf</code> | ||
... | ... | ||
Текущая версия на 13:30, 16 июля 2023
Description
ModSecurity, sometimes called Modsec, is an open-source web application firewall (WAF) to provide protections against generic classes of vulnerabilities using the OWASP ModSecurity Core Rule Set (CRS)
Links
https://aventistech.com/kb/modsecurity-with-nginx-on-centos-8/
Common Installation
Perform System Update
dnf check-update
dnf update
Free up disk space by deleting all downloaded software package and all cached repository
dnf clean all
Install required build tools and dependencies
dnf install -y gcc-c++ flex bison yajl curl-devel curl zlib-devel pcre-devel autoconf automake git curl make libxml2-devel pkgconfig libtool httpd-devel redhat-rpm-config git wget openssl openssl-devel vim nano
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
dnf install -y https://rpms.remirepo.net/enterprise/remi-release-8.rpm
dnf --enablerepo=powertools install -y doxygen yajl-devel
dnf --enablerepo=remi install -y GeoIP-devel
ModSecurity Compile
Clone the latest LibModsecurity GitHub repository to /opt/modsec
mkdir /opt/modsec
cd /opt/modsec
git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity
Compile and install ModSecurity
cd ModSecurity
git submodule init
git submodule update
./build.sh
./configure
make
make install
Nginx Compile to support ModSecurity
Download the ModSecurity-nginx connector which provides a communication channel between Nginx and LibModsecurity
cd /opt/modsec
git clone https://github.com/SpiderLabs/ModSecurity-nginx.git
Create a non-privileged system user and group for Nginx
useradd -r -M -s /sbin/nologin -d /usr/local/nginx nginx
Download Nginx and extract it to /opt/nginx
cd /opt
wget http://nginx.org/download/nginx-1.17.6.tar.gz
tar xzf nginx-1.17.6.tar.gz
Compile Nginx from source code
cd nginx-1.17.6
./configure --user=nginx --group=nginx --with-pcre-jit --with-debug --with-http_ssl_module --with-http_v2_module --with-http_realip_module --add-module=/opt/modsec/ModSecurity-nginx
make
make install
Create a systemd service for Nginx
nano /etc/systemd/system/nginx.service
[Unit] Description=The nginx HTTP and reverse proxy server After=network.target remote-fs.target nss-lookup.target [Service] Type=forking PIDFile=/run/nginx.pid ExecStartPre=/usr/bin/rm -f /run/nginx.pid ExecStartPre=/usr/sbin/nginx -t ExecStart=/usr/sbin/nginx ExecReload=/bin/kill -s HUP $MAINPID KillSignal=SIGQUIT TimeoutStopSec=5 KillMode=mixed PrivateTmp=true [Install] WantedBy=multi-user.target
Create a symbolic link of Nginx binary to /usr/sbin/ path.
ln -s /usr/local/nginx/sbin/nginx /usr/sbin/
Change the location of pid to /run/nginx.pid in Nginx config file
nano /usr/local/nginx/conf/nginx.conf
... pid /run/nginx.pid; ...
Enable and start Nginx service
systemctl enable --now nginx
Allow Firewalld for HTTP & HTTPS
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
systemctl restart firewalld.service
Verify HTTP & HTTPS is allowed
firewall-cmd --list-all
You should be able to access to Nginx Web Server via http://IP-ADDRESS now
Let’s Encrypt Wildcard SSL Certificate
<ADD LINK TO LETSENCRYPT MANUAL>
Let’s Encrypt wildcard SSL Certificate is stored in /etc/letsencrypt/live/cless.pro
ls /etc/letsencrypt/live/cless.pro
... cert.pem chain.pem fullchain.pem privkey.pem README ...
Enable SSL & HTTP/2 Support
Copy the cert.pem & privkey.pem to /usr/local/nginx/ssl/
mkdir /usr/local/nginx/ssl
cp /etc/letsencrypt/live/cless.pro/cert.pem /usr/local/nginx/ssl/
cp /etc/letsencrypt/live/cless.pro/privkey.pem /usr/local/nginx/ssl/
Add HTTPS config into Nginx configuration
nano /usr/local/nginx/conf/nginx.conf
...
server {
# Enable SSL
listen 443 ssl http2;
server_name localhost uat.aventis.dev;
# Letsencrypt enable
ssl_certificate /usr/local/nginx/ssl/cert.pem;
ssl_certificate_key /usr/local/nginx/ssl/privkey.pem;
}
...
Verify the configuration file of Nginx and restart the service
nginx -t
systemctl restart nginx
Go to https://cless.pro and verify that HTTP/2 is enabled
PHP-FPM with NGINX
dnf module list php
Install the latest PHP 7.4 Module
dnf module reset php
dnf module enable -y php:remi-7.4
dnf install -y php php-opcache php-gd php-curl php-mysqlnd
php -v
Change the PHP-FPM to use nginx instead of Apache user in
nano /etc/php-fpm.d/www.conf
... user = nginx group = nginx ...
Enable and start PHP-FPM
systemctl enable php-fpm
systemctl start php-fpm
Configure PHP-FPM with Nginx by modifying /usr/local/nginx/conf/nginx.conf
!!! ADD FOLLOWING INTO HTTPS SECTION: server { listen 443 ssl http2; <...> }
nano /usr/local/nginx/conf/nginx.conf
http {
server {
listen 443 ssl http2;
...
location ~ \.php$ {
root html;
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
...
}
}
...
Restart Nginx & PHP-FPM services
systemctl restart nginx
systemctl restart php-fpm
Create info.php in /usr/local/nginx/html (Default Root Directory for Nginx)
nano /usr/local/nginx/html/info.php
<?php phpinfo(); ?>
Go to https://cless.pro/info.php to verify PHP is installed successfully
Confgure Nginx with ModSecurity
Copy the Sample ModSecurity config file and unicode.mapping from ModSecurity source directory to Nginx configuration directory
cp /opt/modsec/ModSecurity/modsecurity.conf-recommended /usr/local/nginx/conf/modsecurity.conf
cp /opt/modsec/ModSecurity/unicode.mapping /usr/local/nginx/conf/
Create a backup for Nginx config file
cp /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.bak
Create /var/log/nginx to keep all the access & error log
mkdir /var/log/nginx
Add the following to the nginx.conf file
nano /usr/local/nginx/conf/nginx.conf
...
user nginx;
...
# !!! ADD FOLLOWING INTO HTTPS SECTION: server { listen 443 ssl http2; <...> }
...
http {
server {
listen 443 ssl http2;
...
modsecurity on;
modsecurity_rules_file /usr/local/nginx/conf/modsecurity.conf;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
...
}
}
...
Restart Nginx service
systemctl restart nginx
Turn On ModSecurity Rule Engine and change the default log directory for ModSecurity to /var/log/nginx/modsec_audit.log
nano /usr/local/nginx/conf/modsecurity.conf
... # Enable ModSecurity, attaching it to every transaction. Use detection # only to start with, because that minimises the chances of post-installation # disruption. # # By default, ModSecurity is set on detection only mode where it only logs the requests based on the triggered rules without blocking anything # DEFAULT - ONLY DETECTION # TURN IT ON IF YOU WANT TO BLOCK REQUESTS #SecRuleEngine DetectionOnly SecRuleEngine On # Use a single file for logging. This is much easier to look at, but # assumes that you will use the audit log only ocassionally. SecAuditLogType Serial SecAuditLog /var/log/nginx/modsec_audit.log ...
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
git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git /usr/local/nginx/conf/owasp-crs
Rename the crs-setup.conf.example to crs-setup.conf
cp /usr/local/nginx/conf/owasp-crs/crs-setup.conf.example /usr/local/nginx/conf/owasp-crs/crs-setup.conf
Include the OWASP rule to /usr/local/nginx/conf/modsecurity.conf
nano /usr/local/nginx/conf/modsecurity.conf
... Include owasp-crs/crs-setup.conf Include owasp-crs/rules/*.conf
Verify Nginx configuration file and restart Nginx service
nginx -t
systemctl restart nginx
Test
On arbitrary client in CLI or in GUI Browser
curl -k https://cless.pro/index.html?exec=/bin/bash
... <html> <head><title>403 Forbidden</title></head> <body> <center><h1>403 Forbidden</h1></center> <hr><center>nginx/1.17.6</center> </body> </html> ...
On Nginx server
tail /var/log/nginx/modsec_audit.log
... ModSecurity: Warning. Matched "Operator `PmFromFile' with parameter `unix-shell.data' against variable `ARGS:exec' (Value: `/bin/bash' ) [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/bash found within ARGS:exec: /bin/bash"] [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 "192.168.199.187"] [uri "/index.html"] [unique_id "168927378047.184148"] [ref "o1,8v21,9t:urlDecodeUni,t:cmdLine,t:normalizePath,t:lowercase"] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `5' ) [file "/usr/local/nginx/conf/owasp-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "80"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "2"] [ver "OWASP_CRS/3.2.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [hostname "192.168.199.187"] [uri "/index.html"] [unique_id "168927339520.223489"] [ref ""] ...
Custom rules
Block request by special parameter in a Query string
mkdir /usr/local/nginx/conf/modsec-rules
nano /usr/local/nginx/conf/modsec-rules/custom01.conf
SecRule ARGS:testparam "@contains test123" "id:1234,deny,log,status:403"
nano /usr/local/nginx/conf/modsecurity.conf
... Include modsec-rules/*.conf
nginx -t
systemctl restart nginx
Try to connect via browser to https://cless.pro/index.html?testparam=test123 with testparam=test123.
You will get "403 Forbidden"
BUT try to connect via browser to https://cless.pro/index.html?testparam=test.
You will get "200 OK"
SRC-IP block
nano /usr/local/nginx/conf/blacklist.txt
1.2.3.4 5.6.7.8
mkdir /usr/local/nginx/conf/modsec-rules
nano /usr/local/nginx/conf/modsec-rules/custom01.conf
SecRule REMOTE_ADDR "@ipMatchFromFile /usr/local/nginx/conf/blacklist.txt" "id:1,phase:1,deny,status:403,msg:\'blacklist\'"
nano /usr/local/nginx/conf/modsecurity.conf
... Include modsec-rules/*.conf
nginx -t
systemctl restart nginx
Try to connect via browser to https://cless.pro/index.html via SRC-IP from blacklist.txt.
You will get "403 Forbidden"