Repository navigation
Front Door Ban Ladder
Reference for the two rules in rulesdemidocs that turn away document downloads from listed
addresses. The rule set is on the demi-documents route (/demi-search/documents/*) of
eagle-edge-<env>. The rules are banmanual (a person adds addresses) and banauto (DEMI's
edge-ban timer adds addresses, described on the DEMI wiki page Edge-Ban-Detector). The Front Door
side is in eagle-edge (azure/modules/front-door.bicep, README section "Ban ladder"). Other
Front Door rules are in Front-Door-Per-App-Split.
| Order | Rule | Does |
|---|---|---|
| 1 | stripauthsearch |
Drops Authorization
|
| 2 | blockscraperua |
302 to /robots.txt for the scraper user agent, stops the rule set |
| 3 | stampedgesecret |
Stamps X-Edge-Secret
|
| 4 | banmanual |
Counts or blocks addresses in its list |
| 5 | banauto |
Counts or blocks addresses in its list |
| 6 | redirect | Legacy redirect=1&inline=1 links |
| 7, 8 | rewrites | 24-hex and UUID download paths onto APIM /api/documents/*
|
Legacy permalinks on ruleseagleapi redirect into this route first, so they pass the ladder too.
Both rules match SocketAddr with IPMatch: the address that opened the connection to Front
Door. RemoteAddress is not used because it follows X-Forwarded-For, which a client can set.
One list entry is an IPv4 /32 or an IPv6 /64. The detector refuses anything wider. Do not add
a wider prefix by hand: it turns away every download behind it.
Front Door rejects a condition with no values. An empty list deploys the placeholder
192.0.2.1/32 (TEST-NET-1, never seen on a public edge).
| Parameter | Default | Does |
|---|---|---|
edgeBanAction |
count |
count or block, for both rules. Set in main.<env>.bicepparam; test and prod set block. |
edgeBanManual |
[] |
banmanual addresses, filled by deploy-infra.sh from the live rule |
edgeBanAuto |
[] |
banauto addresses, filled by deploy-infra.sh from the live rule |
demiIdentityPrincipalId |
empty | Object id of demi-identity-<env>. Gets CDN Profile Contributor on the rulesdemidocs rule set only. Empty grants nobody. |
demi-identity-<env> is in c4b0a8-test-rg on test and rg-demi-prod on prod:
az identity show --subscription <sub> -g <rg> -n demi-identity-<env> --query principalId -o tsvedgeBanAction |
Request from a listed address |
|---|---|
count |
Passes. The rule adds X-Edge-Ban: count toward DEMI, which ignores it. The client sees nothing. The rule name shows in rulesEngineMatchNames_s in the access log. |
block |
Answers 302 to /blocked.html on the same host and stops the rule set. |
/blocked.html is a file on the eagle-public static site, served by the default route. That
route does not use rulesdemidocs, and spafallback rewrites only paths with no file extension,
so the redirect cannot loop. Publish the page on the site before setting block. Only /demi-search/documents/* is covered. Legacy /api/... document links redirect there first, so they are covered too.
A change takes 7 to 25 minutes to reach every edge. There is no instant rollback.
The address lists are not in the repo. A deploy writes every rule again, lists included, so
scripts/deploy-infra.sh reads the live lists with az afd rule show and passes them back as
EDGE_BAN_MANUAL and EDGE_BAN_AUTO. A missing rule gives the placeholder. Any other read error
stops the script before it deploys.
A timer write between that read and the deploy is lost; the next timer run writes it again. A
deploy that skips the script, such as az deployment group create by hand, resets both lists to
the placeholder.
-
Read the list:
az afd rule show -g <rg> --profile-name eagle-edge-<env> --rule-set-name rulesdemidocs -n banmanual \ --query "conditions[0].parameters.matchValues"
-
Write it back with the address added or removed. Use an IPv4
/32or IPv6/64. Keep the placeholder only while the list is otherwise empty.az afd rule update -g <rg> --profile-name eagle-edge-<env> --rule-set-name rulesdemidocs -n banmanual \ --set 'conditions[0].parameters.matchValues=["203.0.113.7/32"]'
The next deploy keeps the list. To clear banauto, set EDGE_BAN_MODE=off on DEMI's function app
(see the DEMI wiki page Edge-Ban-Detector). banmanual is cleared only by hand, as above.
The detector reads the access log as demi-identity-<env>. scripts/bootstrap-cicd.sh step 5
assigns Log Analytics Reader on workspace eagle-logs-<env> to that identity. If the workspace or
the identity does not exist, the step prints skipped and the script continues; rerun it once
both exist.
Run in eagle-logs-<env>. It lists each address a ban rule matched, per hour, with the distinct
documents it asked for:
AzureDiagnostics
| where Category == "FrontDoorAccessLog" and rulesEngineMatchNames_s contains "rulesdemidocs_ban"
| extend rule = extract(@"rulesdemidocs_(ban[a-z]+)", 1, rulesEngineMatchNames_s), doc = extract(@"/documents/([^/?]+)/download", 1, requestUri_s)
| summarize requests = count(), documents = dcount(doc), statuses = make_set(httpStatusCode_s, 5) by socketIp_s, rule, bin(TimeGenerated, 1h)
| order by TimeGenerated desc, requests desc
The rollout steps for the detector are on the DEMI wiki page Edge-Ban-Detector.
Eagle Documentation
Operations
- Deployment Pipeline
- Helm Charts
- Reverse Proxy
- Rollback Procedures
- Eagle Public Release Lines
- Eagle Search Archive
- Azure Migration Strategy
- Azure Hosting
- Front Door Per-App Split
- Front Door Ban Ladder
- Error Logging
- Secrets Management
Architecture
- Architecture Overview
- API Architecture
- Analytics Architecture
- Angular Patterns
- Eagle Public Page Layout
- Eagle Public Adding A Page
- Extended Project Pages
- ENGAGE–EAGLE Integration
- BCGW Project Export
- Eagle Search
- Document Content Search
- Eagle DEMI
- Eagle DEMI Push Sweep
- Eagle DEMI Re-Push and Backfill
- Eagle Notify
- Project Data Models
- Async Jobs API
- Bulk Document Download
Configuration
Help
Repositories
Environments