ModSecurity and CRS
- 🐧 Linux Command Line
Ansible Playbook
Core
Install ModSecurity
https://github.com/owasp-modsecurity/ModSecurity/wiki/Compilation-recipes-for-v3.x
Install dependencies
dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm
dnf install -y git gcc-c++ automake flex bison yajl yajl-devel curl curl-devel GeoIP GeoIP-devel zlib-devel pcre-devel ssdeep ssdeep-devel autoconf automake libtool
Clone and install ModSecurity
cd /usr/local/
git clone https://github.com/SpiderLabs/ModSecurity
cd ModSecurity
./build.sh
git submodule init
git submodule update
./configure
make && make install
Install ModSecurity-nginx
cd /usr/local/
git clone https://github.com/owasp-modsecurity/ModSecurity-nginx
Install OWASP Core Rule Set (CRS)
https://coreruleset.org/docs/deployment/extended_install/#downloading-the-owasp-core-rule-set
git clone https://github.com/coreruleset/coreruleset /usr/local/modsecurity-crs
cd /usr/local/modsecurity-crs
mv crs-setup.conf.example crs-setup.conf
mv rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
mv rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
Create ModSecurity configuration file
mkdir -p /etc/nginx/modsec
cp /usr/local/ModSecurity/unicode.mapping /etc/nginx/modsec
cp /usr/local/ModSecurity/modsecurity.conf-recommended /etc/nginx/modsec/modsecurity.conf
Enable CRS rules
/etc/nginx/modsec/modsecurity.conf
- SecRuleEngine DetectionOnly
+ SecRuleEngine On
Create a ModSecurity configuration for use in Nginx
/etc/nginx/modsec/main.conf
Include /etc/nginx/modsec/modsecurity.conf
Include /usr/local/modsecurity-crs/crs-setup.conf
Include /usr/local/modsecurity-crs/rules/*.conf
Manage ModSecurity
View audit logs
tail -f /var/log/modsec_audit.log
Update CRS rules
cd /usr/local/modsecurity-crs
git pull
Optional
Install CRS Plugins
https://coreruleset.org/docs/4-about-plugins/4-1-plugins/
mkdir /usr/local/modsecurity-crs/rules/plugins
/etc/nginx/modsec/main.conf
Include /etc/nginx/modsec/modsecurity.conf
Include /usr/local/modsecurity-crs/crs-setup.conf
+ Include /usr/local/modsecurity-crs/plugins/*-config.conf
+ Include /usr/local/modsecurity-crs/plugins/*-before.conf
Include /usr/local/modsecurity-crs/rules/*.conf
+ Include /usr/local/modsecurity-crs/plugins/*-after.conf
https://github.com/coreruleset/plugin-registry
cd /usr/local/modsecurity-crs/plugins
wget https://raw.githubusercontent.com/coreruleset/wordpress-rule-exclusions-plugin/refs/heads/master/plugins/wordpress-rule-exclusions-config.conf
wget https://raw.githubusercontent.com/coreruleset/wordpress-rule-exclusions-plugin/refs/heads/master/plugins/wordpress-rule-exclusions-before.conf
wget https://raw.githubusercontent.com/coreruleset/phpmyadmin-rule-exclusions-plugin/refs/heads/master/plugins/phpmyadmin-rule-exclusions-config.conf
wget https://raw.githubusercontent.com/coreruleset/phpmyadmin-rule-exclusions-plugin/refs/heads/master/plugins/phpmyadmin-rule-exclusions-before.conf
wget https://raw.githubusercontent.com/coreruleset/phpmyadmin-rule-exclusions-plugin/refs/heads/master/plugins/phpmyadmin-rule-exclusions-after.conf
Custom CRS rules
5 phases for the request cycle
Request headers → REQUEST_HEADERS
Request body → REQUEST_BODY
Response headers → RESPONSE_HEADERS
Response body → RESPONSE_BODY
Logging → LOGGING
Example:
SecRule REQUEST_URI "@beginsWith /sync/hostKey" \
"id:1000,\
phase:1,\
pass,\
nolog,\
ctl:ruleEngine=Off"
SecRule REQUEST_URI "@beginsWith /sync/hostKey" \
"id:1001,\
phase:1,\
pass,\
nolog,\
ctl:ruleRemoveById=920420"
SecRule REQUEST_URI "@beginsWith /sync/hostKey" \
"id:1002,\
phase:1,\
pass,\
nolog,\
setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| |text/xml| |application/xml| |application/soap+xml| |application/json| |application/cloudevents+json| |application/cloudevents-batch+json|application/octet-stream|'"
SecRule REQUEST_URI "@beginsWith /notifications/hub" \
"id:1001,\
phase:1,\
pass,\
nolog,\
ctl:ruleRemoveById=920100"
modsecurity-and-crs.yml
- name: Install ModSecurity and OWASP Core Rule Set
hosts: all
remote_user: root
tasks:
- name: Install Remi GPG key
rpm_key:
state: present
key: https://rpms.remirepo.net/RPM-GPG-KEY-remi
- name: Install Remi repository
dnf:
name: https://rpms.remirepo.net/enterprise/remi-release-9.rpm
state: present
disable_gpg_check: true
- name: Install required packages
dnf:
name:
- git
- gcc-c++
- automake
- flex
- bison
- yajl
- yajl-devel
- curl
- curl-devel
- GeoIP
- GeoIP-devel
- zlib-devel
- pcre-devel
- ssdeep
- ssdeep-devel
- autoconf
- automake
- libtool
state: present
- name: Clone ModSecurity repository
git:
repo: https://github.com/SpiderLabs/ModSecurity
dest: /usr/local/ModSecurity
version: v3/master
force: true
- name: Build ModSecurity (/tmp/modsecurity_build_output.log)
shell: |
set -o pipefail
cd /usr/local/ModSecurity
./build.sh
git submodule init
git submodule update
./configure
make | tee /tmp/modsecurity_build_output.log
make install
register: modsecurity_build
changed_when: modsecurity_build.rc != 0
- name: Clone ModSecurity-nginx repository
git:
repo: https://github.com/owasp-modsecurity/ModSecurity-nginx
dest: /usr/local/ModSecurity-nginx
version: master
force: true
- name: Clone OWASP ModSecurity Core Rule Set
git:
repo: https://github.com/coreruleset/coreruleset
dest: /usr/local/modsecurity-crs
version: main
force: true
- name: Move example CRS setup files
shell: |
mv /usr/local/modsecurity-crs/crs-setup.conf.example \
/usr/local/modsecurity-crs/crs-setup.conf && \
mv /usr/local/modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example \
/usr/local/modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf && \
mv /usr/local/modsecurity-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example \
/usr/local/modsecurity-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
register: move_crs_files
changed_when: move_crs_files.rc == 0
- name: Create ModSecurity configuration directory
file:
path: /etc/nginx/modsec
state: directory
mode: "0755"
- name: Copy ModSecurity configuration files
copy:
src: /usr/local/ModSecurity/unicode.mapping
dest: /etc/nginx/modsec/unicode.mapping
mode: "0644"
- name: Copy recommended ModSecurity configuration
copy:
src: /usr/local/ModSecurity/modsecurity.conf-recommended
dest: /etc/nginx/modsec/modsecurity.conf
mode: "0644"
- name: Configure ModSecurity engine
lineinfile:
path: /etc/nginx/modsec/modsecurity.conf
regexp: "^#?SecRuleEngine"
line: "SecRuleEngine On"
- name: Create main.conf for ModSecurity
copy:
dest: /etc/nginx/modsec/main.conf
mode: "0644"
content: |
Include /etc/nginx/modsec/modsecurity.conf
Include /usr/local/modsecurity-crs/crs-setup.conf
Include /usr/local/modsecurity-crs/rules/*.conf