High-performance .NET 10 WAF & Reverse Proxy with Browser Fingerprinting, Bot Scoring and Global Ban Sync.
π‘ Want deep L7 inspection with Python DPI, body scanning and Log4Shell detection? Check out β ShieldX-L7-DeepDefense
Shield-X Proxy is a standalone .NET 10 WAF and reverse proxy β one process, no Python required. It sits in front of your backend and filters every request through a multi-stage security pipeline before it ever reaches your app.
Designed for global scale: bans issued on one node are instantly propagated across the entire cluster via Redis Pub/Sub.
Internet
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββ
β Shield-X Proxy V7 (.NET 10) β
β β
β βββββββββββββββββββββββββββββββββββββββββββ β
β β Security Pipeline β β
β β β β
β β 1. Loopback / Whitelist β pass β β
β β 2. IP Ban (L1 cache) β 403 β β
β β 3. IP Ban (Redis L2) β 403 β β
β β 4. FP Ban (L1 cache) β 403 β β
β β 5. FP Ban (Redis L2) β 403 β β
β β 6. Geo-IP block β 403 β β
β β 7. Bot Score evaluation β 403 / pass β β
β β 8. Rate Limit (30/10s) β 429 β β
β β 3x violation β BAN IP β β
β βββββββββββββββββββββββββββββββββββββββββββ β
β β
β YARP Reverse Proxy β
β /proxy/{**} β your backend β
β β
β SignalR Dashboard (flush every 1s) β
β Async log writer β logs.txt β
ββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β Redis Pub/Sub
βΌ
Other cluster nodes
(instant ban sync)
Every request gets a 16-char SHA-256 fingerprint computed from:
| Header | Field |
|---|---|
User-Agent |
Browser/client identity |
Accept-Language |
Language preferences |
Accept-Encoding |
Compression support |
Accept |
Content type preferences |
Sec-Ch-Ua |
Client hints β browser brand |
Sec-Ch-Ua-Mobile |
Mobile indicator |
Sec-Ch-Ua-Platform |
OS platform |
| Header order | First 8 header names in order |
The fingerprint is independent of IP β bots that rotate IPs or VPNs stay blocked.
Each request is scored based on HTTP stack characteristics:
| Signal | Score |
|---|---|
Missing User-Agent entirely |
+40 |
Known bot UA (curl, wget, python-requests, go-http-client, selenium, playwright, scrapy...) |
+35 |
Missing Accept-Language |
+20 |
Missing Accept-Encoding |
+15 |
Missing Accept |
+10 |
Postman-Token header present |
+10 |
Missing Cookie |
+5 |
| Max score | 100 |
Score actions:
| Condition | Action |
|---|---|
score >= BotScoreThreshold (default 60) |
Increment FP violation counter |
FP violations >= FingerprintViolationLimit (default 5) |
BAN fingerprint |
FP violations >= limit AND score >= 80 |
BAN fingerprint + BAN IP |
Request In
β
ββ Loopback IP? β pass through (dashboard access)
ββ Whitelisted IP? β pass through
β
ββ IP ban in L1 cache? β 403 (shows remaining ban time in minutes)
ββ IP ban in Redis? β 403 + cache locally
β
ββ FP ban in L1 cache? β 403
ββ FP ban in Redis? β 403 + cache locally
β
ββ Geo-IP blocked? β 403 + GeoBlock event
β
ββ Bot score >= threshold β increment FP violations
β ββ violations >= limit β BanFingerprintAsync() + BotEvent
β β ββ score >= 80 β BanIpAsync() + BanEvent
β ββ 403
β
ββ pass through β YARP proxy β backend
β
ββ Response 429? β increment IP violations
ββ violations == 3 β BanIpAsync()
Events are batched and flushed to the dashboard every 1 second via System.Timers.Timer:
| SignalR Method | Triggered by | Payload includes |
|---|---|---|
BanEvent |
IP banned (bot score or rate limit) | ip, country, expiry, duration |
BotEvent |
Bot score threshold hit or FP banned | ip, fingerprint, score, country, violations, expiry |
ViolationEvent |
Rate limit 429 hit | ip, country, count, threshold |
GeoBlock |
Country blocked | ip, country |
ShieldX-Proxy/
βββ Program.cs # Full WAF pipeline β single file
βββ appsettings.json # Configuration
βββ GeoLite2-Country.mmdb # MaxMind GeoIP database
βββ blacklist.txt # Static IP blacklist
βββ logs.txt # Async log output
βββ wwwroot/
β βββ dashboard.html # Real-time SOC dashboard (SignalR)
βββ TestStron.csproj
βββ TestStron.sln
{
"Redis": { "ConnectionString": "localhost:6379" },
"GeoIp": {
"DbPath": "GeoLite2-Country.mmdb",
"BlockedCountries": ["CN", "RU", "KP", "IR"]
},
"BanDuration": "01:00:00",
"BanCacheTtl": "00:00:10",
"ViolationDecayTtl": "01:00:00",
"BotScoreThreshold": 60,
"FingerprintViolationLimit": 5,
"TrustedProxies": ["127.0.0.1"],
"WhitelistedIps": ["your-ip-here"]
}| Parameter | Default | Description |
|---|---|---|
Redis.ConnectionString |
localhost:6379 |
Redis server address |
GeoIp.BlockedCountries |
[] |
ISO country codes to block |
BanDuration |
1h |
How long a ban lasts |
BanCacheTtl |
10s |
Local L1 cache TTL for bans |
ViolationDecayTtl |
1h |
How long violation counters live in Redis |
BotScoreThreshold |
60 |
Minimum score to trigger violation tracking |
FingerprintViolationLimit |
5 |
Violations before fingerprint ban |
TrustedProxies |
[] |
IPs allowed to set X-Forwarded-For |
WhitelistedIps |
[] |
IPs that bypass all checks |
- .NET 10 SDK
- Redis running on
localhost:6379 GeoLite2-Country.mmdb(included in repo β see GeoIP note below)
git clone https://github.com/InsaneInfinity/ShieldX-Proxy.git
cd ShieldX-Proxy
dotnet run
# Dashboard β http://localhost:5000/dashboard.htmlNo Redis? Shield-X uses AbortOnConnectFail = false β it starts anyway and operates in local-only mode. Ban sync across nodes is disabled but the full pipeline still works.
Edit Program.cs β find the cluster config and replace httpbin.org with your backend:
{ "dest1", new DestinationConfig { Address = "https://your-backend.com" } }Requests to /proxy/anything are forwarded to /anything on your backend (prefix stripped automatically).
GeoLite2-Country.mmdb is included in this repo for convenience. It is subject to MaxMind's GeoLite2 license. To get the latest database:
- Register at maxmind.com
- Download GeoLite2-Country (
.mmdbformat) - Replace the file in the repo root
# Normal request β should pass through to httpbin.org
curl http://localhost:5000/proxy/get
# Simulate bot (curl UA triggers +35 score)
curl -v http://localhost:5000/proxy/get
# Simulate high-score bot (missing most headers)
curl --no-alpn -A "" http://localhost:5000/proxy/get
# Rate limit β 31 requests in 10 seconds triggers 429
for i in $(seq 1 35); do curl -s http://localhost:5000/proxy/get > /dev/null; done
# Check dashboard
open http://localhost:5000/dashboard.htmlShield-X Proxy V7 to samodzielny WAF i reverse proxy napisany w .NET 10 β bez ΕΌadnych zaleΕΌnoΕci od Pythona.
KaΕΌde zapytanie przechodzi przez 8-etapowy pipeline: whitelist β ban IP (L1 cache + Redis) β ban fingerprint (L1 cache + Redis) β Geo-IP β Bot Score β rate limit. Browser Fingerprinting tworzy 16-znakowy hash SHA-256 z nagΕΓ³wkΓ³w HTTP i ich kolejnoΕci β boty zmieniajΔ ce IP lub VPN pozostajΔ zablokowane. System Bot Scoring przyznaje punkty za podejrzane sygnaΕy (brak UA, znane narzΔdzia jak curl/selenium/playwright, brak standardowych nagΕΓ³wkΓ³w przeglΔ darki). Po przekroczeniu progu 5 naruszeΕ ban jest nakΕadany na fingerprint, a przy score β₯ 80 β takΕΌe na IP.
Bany sΔ
synchronizowane przez Redis Pub/Sub β kaΕΌdy wΔzeΕ klastra natychmiast wie o nowym banie. Dashboard SignalR odbiera zdarzenia paczkowane co 1 sekundΔ. Logi zapisywane sΔ
asynchronicznie przez bounded channel do pliku logs.txt.
MIT β free to use, modify and distribute. See LICENSE.txt for details.
Disclaimer: This project was developed for educational purposes and infrastructure security audits. Always ensure compliance with local laws when deploying security tools.
Built with β€οΈ β because "standard" protection is never enough.