```json
{
    "title": "Enterprise Shield: The flow and general process",
    "url": "https://performancezen.com/2026/05/08/enterprise-shield-the-flow-and-general-process/",
    "datePublished": "2026-05-08",
    "dateModified": "2026-05-08",
    "language": "en-US",
    "description": "So, for those who are interested here is the current processing flow and update cycles for my Enterprise Shield and Bot Filtering setup. Currently this setup comfortably supports blocking 425,000…",
    "author": "spierzchala",
    "publisher": "Performance Zen"
}
```

# Enterprise Shield: The flow and general process

So, for those who are interested here is the current processing flow and update cycles for my [Enterprise Shield](https://performancezen.com/2026/04/02/enterprise-shield-on-dinosaur-hardware/) and Bot Filtering setup.

Currently this setup comfortably supports blocking 425,000 CIDR Blocks and 10K AbuseIPDB IPs, with additional processing for cloud providers that depends on the rate they send traffic through.

Attackers, do what you will.

Enterprise Shield — Request Processing Flow
 A three-layer flowchart showing how incoming requests are processed through the kernel SHIELD-LOGIC chain, Apache mod_rewrite UA filter, and WordPress/Wordfence application layer.

 text { font-family: 'Segoe UI', Arial, sans-serif; }
 .lh { font-size: 14px; font-weight: 600; }
 .ls { font-size: 12px; }
 line { stroke: #B4B2A9; stroke-width: 1.5; fill: none; marker-end: url(#arr-head); }

 Inbound request

 Kernel — SHIELD-LOGIC chain

 Trusted source?
 Loopback · ESTAB/RELATED · LAN · CDN IPs

 AbuseIPDB penalty box?
 SHIELD_PENALTY ipset — updated 5 times daily (AbuseIPDB Free API)

 Blocked ASN or country?
 blocked_asns ipset — rebuilt nightly at 02:00 UTC

 Known AI crawler UA?
 GPTBot · ClaudeBot · Google-Extended · others

 Apache — mod_rewrite UA filter

 UA block rules?
 Bot strings · outdated browsers · attack patterns

 Application — WordPress / Wordfence / PHP

 Legitimate request served
 Wordfence WAF evaluates · WordPress delivers content

 Accept

 Silent drop
 AbuseIPDB match

 Silent drop
 ASN / country match

 rDNS verify
 Accept or drop

 403 GO AWAY!

.es-wrap{font-family:'Segoe UI',system-ui,-apple-system,sans-serif;font-size:14px;line-height:1.6;color:#1a1a1a;border:1px solid #e0ddd5;border-radius:10px;margin:1.5rem 0;background:#fff}
.es-head{padding:1.25rem 1.5rem;border-bottom:1px solid #e8e6e0}
.es-head h3{font-size:1rem;font-weight:600;color:#111;margin:0 0 .2rem}
.es-head p{font-size:.8rem;color:#666;margin:0}
.es-utc{display:inline-block;margin-top:.4rem;font-size:.72rem;color:#666;background:#f8f7f3;border:1px solid #e0ddd5;border-radius:4px;padding:.1rem .4rem}

/* Horizontal scroll wrapper */
.es-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}

/* table-layout:fixed + colgroup controls column widths */
.es-table{width:100%;min-width:560px;border-collapse:collapse;table-layout:fixed}
.es-table thead tr{background:#f8f7f3;border-bottom:2px solid #e0ddd5}
.es-table th{padding:.6rem .85rem;text-align:left;font-size:.65rem;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#555}
.es-table tbody tr{border-bottom:1px solid #eeece6}
.es-table tbody tr:last-child{border-bottom:none}
.es-table td{padding:.85rem .85rem;vertical-align:top;font-size:.78rem;color:#2a2a2a;overflow-wrap:break-word;word-wrap:break-word}
.es-table td:nth-child(2){color:#444}

/* Component name in col 1 */
.es-mono{font-family:'Consolas','SF Mono',monospace;font-size:.72rem;font-weight:600;display:block;margin-bottom:.25rem;color:#1a1a1a;overflow-wrap:break-word;word-break:break-word}

/* Layer + cycle badges */
.es-badge{display:inline-block;padding:.1rem .45rem;border-radius:20px;font-size:.64rem;font-weight:500;white-space:nowrap}
.es-bk{background:#EEEDFE;color:#3C3489}
.es-ba{background:#E1F5EE;color:#085041}
.es-bw{background:#EAF3DE;color:#27500A}
.es-cycle{display:inline-flex;align-items:center;gap:.25rem;padding:.15rem .5rem;border-radius:5px;font-size:.72rem;font-weight:600;white-space:nowrap}
.es-cn{background:#E6F1FB;color:#0C447C;border:1px solid #9FC8F0}
.es-ch{background:#FFF3CD;color:#7D4E00;border:1px solid #F0C96B}
.es-cm{background:#F1EFE8;color:#444441;border:1px solid #B4B2A9}
.es-ce{background:#EEEDFE;color:#3C3489;border:1px solid #AFA9EC}
.es-cw{background:#FAECE7;color:#4A1B0C;border:1px solid #F0997B}
.es-dot{width:6px;height:6px;border-radius:50%;display:inline-block;flex-shrink:0}
.es-dn{background:#185FA5}.es-dh{background:#E8A020}.es-dm{background:#888780}.es-de{background:#534AB7}.es-dw{background:#D85A30}

/* List: position:absolute arrow avoids making code elements flex items */
.es-list{list-style:none;padding:0;margin:0}
.es-list li{position:relative;padding-left:1.1rem;margin-bottom:.5rem;font-size:.76rem;line-height:1.5}
.es-list li::before{content:'→';color:#bbb;position:absolute;left:0;top:0}

/* Inline code: span avoids theme CSS interference */
.es-code{font-family:'Consolas','SF Mono',monospace;font-size:.7rem;background:#f0ede6;padding:.08rem .28rem;border-radius:3px;color:#2a2a2a}

/* Block command: sits on its own line, breaks on long strings only */
.es-cmd{display:block;font-family:'Consolas','SF Mono',monospace;font-size:.7rem;background:#f0ede6;padding:.2rem .4rem;border-radius:4px;color:#2a2a2a;margin:.2rem 0;overflow-wrap:break-word;word-break:break-all}

.es-note{font-size:.68rem;color:#888;margin-top:.15rem;display:block}
.es-foot{padding:.75rem 1.5rem;background:#f8f7f3;border-top:1px solid #e8e6e0;font-size:.7rem;color:#888;border-radius:0 0 9px 9px;overflow-wrap:break-word}

Enterprise Shield — Component Update Cycles
 Scheduled refresh intervals and out-of-band injection methods for each protection layer.

 🕐 All scheduled times are UTC

 Component
 What it controls
 Update cycle (UTC)
 Out-of-band injection

 blocked_asns ipset
 Kernel

 IP ranges for all ASNs in blocklist_asns.txt, resolved via RADB WHOIS using 8 parallel threads
 Nightly — 02:00

 **Penalty box (temporary):**
 sudo block_asn.sh AS9009
 Live inject. Cleared at next 02:00 UTC run.

 **Permanent block:**
 sudo block_asn.sh --permanent AS9009
 Writes to blocklist and injects live. Persists forever.

 Country IP blocks
 Kernel

 IPv4 CIDRs for blocked countries from the ipverse GitHub feed, merged into the same blocked_asns ipset
 Nightly — 02:00

 **CIDR penalty box:**
 sudo block_asn.sh --cidr 1.2.3.0/24
 Live inject only. Cleared at next 02:00 UTC run.

 **Add country permanently:** Edit BLOCK_COUNTRIES in enterprise_shield.sh and re-run.
 Takes effect immediately; persists.

 SHIELD_PENALTY ipset
 Kernel

 Top abusive IPs from AbuseIPDB API (≥ 90% confidence). Evaluated before the ASN chain in iptables INPUT
 5x Daily — :00

 **No manual add.** The set is atomically replaced each run. To block an IP immediately, use block_asn.sh --cidr <IP>/32 against the main ipset instead.
 **Force early refresh:**
 sudo /usr/local/bin/abuseipdb_penaltybox.sh

 AI bot verifier
 Kernel

 Python daemon on NFQUEUE 10. Intercepts known AI crawler UAs (GPTBot, ClaudeBot, Google-Extended) and verifies via rDNS before allowing or dropping
 On service restart

 **Add a new AI bot UA:** Edit the NFQUEUE rules in enterprise_shield.sh, then:
 sudo systemctl restart shield-ai-bot.service

 **Rebuild the full chain:**
 sudo /usr/local/bin/enterprise_shield.sh

 mod_rewrite UA rules
 Apache

 Apache-level .htaccess and VirtualHost rewrite rules blocking by UA string, version ranges, empty UAs, and attack patterns. Returns 403 GO AWAY! inline — no PHP, no WordPress bootstrap
 Manual

 **Add bot string:** Append a RewriteCond to .htaccess, then:
 sudo apachectl graceful
 Takes effect immediately with no dropped connections.

 **Update browser version range:** Edit the version regex, then run apachectl graceful.
 Must cover the ESR floor and current version ceiling.

 **IP block at Apache layer:** Add Require not ip <addr> to the VirtualHost config.

 Wordfence WAF
 WordPress

 PHP-layer WAF bootstrapped before WordPress via waf/bootstrap.php. Independently evaluates every request surviving Apache, checks Wordfence’s threat database, and serves its own 403 pages from wp-content/wflogs/

 Automatic
 Free: 30-day rule delay.
Premium: real-time feed.

 **Block an IP immediately:** WP-Admin → Wordfence → Blocking → Create a Block → Block by IP
 No server restart required.

 **Add a custom firewall rule:** WP-Admin → Wordfence → Firewall → Custom Patterns
 Can match on IP, UA, referrer, URL, or request parameter.

 **Force rule sync:** WP-Admin → Wordfence → Firewall → Sync Firewall Rules

 Boot persistence: shield-ipset-restore → ufw.service → shield-iptables-restore → shield-ai-bot.service. All ipsets and chains restored on reboot. All times UTC.
