ModSecurity WAF Remote Work Setup — ตั้งค่า Web
ModSecurity WAF Remote Work
ModSecurity WAF Remote Work VPN OWASP CRS SQL Injection XSS Brute Force Geo-blocking Rate Limiting Zero Trust Production
| Attack | OWASP CRS Rule | Remote Work Risk | Prevention |
|---|---|---|---|
| SQL Injection | 942xxx | สูง (Public-facing App) | CRS PL2 + Virtual Patch |
| XSS | 941xxx | สูง | CRS PL2 + CSP Header |
| Brute Force | Custom Rate Limit | สูงมาก (Login จากทุกที่) | Rate Limit + Account Lock |
| Path Traversal | 930xxx | ปานกลาง | CRS PL1 |
| Bot Attack | Custom UA Rule | สูง | Bot Detection + CAPTCHA |
| DDoS | Custom Rate Limit | สูง (No Office Firewall) | Cloudflare + Rate Limit |
Installation & Configuration
# === ModSecurity Setup for Nginx ===
# Install ModSecurity with Nginx
# apt-get install libmodsecurity3 libmodsecurity-dev
# or compile from source for latest version
# Nginx configuration (nginx.conf)
# load_module modules/ngx_http_modsecurity_module.so;
# http {
# modsecurity on;
# modsecurity_rules_file /etc/nginx/modsec/main.conf;
# }
# main.conf
# Include /etc/nginx/modsec/modsecurity.conf
# Include /etc/nginx/modsec/crs/crs-setup.conf
# Include /etc/nginx/modsec/crs/rules/*.conf
# modsecurity.conf key settings:
# SecRuleEngine On (DetectionOnly for testing)
# SecRequestBodyAccess On
# SecResponseBodyAccess Off (Performance)
# SecAuditEngine RelevantOnly
# SecAuditLog /var/log/modsec/audit.log
# SecAuditLogFormat JSON
from dataclasses import dataclass
@dataclass
class WAFRule:
rule_id: str
description: str
action: str
remote_work_reason: str
rules = [
WAFRule("Custom-001",
"Rate Limit Login: > 5 attempts/10min per IP",
"SecRule IP:bf_counter '@gt 5' 'id:100001, deny, status:429'",
"Remote workers login จากทุกที่ ต้องป้องกัน Brute Force"),
WAFRule("Custom-002",
"Geo-restrict: Allow only TH US SG",
"SecRule REMOTE_ADDR '!@geoLookup' ... OR GEO:COUNTRY_CODE '!@within TH, US, SG'",
"จำกัดประเทศที่พนักงาน Remote อยู่"),
WAFRule("Custom-003",
"Block Suspicious User-Agent",
"SecRule REQUEST_HEADERS:User-Agent '@rx (sqlmap|nikto|nmap)' 'deny'",
"Block Hacking Tool ที่สแกนจากภายนอก"),
WAFRule("Custom-004",
"Upload File Size Limit 10MB",
"SecRequestBodyLimit 10485760",
"จำกัด Upload ป้องกัน DoS ผ่าน Large File"),
WAFRule("Custom-005",
"API Rate Limit 100 req/min/IP",
"SecRule IP:api_counter '@gt 100' 'id:100005, deny, status:429'",
"ป้องกัน API Abuse จาก Remote Network"),
]
print("=== Custom WAF Rules ===")
for r in rules:
print(f" [{r.rule_id}] {r.description}")
print(f" Rule: {r.action}")
print(f" Why: {r.remote_work_reason}")
VPN + WAF Architecture
# === Zero Trust Architecture ===
@dataclass
class SecurityLayer:
layer: str
tool: str
protection: str
config: str
layers = [
SecurityLayer("Layer 1: Edge/CDN",
"Cloudflare (Free/Pro)",
"DDoS Protection SSL/TLS Bot Management",
"เปิด Under Attack Mode เมื่อถูกโจมตี"),
SecurityLayer("Layer 2: WAF",
"ModSecurity + OWASP CRS",
"SQL Injection XSS CSRF Brute Force",
"PL2 + Custom Rules + Virtual Patching"),
SecurityLayer("Layer 3: VPN/ZTNA",
"WireGuard / Tailscale / Cloudflare Access",
"Network Encryption Identity Verification",
"MFA Required Device Check Geo-restrict"),
SecurityLayer("Layer 4: Application",
"Application Code + Framework",
"Input Validation Auth Session CSRF Token",
"Secure Coding OWASP Best Practices"),
SecurityLayer("Layer 5: Database",
"PostgreSQL / MySQL",
"Encryption at Rest Access Control Audit",
"Least Privilege Encrypted Connection Backup"),
]
print("=== Security Layers ===")
for l in layers:
print(f" [{l.layer}] Tool: {l.tool}")
print(f" Protect: {l.protection}")
print(f" Config: {l.config}")
Monitoring & Alerting
# === WAF Monitoring ===
# ELK Stack for ModSecurity
# Filebeat → Elasticsearch → Kibana
# filebeat.yml:
# filebeat.inputs:
# - type: log
# paths: ["/var/log/modsec/audit.log"]
# json.keys_under_root: true
@dataclass
class AlertConfig:
alert: str
condition: str
severity: str
action: str
alerts = [
AlertConfig("Brute Force Detected",
"Same IP blocked > 10 times in 10 min on /login",
"P2 High",
"Block IP 1 hour + Alert Security Team"),
AlertConfig("SQL Injection Attempt",
"Rule 942xxx triggered > 3 times from same IP",
"P1 Critical",
"Block IP + Check if Attack Succeeded + Alert"),
AlertConfig("DDoS Pattern",
"Blocked requests > 1000/hour total",
"P1 Critical",
"Enable Cloudflare Under Attack + Scale WAF"),
AlertConfig("New Attack Pattern",
"New Rule ID triggered first time",
"P3 Medium",
"Review Audit Log + Update Rules if needed"),
AlertConfig("False Positive Spike",
"Legitimate users blocked > 5 in 1 hour",
"P2 High",
"Review Rules + Add Exception + Notify Users"),
]
print("=== Alert Configuration ===")
for a in alerts:
print(f" [{a.alert}] Severity: {a.severity}")
print(f" Condition: {a.condition}")
print(f" Action: {a.action}")
เคล็ดลับ
- DetectionOnly: เริ่มด้วย DetectionOnly Mode 2 สัปดาห์ ก่อนเปิด Block
- PL2: ใช้ Paranoia Level 2 สมดุลระหว่าง Security และ False Positive
- VPN+WAF: ใช้ร่วมกัน VPN ป้องกัน Network WAF ป้องกัน Application
- Geo-block: จำกัดประเทศที่ Remote Workers อยู่จริง
- JSON Log: ใช้ JSON Audit Log ส่ง ELK ง่ายกว่า
ModSecurity คืออะไร
Open Source WAF Apache Nginx OWASP CRS SQL Injection XSS CSRF Brute Force Virtual Patching Rate Limiting Audit Log Detection Prevention