SiamCafe · Blog
ModSecurity WAF Remote Work Setup — ตั้งค่า Web
บทความ

ModSecurity WAF Remote Work Setup — ตั้งค่า Web

เผยแพร่ 28 พฤษภาคม 2569

ModSecurity WAF Remote Work

ModSecurity WAF Remote Work VPN OWASP CRS SQL Injection XSS Brute Force Geo-blocking Rate Limiting Zero Trust Production

AttackOWASP CRS RuleRemote Work RiskPrevention
SQL Injection942xxxสูง (Public-facing App)CRS PL2 + Virtual Patch
XSS941xxxสูงCRS PL2 + CSP Header
Brute ForceCustom Rate Limitสูงมาก (Login จากทุกที่)Rate Limit + Account Lock
Path Traversal930xxxปานกลางCRS PL1
Bot AttackCustom UA RuleสูงBot Detection + CAPTCHA
DDoSCustom 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