Skip to content

susuomlu/modsecurity-nginx-docker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

44 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Containerized WAF with ModSecurity + NGINX

A production-ready Web Application Firewall (WAF) implementation using ModSecurity 3.x with NGINX, containerized with Docker for easy deployment and management.

πŸš€ Features

  • ModSecurity 3.x with OWASP Core Rule Set (CRS)
  • NGINX as reverse proxy with security hardening
  • TLS/SSL encryption with auto-generated certificates
  • Custom rule support with hot-reload capability
  • Rate limiting and DDoS protection
  • Security headers automatically configured
  • Comprehensive logging (access, error, and audit logs)
  • Custom error pages with modern UI
  • Docker containerization for portability

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Client    │────────▢│  NGINX WAF   │────────▢│  Backend    β”‚
β”‚             β”‚  HTTPS  β”‚ + ModSecurityβ”‚  HTTP   β”‚  Applicationβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
                              β–Ό
                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                        β”‚   Logs   β”‚
                        β”‚  & Audit β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“ Directory Structure

modsecurity-nginx-docker/
β”œβ”€β”€ cert-gen.sh                    # SSL certificate generation script
β”œβ”€β”€ docker-compose.yml             # Docker orchestration file
β”œβ”€β”€ Dockerfile                     # NGINX + ModSecurity container
β”œβ”€β”€ watcher.sh                     # Auto-reload script for rule changes
β”œβ”€β”€ update-crs.sh                  # OWASP CRS update utility
β”œβ”€β”€ README.md                      # This file
β”‚
β”œβ”€β”€ modsec-data/                   # ModSecurity configuration directory
β”‚   β”œβ”€β”€ nginx.conf                 # Main NGINX configuration
β”‚   β”œβ”€β”€ modsecurity.conf           # ModSecurity core configuration
β”‚   β”œβ”€β”€ custom-rules.conf          # Your custom ModSecurity rules
β”‚   β”‚
β”‚   β”œβ”€β”€ conf.d/                    # NGINX server blocks
β”‚   β”‚   └── node.conf              # Backend proxy configuration
β”‚   β”‚
β”‚   β”œβ”€β”€ crs/                       # OWASP Core Rule Set
β”‚   β”‚   β”œβ”€β”€ crs-setup.conf         # CRS configuration
β”‚   β”‚   └── rules/                 # CRS rule files
β”‚   β”‚       β”œβ”€β”€ REQUEST-901-*.conf # Initialization rules
β”‚   β”‚       β”œβ”€β”€ REQUEST-9XX-*.conf # Attack detection rules
β”‚   β”‚       β”œβ”€β”€ RESPONSE-9XX-*.conf# Response inspection rules
β”‚   β”‚       └── *.data             # Supporting data files
β”‚   β”‚
β”‚   β”œβ”€β”€ html/                      # Custom error pages
β”‚   β”‚   β”œβ”€β”€ custom_403.html        # Blocked request page
β”‚   β”‚   └── tailwind.css           # Styling
β”‚   β”‚
β”‚   β”œβ”€β”€ logs/                      # Log files (generated at runtime)
β”‚   β”‚   β”œβ”€β”€ access.log             # HTTP access logs
β”‚   β”‚   β”œβ”€β”€ error.log              # NGINX error logs
β”‚   β”‚   └── audit.log              # ModSecurity audit logs
β”‚   β”‚
β”‚   └── ssl/                       # TLS certificates
β”‚       β”œβ”€β”€ cert.pem               # Certificate
β”‚       └── privkey.pem            # Private key
β”‚
└── nodeapp/                       # Example backend application
    β”œβ”€β”€ Dockerfile
    └── app.js

🚦 Quick Start

1. Clone and Navigate

git clone https://github.com/susuomlu/modsecurity-nginx-docker.git
cd modsecurity-nginx-docker/

2. Generate SSL Certificates (Optional)

chmod +x cert-gen.sh
./cert-gen.sh

3. Build the Container

docker compose -f docker-compose.yml build --no-cache

4. Start the Services

docker compose -f docker-compose.yml up -d

5. Verify Deployment

# Check container status
docker ps -a

# View logs
docker compose logs -f

# Test HTTPS access
curl -k https://localhost:8443

πŸ”§ Configuration

ModSecurity Settings

Edit modsec-data/modsecurity.conf:

# Enable ModSecurity
SecRuleEngine On

# Set paranoia level (1-4, higher = more strict)
SecAction "id:900000,phase:1,nolog,pass,t:none,setvar:tx.paranoia_level=2"

# Logging
SecAuditEngine RelevantOnly
SecAuditLog /var/log/modsec/audit.log

NGINX Configuration

Edit modsec-data/nginx.conf for global settings:

# Worker processes
worker_processes auto;

# Rate limiting zone
limit_req_zone $binary_remote_addr zone=waf_limit:10m rate=10r/s;

Edit modsec-data/conf.d/node.conf for backend configuration:

server {
    listen 8443 ssl http2;
    server_name _;
    
    # Backend proxy
    location / {
        proxy_pass http://nodeapp:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Custom Rules

Add custom ModSecurity rules in modsec-data/custom-rules.conf:

# Block specific parameter
SecRule ARGS:testparam "@streq test" \
    "id:10001,phase:2,deny,log,status:403,msg:'Test parameter blocked'"

# Block curl User-Agent
SecRule REQUEST_HEADERS:User-Agent "@contains curl" \
    "id:10002,phase:1,deny,log,status:403,msg:'Curl blocked'"

# Block SQL injection patterns
SecRule ARGS "@rx (?i)(union(.*?)select|select.+from)" \
    "id:10003,phase:2,deny,log,status:403,msg:'SQLi attempt blocked'"

# Block XSS attempts
SecRule ARGS "@rx (?i)(<script|javascript:|onerror=)" \
    "id:10004,phase:2,deny,log,status:403,msg:'XSS attempt blocked'"

# Block path traversal
SecRule REQUEST_URI "@rx (\.\./|\.\.\\)" \
    "id:10005,phase:1,deny,log,status:403,msg:'Path traversal blocked'"

Hot-Reload Rules

Enable automatic rule reloading:

docker exec -it modsec /usr/local/bin/watcher.sh

Or manually reload:

docker compose restart

πŸ›‘οΈ Security Features

1. OWASP Core Rule Set Protection

  • SQL Injection (SQLi)
  • Cross-Site Scripting (XSS)
  • Remote File Inclusion (RFI)
  • Local File Inclusion (LFI)
  • Remote Code Execution (RCE)
  • Session Fixation
  • Scanner Detection
  • Protocol Violations
  • Data Leakage Prevention

2. Security Headers

Automatically configured:

X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=()

3. Rate Limiting

  • Default: 10 requests/second per IP
  • Burst allowance: 20 requests
  • Configurable per location

4. TLS/SSL

  • TLS 1.2 and 1.3 only
  • Strong cipher suites
  • HTTP to HTTPS redirect
  • HSTS enabled

πŸ“Š Monitoring & Logging

View Live Logs

# All logs
docker compose logs -f

# Access logs only
docker exec modsec tail -f /var/log/nginx/access.log

# ModSecurity audit logs
docker exec modsec tail -f /var/log/modsec/audit.log

# Error logs
docker exec modsec tail -f /var/log/nginx/error.log

Log Locations

Inside container:

  • Access: /var/log/nginx/access.log
  • Error: /var/log/nginx/error.log
  • Audit: /var/log/modsec/audit.log

On host (mounted):

  • modsec-data/logs/access.log
  • modsec-data/logs/error.log
  • modsec-data/logs/audit.log

πŸ§ͺ Testing

Test Basic Access

curl -k https://localhost:8443

Test SQL Injection Block

curl -k "https://localhost:8443/?id=1' OR '1'='1"
# Expected: 403 Forbidden

Test XSS Block

curl -k "https://localhost:8443/?name=<script>alert('xss')</script>"
# Expected: 403 Forbidden

Test Custom Rule

curl -k "https://localhost:8443/?testparam=test"
# Expected: 403 Forbidden

Test User-Agent Block

curl -k https://localhost:8443
# Expected: 403 Forbidden (curl is blocked by custom rule)

πŸ”„ Management Commands

Start Services

docker compose up -d

Stop Services

docker compose down

Restart Services

docker compose restart

Rebuild After Changes

docker compose down
docker compose build --no-cache
docker compose up -d

Update OWASP CRS

chmod +x update-crs.sh
./update-crs.sh
docker compose restart

Access Container Shell

docker exec -it modsec /bin/sh

🎯 Tuning & Optimization

Adjust Paranoia Level

Higher paranoia = more false positives but better security:

# In modsec-data/crs/crs-setup.conf
SecAction "id:900000,phase:1,nolog,pass,t:none,setvar:tx.paranoia_level=2"

Levels:

  • 1: Basic security (recommended for start)
  • 2: Elevated security
  • 3: High security (more false positives)
  • 4: Maximum security (many false positives)

Whitelist Specific IPs

# In nginx.conf or server block
geo $whitelist {
    default 0;
    10.0.0.0/8 1;
    192.168.1.100 1;
}

# In custom-rules.conf
SecRule REMOTE_ADDR "@ipMatch 192.168.1.100" \
    "id:10100,phase:1,pass,nolog,ctl:ruleEngine=Off"

Disable Specific Rules

# In custom-rules.conf
SecRuleRemoveById 942100
SecRuleRemoveByMsg "SQL Injection Attack"

πŸ› Troubleshooting

Port Already in Use

# Check what's using the port
sudo lsof -i :8443

# Change ports in docker-compose.yml
ports:
  - "9443:8443"  # For example, use 9443 instead

Permission Denied on Logs

# Fix log directory permissions
chmod -R 755 modsec-data/logs/

Too Many False Positives

  1. Review audit logs to identify problematic rules
  2. Temporarily disable the rule
  3. Whitelist legitimate patterns
  4. Lower paranoia level

πŸ” Production Recommendations

  1. Use Valid SSL Certificates: Replace self-signed certs with Let's Encrypt or commercial certificates
  2. Configure Monitoring: Integrate with ELK, Splunk, or similar
  3. Regular Updates: Keep CRS and ModSecurity updated
  4. Tune Rules: Start with paranoia level 1, gradually increase
  5. Backup Configuration: Version control your custom rules
  6. Resource Limits: Set appropriate Docker resource constraints
  7. Network Segmentation: Place WAF in DMZ
  8. Regular Audits: Review logs and rules monthly

πŸ“š Additional Resources

πŸ“ License

This project configuration is provided as-is for educational and production use.

🀝 Contributing

Feel free to submit issues, fork the repository, and create pull requests for any improvements.


Note: Always test thoroughly in a staging environment before deploying to production.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors