Set up ModSecurity 3 with OWASP Core Rule Set 4.0 to protect web applications from SQL injection, XSS, and other attacks. Configure integration with Nginx and Apache, implement custom rules, and optimize performance for production environments.
Prerequisites
- Root or sudo access
- Web server (Nginx or Apache) installed
- Basic understanding of web server configuration
- At least 2GB RAM for compilation
What this solves
ModSecurity 3 is an open-source web application firewall (WAF) that protects your web applications from common attacks like SQL injection, cross-site scripting (XSS), and remote file inclusion. Combined with the OWASP Core Rule Set (CRS), it provides enterprise-grade threat detection and blocking capabilities. This tutorial shows you how to install ModSecurity 3, configure it with OWASP CRS 4.0, integrate it with popular web servers, and optimize performance for production use.
Step-by-step installation
Update system packages
Start by updating your package manager to ensure you get the latest security patches and dependencies.
sudo apt update && sudo apt upgrade -y
sudo dnf update -y
Install build dependencies
Install the required development tools and libraries needed to compile ModSecurity 3 from source.
sudo apt install -y build-essential git cmake libpcre2-dev libxml2-dev libcurl4-openssl-dev libyajl-dev libgeoip-dev liblua5.3-dev libfuzzy-dev libpcre3-dev zlib1g-dev
sudo dnf groupinstall -y "Development Tools"
sudo dnf install -y git cmake pcre2-devel libxml2-devel libcurl-devel yajl-devel GeoIP-devel lua-devel ssdeep-devel pcre-devel zlib-devel
Download and compile ModSecurity 3
Clone the ModSecurity repository and compile the library with optimizations enabled for production use.
cd /opt
sudo git clone --depth 1 -b v3.0.12 https://github.com/owasp-modsecurity/ModSecurity.git
cd ModSecurity
sudo git submodule init
sudo git submodule update
sudo ./build.sh
sudo ./configure --with-pcre2 --with-yajl --with-geoip --with-lua --enable-parser-generation
sudo make -j$(nproc)
sudo make install
Configure library path
Add ModSecurity libraries to the system library path so web servers can find them at runtime.
echo '/usr/local/modsecurity/lib' | sudo tee /etc/ld.so.conf.d/modsecurity.conf
sudo ldconfig
Download OWASP Core Rule Set
Download the latest OWASP CRS 4.0 which provides comprehensive protection rules against common web attacks.
cd /opt
sudo wget https://github.com/coreruleset/coreruleset/archive/v4.0.0.tar.gz
sudo tar -xzf v4.0.0.tar.gz
sudo mv coreruleset-4.0.0 /etc/modsecurity
sudo chown -R root:root /etc/modsecurity
sudo chmod -R 755 /etc/modsecurity
Create ModSecurity configuration
Set up the main ModSecurity configuration with logging, audit settings, and security policies.
# ModSecurity Configuration
SecRuleEngine On
SecRequestBodyAccess On
SecRule REQUEST_HEADERS:Content-Type "^(?:application(?:/soap\+|/)|text/)xml" "id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"
SecRule REQUEST_HEADERS:Content-Type "^application/json" "id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
SecRequestBodyInMemoryLimit 131072
SecRequestBodyLimitAction Reject
SecRule REQBODY_ERROR "!@eq 0" "id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'Error %{reqbody_error_msg}',severity:2"
SecRule MULTIPART_STRICT_ERROR "!@eq 0" "id:'200003',phase:2,t:none,log,deny,status:400, msg:'Multipart request body failed strict validation'"
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" "id:'200004',phase:2,t:none,log,deny,status:44"
SecRule TX:/^MSC_/ "!@streq 0" "id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"
SecResponseBodyAccess On
SecResponseBodyMimeType text/plain text/html text/xml
SecResponseBodyLimit 524288
SecResponseBodyLimitAction ProcessPartial
SecTmpDir /tmp/
SecDataDir /tmp/
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLogParts ABIJDEFHZ
SecAuditLogType Serial
SecAuditLog /var/log/modsecurity/audit.log
SecArgumentSeparator &
SecCookieFormat 0
SecUnicodeMapFile unicode.mapping 20127
SecStatusEngine On
Configure OWASP Core Rule Set
Create the CRS setup configuration with custom settings for your environment and security requirements.
# OWASP CRS 4.0 Setup Configuration
Include /etc/modsecurity/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example
SecDefaultAction "phase:1,log,auditlog,pass"
SecDefaultAction "phase:2,log,auditlog,pass"
SecAction "id:900000,phase:1,nolog,pass,t:none,setvar:tx.paranoia_level=1"
SecAction "id:900001,phase:1,nolog,pass,t:none,setvar:tx.executing_paranoia_level=1"
SecAction "id:900010,phase:1,nolog,pass,t:none,setvar:tx.inbound_anomaly_score_threshold=5"
SecAction "id:900011,phase:1,nolog,pass,t:none,setvar:tx.outbound_anomaly_score_threshold=4"
SecAction "id:900020,phase:1,nolog,pass,t:none,setvar:tx.allowed_methods=GET HEAD POST OPTIONS"
SecAction "id:900021,phase:1,nolog,pass,t:none,setvar:tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |text/xml| |application/xml| |application/soap+xml| |application/x-amf| |application/json| |application/octet-stream| |application/csp-report| |application/xss-auditor-report| |text/plain|"
SecAction "id:900022,phase:1,nolog,pass,t:none,setvar:tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0"
SecAction "id:900023,phase:1,nolog,pass,t:none,setvar:tx.restricted_extensions=.asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .resources/ .resx/ .sql/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/"
SecAction "id:900024,phase:1,nolog,pass,t:none,setvar:tx.restricted_headers=/proxy-connection/ /lock-token/ /content-range/ /translate/ /if/"
SecAction "id:900030,phase:1,nolog,pass,t:none,setvar:tx.crs_validate_utf8_encoding=1"
SecAction "id:900031,phase:1,nolog,pass,t:none,setvar:tx.arg_name_length=100"
SecAction "id:900032,phase:1,nolog,pass,t:none,setvar:tx.arg_length=400"
SecAction "id:900033,phase:1,nolog,pass,t:none,setvar:tx.total_arg_length=64000"
SecAction "id:900034,phase:1,nolog,pass,t:none,setvar:tx.max_num_args=255"
Create log directory
Set up the directory structure for ModSecurity logs with appropriate permissions for the web server.
sudo mkdir -p /var/log/modsecurity
sudo chown www-data:www-data /var/log/modsecurity
sudo chmod 755 /var/log/modsecurity
Nginx integration
Compile Nginx ModSecurity connector
Download and compile the Nginx connector module that enables ModSecurity integration with Nginx.
cd /opt
sudo git clone --depth 1 https://github.com/owasp-modsecurity/ModSecurity-nginx.git
Recompile Nginx with ModSecurity module
Get Nginx source and recompile it with the ModSecurity module enabled for dynamic loading.
sudo apt install -y nginx-dev
nginx_version=$(nginx -v 2>&1 | grep -o '[0-9.]\+')
cd /opt
sudo wget http://nginx.org/download/nginx-${nginx_version}.tar.gz
sudo tar -xzf nginx-${nginx_version}.tar.gz
cd nginx-${nginx_version}
sudo ./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
sudo make modules
sudo cp objs/ngx_http_modsecurity_module.so /usr/lib/nginx/modules/
sudo dnf install -y nginx-mod-devel
nginx_version=$(nginx -v 2>&1 | grep -o '[0-9.]\+')
cd /opt
sudo wget http://nginx.org/download/nginx-${nginx_version}.tar.gz
sudo tar -xzf nginx-${nginx_version}.tar.gz
cd nginx-${nginx_version}
sudo ./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
sudo make modules
sudo cp objs/ngx_http_modsecurity_module.so /usr/lib64/nginx/modules/
Configure Nginx with ModSecurity
Update the Nginx configuration to load the ModSecurity module and enable WAF protection on your sites. This configuration builds on standard Nginx reverse proxy setups with additional security layers.
load_module modules/ngx_http_modsecurity_module.so;
user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# ModSecurity
modsecurity on;
modsecurity_rules_file /etc/nginx/modsecurity.conf;
# Logging
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# Basic settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Create Nginx ModSecurity rules file
Create the main rules file that Nginx will use to load ModSecurity configuration and OWASP CRS rules.
# Include ModSecurity configuration
Include /etc/modsecurity/modsecurity.conf
# Include OWASP CRS setup
Include /etc/modsecurity/crs-setup.conf
# Include OWASP CRS rules
Include /etc/modsecurity/rules/*.conf
Create symbolic links for CRS rules
Set up the rules directory structure and link the OWASP CRS rule files for easy management.
sudo mkdir -p /etc/modsecurity/rules
sudo ln -sf /etc/modsecurity/rules/*.conf /etc/modsecurity/rules/
for rule in /etc/modsecurity/rules/REQUEST-9*.conf; do
sudo ln -sf "$rule" /etc/modsecurity/rules/
done
for rule in /etc/modsecurity/rules/RESPONSE-9*.conf; do
sudo ln -sf "$rule" /etc/modsecurity/rules/
done
Apache integration
Install Apache ModSecurity module
For Apache integration, compile the mod_security2 module from source for optimal compatibility with ModSecurity 3.
sudo apt install -y apache2-dev
cd /opt
sudo git clone --depth 1 https://github.com/owasp-modsecurity/ModSecurity-apache.git
cd ModSecurity-apache
sudo ./autogen.sh
sudo ./configure --with-libmodsecurity=/usr/local/modsecurity/
sudo make
sudo make install
sudo dnf install -y httpd-devel
cd /opt
sudo git clone --depth 1 https://github.com/owasp-modsecurity/ModSecurity-apache.git
cd ModSecurity-apache
sudo ./autogen.sh
sudo ./configure --with-libmodsecurity=/usr/local/modsecurity/
sudo make
sudo make install
Enable ModSecurity in Apache
Create Apache configuration to load and enable ModSecurity with OWASP CRS rules. This works alongside existing Apache virtual host configurations.
LoadModule security3_module /usr/lib/apache2/modules/mod_security3.so
Create Apache rules configuration
Set up the Apache-specific rules file that includes all ModSecurity and OWASP CRS configurations.
# Include ModSecurity configuration
Include /etc/modsecurity/modsecurity.conf
# Include OWASP CRS setup
Include /etc/modsecurity/crs-setup.conf
# Include OWASP CRS rules
Include /etc/modsecurity/rules/REQUEST-901-INITIALIZATION.conf
Include /etc/modsecurity/rules/REQUEST-903-IP-REPUTATION.conf
Include /etc/modsecurity/rules/REQUEST-905-COMMON-EXCEPTIONS.conf
Include /etc/modsecurity/rules/REQUEST-910-IP-REPUTATION.conf
Include /etc/modsecurity/rules/REQUEST-911-METHOD-ENFORCEMENT.conf
Include /etc/modsecurity/rules/REQUEST-912-DOS-PROTECTION.conf
Include /etc/modsecurity/rules/REQUEST-913-SCANNER-DETECTION.conf
Include /etc/modsecurity/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf
Include /etc/modsecurity/rules/REQUEST-921-PROTOCOL-ATTACK.conf
Include /etc/modsecurity/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf
Include /etc/modsecurity/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf
Include /etc/modsecurity/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf
Include /etc/modsecurity/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf
Include /etc/modsecurity/rules/REQUEST-934-APPLICATION-ATTACK-NODEJS.conf
Include /etc/modsecurity/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf
Include /etc/modsecurity/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf
Include /etc/modsecurity/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf
Include /etc/modsecurity/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf
Include /etc/modsecurity/rules/REQUEST-949-BLOCKING-EVALUATION.conf
Include /etc/modsecurity/rules/RESPONSE-950-DATA-LEAKAGES.conf
Include /etc/modsecurity/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf
Include /etc/modsecurity/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf
Include /etc/modsecurity/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf
Include /etc/modsecurity/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf
Include /etc/modsecurity/rules/RESPONSE-959-BLOCKING-EVALUATION.conf
Include /etc/modsecurity/rules/RESPONSE-980-CORRELATION.conf
Enable the module
Activate ModSecurity in Apache and restart the web server to apply the configuration.
sudo a2enmod modsecurity
sudo systemctl restart apache2
sudo systemctl status apache2
sudo systemctl restart httpd
sudo systemctl status httpd
Custom rules and whitelisting
Create custom rules file
Set up a custom rules file for application-specific security rules and exceptions that don't fit the standard OWASP CRS.
# Custom ModSecurity Rules
# Block common attack patterns
SecRule REQUEST_URI "@detectSQLi" \
"id:1001,\
phase:2,\
block,\
msg:'SQL Injection Attack Detected',\
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
tag:'attack-sqli',\
severity:2"
# Block XSS attempts
SecRule ARGS "@detectXSS" \
"id:1002,\
phase:2,\
block,\
msg:'XSS Attack Detected',\
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
tag:'attack-xss',\
severity:2"
# Rate limiting per IP
SecRule IP:RATE_LIMITED "@eq 1" \
"id:1003,\
phase:1,\
deny,\
status:429,\
msg:'Rate limit exceeded',\
expirevar:ip.rate_limited=60"
SecRule REQUEST_HEADERS:User-Agent "@streq \"\"" \
"id:1004,\
phase:1,\
deny,\
msg:'Empty User-Agent blocked'"
# Geographic IP blocking (example)
SecGeoLookupDB /etc/modsecurity/GeoLite2-Country.mmdb
SecRule GEO:COUNTRY_CODE "@streq CN" \
"id:1005,\
phase:1,\
deny,\
msg:'Access denied from country'"
Create whitelist exceptions
Configure rule exceptions for legitimate application functionality that might trigger false positives.
# ModSecurity Whitelist Rules - Application Exceptions
# Allow legitimate admin panel access
SecRule REQUEST_URI "@beginsWith /admin" \
"id:2001,\
phase:1,\
pass,\
ctl:ruleRemoveTargetById=942100;ARGS:query,\
ctl:ruleRemoveTargetById=941160;ARGS:content"
# API endpoint exceptions
SecRule REQUEST_URI "@beginsWith /api/v1" \
"id:2002,\
phase:1,\
pass,\
ctl:ruleRemoveById=920230,\
msg:'API endpoint - relax protocol enforcement'"
# Upload functionality exceptions
SecRule REQUEST_URI "@beginsWith /upload" \
"id:2003,\
phase:1,\
pass,\
ctl:ruleRemoveTargetById=200003;FILES,\
msg:'File upload - allow multipart'"
# CMS-specific exceptions (WordPress example)
SecRule REQUEST_URI "@beginsWith /wp-admin" \
"id:2004,\
phase:1,\
pass,\
ctl:ruleRemoveTargetById=931130;ARGS:action,\
ctl:ruleRemoveTargetById=942100;ARGS:post_content"
# Search functionality exceptions
SecRule ARGS:search "@unconditionalMatch" \
"id:2005,\
phase:1,\
pass,\
ctl:ruleRemoveTargetById=942100;ARGS:search,\
msg:'Search query - allow SQL-likAutomated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Configuration
MODSEC_VERSION="v3.0.12"
CRS_VERSION="v4.0.0"
INSTALL_DIR="/opt"
CONFIG_DIR="/etc/modsecurity"
LOG_DIR="/var/log/modsecurity"
usage() {
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " -w, --webserver WEBSERVER Web server to configure (nginx|apache2) [optional]"
echo " -h, --help Show this help message"
echo ""
echo "Example: $0 --webserver nginx"
}
cleanup() {
if [[ $? -ne 0 ]]; then
echo -e "${RED}[ERROR] Installation failed. Cleaning up...${NC}"
sudo rm -rf ${INSTALL_DIR}/ModSecurity 2>/dev/null || true
sudo rm -rf ${CONFIG_DIR} 2>/dev/null || true
sudo rm -f /etc/ld.so.conf.d/modsecurity.conf 2>/dev/null || true
sudo ldconfig 2>/dev/null || true
fi
}
trap cleanup ERR
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
check_prerequisites() {
if [[ $EUID -eq 0 ]]; then
log_error "This script should not be run as root. Use sudo when needed."
exit 1
fi
if ! command -v sudo >/dev/null 2>&1; then
log_error "sudo is required but not installed."
exit 1
fi
if ! sudo -n true 2>/dev/null; then
log_error "This script requires sudo privileges."
exit 1
fi
}
detect_distro() {
if [[ ! -f /etc/os-release ]]; then
log_error "Cannot detect distribution. /etc/os-release not found."
exit 1
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update && apt upgrade -y"
PKG_INSTALL="apt install -y"
BUILD_DEPS="build-essential git cmake libpcre2-dev libxml2-dev libcurl4-openssl-dev libyajl-dev libgeoip-dev liblua5.3-dev libfuzzy-dev libpcre3-dev zlib1g-dev"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf update -y"
PKG_INSTALL="dnf install -y"
BUILD_DEPS="git cmake pcre2-devel libxml2-devel libcurl-devel yajl-devel GeoIP-devel lua-devel ssdeep-devel pcre-devel zlib-devel"
DEVTOOLS="dnf groupinstall -y \"Development Tools\""
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum update -y"
PKG_INSTALL="yum install -y"
BUILD_DEPS="git cmake pcre2-devel libxml2-devel libcurl-devel yajl-devel GeoIP-devel lua-devel ssdeep-devel pcre-devel zlib-devel"
DEVTOOLS="yum groupinstall -y \"Development Tools\""
;;
*)
log_error "Unsupported distribution: $ID"
exit 1
;;
esac
log_info "Detected distribution: $PRETTY_NAME"
}
parse_args() {
WEBSERVER=""
while [[ $# -gt 0 ]]; do
case $1 in
-w|--webserver)
WEBSERVER="$2"
if [[ "$WEBSERVER" != "nginx" && "$WEBSERVER" != "apache2" ]]; then
log_error "Unsupported web server: $WEBSERVER"
usage
exit 1
fi
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
log_error "Unknown option: $1"
usage
exit 1
;;
esac
done
}
update_system() {
log_info "[1/8] Updating system packages..."
sudo bash -c "$PKG_UPDATE"
}
install_dependencies() {
log_info "[2/8] Installing build dependencies..."
if [[ -n "${DEVTOOLS:-}" ]]; then
sudo bash -c "$DEVTOOLS"
fi
sudo $PKG_INSTALL $BUILD_DEPS
}
compile_modsecurity() {
log_info "[3/8] Downloading and compiling ModSecurity 3..."
cd $INSTALL_DIR
sudo git clone --depth 1 -b $MODSEC_VERSION https://github.com/owasp-modsecurity/ModSecurity.git
cd ModSecurity
sudo git submodule init
sudo git submodule update
sudo ./build.sh
sudo ./configure --with-pcre2 --with-yajl --with-geoip --with-lua --enable-parser-generation
sudo make -j$(nproc)
sudo make install
}
configure_library_path() {
log_info "[4/8] Configuring library path..."
echo '/usr/local/modsecurity/lib' | sudo tee /etc/ld.so.conf.d/modsecurity.conf >/dev/null
sudo ldconfig
}
download_owasp_crs() {
log_info "[5/8] Downloading OWASP Core Rule Set..."
cd $INSTALL_DIR
sudo wget -O crs.tar.gz "https://github.com/coreruleset/coreruleset/archive/${CRS_VERSION}.tar.gz"
sudo tar -xzf crs.tar.gz
sudo rm -f crs.tar.gz
CRS_DIR=$(sudo find . -name "coreruleset-*" -type d | head -1)
sudo mkdir -p $CONFIG_DIR
sudo mv "$CRS_DIR"/* $CONFIG_DIR/
sudo rmdir "$CRS_DIR"
sudo chown -R root:root $CONFIG_DIR
sudo find $CONFIG_DIR -type d -exec chmod 755 {} \;
sudo find $CONFIG_DIR -type f -exec chmod 644 {} \;
}
create_modsecurity_config() {
log_info "[6/8] Creating ModSecurity configuration..."
sudo mkdir -p $LOG_DIR
sudo chmod 755 $LOG_DIR
sudo tee ${CONFIG_DIR}/modsecurity.conf >/dev/null <<'EOF'
SecRuleEngine On
SecRequestBodyAccess On
SecRule REQUEST_HEADERS:Content-Type "^(?:application(?:/soap\+|/)|text/)xml" "id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"
SecRule REQUEST_HEADERS:Content-Type "^application/json" "id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
SecRequestBodyInMemoryLimit 131072
SecRequestBodyLimitAction Reject
SecResponseBodyAccess On
SecResponseBodyMimeType text/plain text/html text/xml
SecResponseBodyLimit 524288
SecResponseBodyLimitAction ProcessPartial
SecTmpDir /tmp/
SecDataDir /tmp/
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLogParts ABIJDEFHZ
SecAuditLogType Serial
SecAuditLog /var/log/modsecurity/audit.log
SecArgumentSeparator &
SecCookieFormat 0
SecStatusEngine On
EOF
sudo chmod 644 ${CONFIG_DIR}/modsecurity.conf
}
configure_owasp_crs() {
log_info "[7/8] Configuring OWASP Core Rule Set..."
sudo cp ${CONFIG_DIR}/crs-setup.conf.example ${CONFIG_DIR}/crs-setup.conf
sudo tee ${CONFIG_DIR}/main.conf >/dev/null <<EOF
Include ${CONFIG_DIR}/modsecurity.conf
Include ${CONFIG_DIR}/crs-setup.conf
Include ${CONFIG_DIR}/rules/*.conf
EOF
sudo chmod 644 ${CONFIG_DIR}/crs-setup.conf ${CONFIG_DIR}/main.conf
}
verify_installation() {
log_info "[8/8] Verifying installation..."
# Check if ModSecurity library exists
if [[ ! -f /usr/local/modsecurity/lib/libmodsecurity.so ]]; then
log_error "ModSecurity library not found"
exit 1
fi
# Check if configuration files exist
if [[ ! -f ${CONFIG_DIR}/main.conf ]]; then
log_error "ModSecurity configuration not found"
exit 1
fi
# Check if CRS rules exist
if [[ ! -d ${CONFIG_DIR}/rules ]]; then
log_error "OWASP CRS rules not found"
exit 1
fi
# Check library path
if ! ldconfig -p | grep -q modsecurity; then
log_error "ModSecurity library not in system path"
exit 1
fi
log_info "ModSecurity 3 with OWASP CRS installation completed successfully!"
echo ""
echo -e "${GREEN}Next steps:${NC}"
echo "1. Configure your web server to use ModSecurity"
echo "2. Test the configuration with: nginx -t (for Nginx) or apache2ctl configtest (for Apache)"
echo "3. Monitor logs in: $LOG_DIR"
echo "4. Customize rules in: ${CONFIG_DIR}/crs-setup.conf"
if [[ -n "$WEBSERVER" ]]; then
log_warn "Web server integration for $WEBSERVER requires manual configuration"
log_warn "Please refer to the ModSecurity documentation for $WEBSERVER integration"
fi
}
main() {
echo -e "${GREEN}ModSecurity 3 with OWASP CRS Installation Script${NC}"
echo "================================================"
echo ""
check_prerequisites
detect_distro
parse_args "$@"
update_system
install_dependencies
compile_modsecurity
configure_library_path
download_owasp_crs
create_modsecurity_config
configure_owasp_crs
verify_installation
}
main "$@"
Review the script before running. Execute with: bash install.sh