Skip to main content
Lumos Gate Docs

Web Application Firewall

Per-domain WAF with IP blocking, rate limiting, bot protection, and OWASP rules. Runs as HAProxy Lua modules at wire speed on your VPS.

Overview

Lumos Gate includes a built-in Web Application Firewall (WAF) that filters malicious traffic before it reaches your origin servers. The WAF is implemented as HAProxy Lua modules -- each domain gets its own generated Lua script that runs inline with the proxy, filtering requests at wire speed with no external dependencies.

When you configure WAF rules in the dashboard, changes are pushed to the agent via WebSocket in real time. The agent regenerates the Lua WAF scripts and reloads HAProxy. The entire process from dashboard click to live protection takes seconds.

The WAF supports five rule types:

Rule TypeAPI ValueDescription
IP Blacklistblock_ipBlock specific IPs or CIDR ranges
Country Blockblock_countryBlock traffic by 2-letter ISO country code
Rate Limitingrate_limitLimit requests per IP per minute (1-10,000)
Bot Protectionblock_botJavaScript challenge with HMAC cookie verification
Custom RulecustomCustom pattern matching (max 1,000 characters)

Architecture

Request processing pipeline:

  1. Incoming Request → HAProxy Frontend receives the connection
  2. WAF Lua Module (per-domain) runs these checks in order:
    • IP Whitelist check → if matched, bypass all checks
    • IP Blacklist check → if matched, return 403 Forbidden
    • Bot Protection → bad UA block + JS challenge
    • Rate Limit check → if exceeded, return 429 Too Many Requests
    • OWASP pattern matching → SQLi, XSS detection (high level only)
  3. Pass → HAProxy Backend forwards to Origin Server
  4. Block403 or 429 response returned to client

The WAF runs as a Lua script within HAProxy's request processing pipeline. This means:

  • No additional processes -- The WAF is part of HAProxy itself, not a separate service.
  • No latency overhead -- Lua scripts execute in microseconds within the request path.
  • No external dependencies -- No databases, no API calls, everything runs locally on the shield VPS.
  • Automatic cleanup -- Rate limit trackers and stale entries are cleaned up every 5 minutes by a background task, with a maximum of 50,000 tracked IPs before automatic eviction.

WAF Levels

The WAF has three protection levels that control which modules are active. The level determines the baseline behavior even before you configure individual rules:

LevelIP BlacklistRate LimitingOWASP RulesBot Protection
LowYesNo (unless rule added)NoIf enabled
Medium (default)YesYesNoIf enabled
HighYesYesYesIf enabled
  • At low level, only IP blacklist rules are enforced (plus bot protection if you enable it). Rate limiting rules exist in the database but the Lua script does not include rate limit logic.
  • At medium level, both IP blacklist and rate limiting are active. This is the recommended default for most sites.
  • At high level, all protections are active including OWASP pattern matching for SQL injection and XSS detection. Use this for public-facing applications that handle sensitive data.

Important: Bot protection is independent of the level setting. It activates only when you explicitly create a block_bot rule and enable it for a domain.

Per-Domain Configuration

Each domain has its own independent WAF configuration. You can enable or disable the WAF per domain, and each domain can have different rules and levels. This allows you to apply strict protection to public-facing sites while leaving internal APIs or development environments with lighter filtering.

To manage WAF settings:

  1. Navigate to Dashboard -> WAF.
  2. Select the domain you want to configure.
  3. Enable the WAF toggle for that domain.
  4. Set the protection level (low, medium, or high).
  5. Configure individual protection modules (IP blacklist, rate limiting, bot protection).

Tip: If you assign a domain to multiple servers, WAF rules are pushed to all assigned shield servers simultaneously. You do not need to configure each server separately.

Protection Modules

The WAF provides four main protection layers, each documented in detail on its own page:

IP Blacklist

Block specific IP addresses or CIDR ranges from accessing your domain. Also supports a whitelist for trusted IPs that bypass all WAF checks entirely.

See IP Blacklist for detailed configuration including supported formats, whitelist setup, and common use cases.

Rate Limiting

Limit the number of requests per IP address within a one-minute sliding window. The rate limit value must be between 1 and 10,000 requests per minute. When exceeded, clients receive a 429 Too Many Requests response.

See Rate Limiting for detailed configuration including burst allowance, per-domain recommendations, and troubleshooting.

Bot Protection

JavaScript challenge with HMAC cookie verification. Blocks automated bots that cannot execute JavaScript while allowing legitimate browsers and whitelisted search engine crawlers (Googlebot, Bingbot, DuckDuckBot, and others). Known bad bot user-agents (sqlmap, nikto, HeadlessChrome, etc.) are blocked outright.

See Bot Protection for detailed configuration including the challenge flow, HMAC cookie mechanics, and SEO considerations.

OWASP-Inspired Rules

Pattern matching rules that detect common attack patterns in the URL path and query string. These are only active at the high WAF level and include:

  • SQL injection -- Detects UNION SELECT, OR injection, DROP, INSERT, UPDATE, DELETE patterns
  • Cross-site scripting (XSS) -- Detects <script> tags, onerror=, onload=, onclick=, javascript:, vbscript: patterns

These rules are included automatically when the WAF level is set to "high" and do not require manual configuration. They match against the full request path plus query string.

Warning: OWASP rules can produce false positives on sites that accept user-generated content or have URLs containing SQL-like keywords. Monitor the events log carefully after enabling the high level, and consider using the medium level with explicit rate limiting and bot protection if false positives are a problem.

WAF Events Log

Every blocked request is logged and visible in the dashboard. The WAF events API returns the 50 most recent blocked requests. The events log shows:

FieldDescription
TimestampWhen the request was blocked
Source IPIP address of the blocked request
DomainWhich domain the request targeted
ReasonWhy it was blocked (see reason codes below)
Rule IDThe specific WAF rule that triggered the block (if applicable)

Reason Codes

Reason CodeModuleDescription
ip_blockedIP BlacklistSource IP matched a blacklist entry
bot_blockedBot ProtectionUser-agent matched a known bad bot pattern
bot_challengeBot ProtectionClient failed or did not attempt the JS challenge
rate_limitedRate LimitingIP exceeded the requests-per-minute limit
sqli_detectedOWASPURL matched a SQL injection pattern
xss_detectedOWASPURL matched a cross-site scripting pattern

To view WAF events:

  1. Navigate to Dashboard -> WAF.
  2. Select a domain or view events across all domains.
  3. Events are displayed in reverse chronological order.

Note: WAF events have a 7-day retention policy and a cap of 5,000 events per server per day to prevent storage abuse during high-volume attacks.

Processing Order

Understanding the order in which WAF checks execute is important for troubleshooting and rule design. The Lua module processes each request in this exact sequence:

1. IP Whitelist  -> If matched, SKIP all checks, pass to origin
2. IP Blacklist  -> If matched, return 403 Forbidden
3. Bot Protection -> Bad UA check (403) then JS challenge (200 challenge page)
4. Rate Limiting  -> If exceeded, return 429 Too Many Requests
5. OWASP Rules   -> If matched, return 403 Blocked by WAF
6. Pass to origin

Key implications:

  • Whitelisted IPs bypass everything, including rate limiting and bot protection.
  • Blacklisted IPs are blocked before any other processing, so they do not consume rate limit counters.
  • Bot protection runs before rate limiting, so bots that fail the challenge do not inflate rate limit counters for the IP.
  • OWASP rules are checked last, only on requests that passed all other checks.

Real-Time Config Push

WAF configuration changes take effect immediately through the following flow:

Dashboard (WAF rule change)
    |
    v
API saves rule to database + validates input
    |
    v
Config push to WebSocket Server
    |
    v
WebSocket Server receives and forwards to Agent
    |
    v
Agent regenerates Lua WAF script from template
    |
    v
HAProxy reloaded with new WAF rules (zero-downtime reload)

There is no polling interval or delay. The moment you save a WAF rule in the dashboard, it is live on the shield VPS within seconds. If the HAProxy reload fails, the agent automatically rolls back to the previous configuration. See Architecture for details on the config push mechanism.

Enabling the WAF

To enable WAF protection on a domain:

  1. Make sure the domain is added to your Lumos dashboard and assigned to a shield server.
  2. Go to Dashboard -> WAF.
  3. Select the domain.
  4. Toggle WAF Enabled to on.
  5. Choose a protection level (low, medium, or high).
  6. Configure the individual modules (IP blacklist, rate limiting, bot protection) as needed.

To disable the WAF for a domain, simply toggle it off. The domain will continue to be proxied through HAProxy, but the Lua WAF script is replaced with a no-op stub that allows all traffic.

Tip: Disabling the WAF does not delete your rules. When you re-enable it, all previously configured rules are restored automatically.

API Reference

WAF rules can also be managed programmatically using API keys. The WAF API endpoints are:

MethodEndpointDescription
GET/api/wafList all WAF rules for the authenticated user
POST/api/wafCreate a new WAF rule
PUT/api/waf/{id}Update an existing WAF rule
DELETE/api/waf/{id}Delete a WAF rule
GET/api/waf/eventsGet the 50 most recent blocked requests

Creating a Rule (POST /api/waf)

{
  "rule_type": "block_ip",
  "value": "45.33.32.0/24",
  "domain_id": "uuid-of-your-domain",
  "enabled": true,
  "priority": 100
}

Required fields: rule_type, value. The domain_id is optional; if omitted, the rule applies globally. The priority field defaults to 100 (lower numbers execute first).

Validation Rules

Rule TypeValue FormatConstraints
block_ipIP address or CIDRValid IPv4 with optional /0-32 suffix
block_countryISO country codeExactly 2 uppercase letters (e.g., CN, RU)
rate_limitJSON string{"requests_per_minute": 1-10000}
block_botJSON string{"enabled": true}
customPattern stringMax 1,000 characters, no control characters, --, or ]]

Note: Creating or modifying WAF rules requires an active (non-frozen) account. Reading rules and events works with any authenticated session. See Account for details on account status.

Best Practices

  • Start with monitoring. Enable the WAF at the medium level and monitor the events log for a few days before adding aggressive rules. This helps you understand your traffic patterns and avoid blocking legitimate users.

  • Use rate limiting conservatively. Set limits that are reasonable for your traffic. A blog might handle 60 requests per minute per IP, while an API endpoint might need 300. See the rate limiting page for per-service recommendations.

  • Whitelist trusted IPs. Add your own IPs, monitoring services (UptimeRobot, Pingdom), and trusted partners to the IP whitelist so they bypass WAF checks entirely. See IP Blacklist for whitelist configuration.

  • Review events regularly. Check the WAF events log periodically to spot attack patterns and adjust rules accordingly. Consistent rate_limited events from the same IP may warrant escalation to the IP blacklist.

  • Enable bot protection selectively. The JS challenge adds a brief delay on first visit. Enable it on domains that face bot abuse, but disable it for API endpoints that receive legitimate automated traffic. See Bot Protection for guidance on when to enable it.

  • Combine with origin firewall. WAF rules protect at the proxy level, but you should also lock down your origin server's firewall to only accept traffic from your shield VPS. See Origin Firewall for setup instructions.

  • Use WireGuard for sensitive traffic. For maximum security, route traffic between your shield VPS and origin through an encrypted WireGuard tunnel so even your VPS provider cannot inspect the traffic.

Troubleshooting

WAF rules not taking effect:

  • Verify the agent is connected (check server status in Dashboard -> Servers).
  • Confirm the WAF is enabled for the specific domain, not just that rules exist.
  • Check that the WAF level is appropriate -- rate limiting requires medium or high, OWASP requires high.
  • Look at the agent logs for config update or HAProxy reload errors. See Troubleshooting for log locations.

False positives blocking legitimate users:

  • Check the WAF events log to identify which module is blocking (reason code tells you exactly which check failed).
  • Lower the WAF level from high to medium if OWASP rules are causing false positives.
  • Increase rate limits or add trusted IPs to the whitelist.
  • Disable bot protection for API endpoints.

High WAF event volume:

  • Events are capped at 5,000 per server per day. If you are hitting this limit, consider blocking the offending IP ranges in the IP blacklist to reduce event volume.
  • Events older than 7 days are automatically purged.

Account is frozen and cannot modify WAF rules:

  • WAF rule creation and modification require an active account. Deposit credits to unfreeze your account. Existing WAF rules continue to function on the agent even while your account is frozen.

Next Steps

  • IP Blacklist -- Block specific IPs and configure trusted IP whitelists
  • Rate Limiting -- Configure per-domain request rate limits
  • Bot Protection -- Set up JavaScript challenges to block automated traffic
  • Origin Firewall -- Lock down your origin server to only accept traffic from shield VPS
  • WireGuard Tunnel -- Encrypt traffic between shield and origin servers
  • Domains -- Manage domains and origin server assignments
  • Architecture -- Understand the full config push and WAF pipeline
  • Troubleshooting -- Common issues and solutions