# **StyloBot: Så enkelt som möjligt och inte så enkelt (Teil 3)**

*Enterprise-botdetektorn borde inte kräva en doktorsexamen i infrastruktur. ( eller tusen i månaden för att använda den.*

**[Read Part 1: StyloBot: Kämpar tillbaka mot schackare](https://www.mostlylucid.net/blog/botdetection-introduction)**

**[Lees del 2: Hur botar blev smartare](https://www.mostlylucid.net/blog/botdetection-part2-signature-pipeline-and-stylobot-architecture)**

**[👉 Se det live: StyloBotM SK2net](https://stylobot.net)** - Den verkliga produktionssystemet körs tidigt -

<!--category-- ASP.NET, Bot Detection, Security, Architecture -->
<datetime class="hidden">2026-02-16T10:30</datetime>

[![NuGet](https://img.shields.io/nuget/v/mostlylucid.botdetection.svg)](https://www.nuget.org/packages/mostlylucid.botdetection/)
[![GitHub](https://img.shields.io/github/stars/scottgal/stylobot?style=social)](https://github.com/scottgal/stylobot)
[![Docker](https://img.shields.io/docker/pulls/scottgal/stylobot-gateway)](https://hub.docker.com/r/scottgal/stylobot-gateway)

---


[TOC]

---


## Idéen

Einstein ansåg att allting skulle göras så enkelt som möjligt. , men inte så enkelt, ." Det är ' som designprincipen bakom StyloBot och ' som är integreringsmodell.

Delarna 1 och 2 täckt *varför* bot-detektorer och *hur det detekterade pipelinet fungerar*. Denna artikel omfattar *hur liten kod du faktiskt behöver* - och hur samma system skalar från en enda plikapp till ett komplettt produktionsportaal med TimescaleDB, Qdrant-vektorsökningen , och CPUM SK4 endast LLM-klassificering

Den viktigaste insikten **varje nivå använder samma detektionskanal**. Du, ', skiftar inte fram konstruktioner när du växer.

---


## Två rader kod

Detta är det absoluta minimumet. Inga konfigurationsfiler ,

```csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddBotDetection();       // ← that's line 1

var app = builder.Build();
app.UseBotDetection();                    // ← that's line 2
app.Run();
```

Vad har just hänt?

- **21-detektorer** registrerad: UserAgent mönster matchingM SK1 headerkonsistens , IP datacenter-detektor-detection, beteendeanalysMska4 TLS fingerprinting Mske5 JA Mska6JA Mske7 TCP / IP fingerprintningMsko9 HTTP M Ska10 fingerprintingsM Ska11 cache-beteende-analys, Mska12 responsbeteendens återkoppling, , multi, M Ska14, lagerkorrelation, ,, och mer,Mska16
- **Pipeline baserat på våg**: Detektorer körs i beroendevågor . Wella | | 0 | ( | inga beroenden | МSK4 | utför parallellt |. | Senare vågor triggar bara när tidigare signaler kräver mer djupgående analys
- **SQLite lagring**: A `botdetection.db` file auto- skapar lärde mönster och vikter. Ingen konfiguration
- **In-processliknande sök**: HNSW-index för att hitta liknande Bot-signaturer . Ingen extern vektordatabas
- **Heuristisk poäng**: ~50 egenskaper extraherade per begäran

Allt det här körs in **under 1 millisekund** per fråga på handelshardware. endast CPU , ingen GPU

Varje begäran har nu detektionsresultat tillgängliga via `HttpContext` förlängningar:

```csharp
app.MapGet("/", (HttpContext ctx) => Results.Ok(new
{
    isBot = ctx.IsBot(),
    probability = ctx.GetBotProbability(),     // 0.0-1.0: how likely it's a bot
    confidence = ctx.GetDetectionConfidence(),  // 0.0-1.0: how certain the system is
    type = ctx.GetBotType()?.ToString(),
    name = ctx.GetBotName()
}));
```

Detektorn går igång men inget blockerar.. Du bestämmer vad du ska göra med resultaten.

---


## Blokera alla Bots, Hela App

Om du bara vill blockera robotar från hela din application - inga per- slutpunkt configM SK2 inga attribut - detMSC4 en rad JSON

```json
{
  "BotDetection": {
    "BlockDetectedBots": true
  }
}
```

Det är "'". Det är det. Det detekterade robotar ovanför din block, - och självförtroende tröskeln får en`MinConfidenceToBlock` defaults till `0.8`sökmotorer Googlebot Bingbot ( Facebook , Twitter / X ), och övervakningsrobotar ( UptimeRobot , Pingdom ) är standardmässigt tillåtna eftersom du nästan definitivt vill ha dem

Eller samma sak i koden

```csharp
builder.Services.Configure<BotDetectionOptions>(o =>
{
    o.BlockDetectedBots = true;
    o.MinConfidenceToBlock = 0.8;           // only block when confident
    o.AllowVerifiedSearchEngines = true;     // Googlebot, Bingbot through
    o.AllowSocialMediaBots = true;           // Facebook, Twitter previews through
    o.AllowMonitoringBots = true;            // UptimeRobot, Pingdom through
});
```

Det här är """. Jag vill inte tänka på det. " "", modet, . "" Detektorn kör "", , "" Boten blir blockerade, , "", bra klättrar går igenom "". . "", rör sig till "" per "",- "", slutpunktkontroll när du behöver den.

---


## Minimal API: Det kompletta exemplet

Här är "'" en komplett "," -drivande API med per , "-" och endpoint bot protection . `Program.cs`:

```csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddBotDetection();

var app = builder.Build();
app.UseBotDetection();

// Detection results available, no blocking
app.MapGet("/", (HttpContext ctx) => Results.Ok(new
{
    isBot = ctx.IsBot(),
    probability = ctx.GetBotProbability(),
    confidence = ctx.GetDetectionConfidence(),
    type = ctx.GetBotType()?.ToString(),
    name = ctx.GetBotName()
}));

// Block all bots
app.MapGet("/api/data", () => Results.Ok(new { data = "sensitive" }))
   .BlockBots();

// Allow search engines (Googlebot, Bingbot, Yandex)
app.MapGet("/products", () => Results.Ok(new { catalog = "public" }))
   .BlockBots(allowSearchEngines: true);

// Allow search engines + social media previews (Facebook, Twitter/X)
app.MapGet("/blog/{slug}", (string slug) => Results.Ok(new { post = slug }))
   .BlockBots(allowSearchEngines: true, allowSocialMediaBots: true);

// Health check: monitoring bots allowed (UptimeRobot, Pingdom)
app.MapGet("/health", () => Results.Ok("healthy"))
   .BlockBots(allowMonitoringBots: true);

// Humans only - blocks ALL bots including verified crawlers
app.MapPost("/api/submit", () => Results.Ok(new { submitted = true }))
   .RequireHuman();

// High-confidence blocking only (reduces false positives)
app.MapGet("/api/lenient", () => Results.Ok("data"))
   .BlockBots(minConfidence: 0.9);

// Geo + network blocking (needs GeoDetection contributor)
app.MapPost("/api/payment", () => Results.Ok("ok"))
   .BlockBots(blockCountries: "CN,RU", blockVpn: true, blockDatacenter: true);

// Honeypot: deliberately allow scrapers in
app.MapGet("/honeypot", () => Results.Ok("welcome"))
   .BlockBots(allowScrapers: true, allowMaliciousBots: true);

// Dev diagnostics
app.MapBotDetectionEndpoints();

app.Run();
```

Varje `.BlockBots()` ringblöcke **alla** bot-typer standardmässigt. Du väljer specifika typer *i* med `Allow*` parametrar. Tanken är att förneka-avM SK2defaultMSC3 att göra en vitlista av de bra

### Bot-typer du kan tillåta

| Parameter
|-----------|---------------|-----------------|
| `allowSearchEngines` | Googlebot, Bingbot , Yandex | SEO - du vill bli indexerad |
| `allowSocialMediaBots` | FacebookM SK1 Twitter/XMSC3 LinkedIn | Link previewsMska5 Open Graph cards mska6
| `allowMonitoringBots` | UpptimeRobot, PingdomM SK2 StatusCake | hälsokontroller , upptime-monitoring
| `allowAiBots` |, GPTBot, ,, ClaudeBot, ,, Google, M SK3, Extended, |, Opt och -, till AI-utbildning.
| `allowGoodBots` | Feedreader , länkarna kontroller | | | Benign-automation ||
| `allowVerifiedBots` | DNS
| `allowScrapers` | AhrefsBot
| `allowMaliciousBots` | Bekänna dåliga skådespelare | Honigburkar
| `minConfidence` | *( tröskel* | Bara blockera när systemet är väldigt säker |

---


## MVC Controllers: egenskaper

Samma detekteringssledning, skydd genom attributer.

```csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddBotDetection();
builder.Services.AddControllersWithViews();

var app = builder.Build();
app.UseBotDetection();
app.MapControllers();
app.Run();
```

### Attityderna

```csharp
[ApiController]
[Route("[controller]")]
public class ProductsController : ControllerBase
{
    // No protection - detection runs but nothing blocks
    [HttpGet]
    public IActionResult List() => Ok(new { products = "all" });

    // Block all bots, allow search engines
    [HttpGet("catalog")]
    [BlockBots(AllowSearchEngines = true)]
    public IActionResult Catalog() => Ok(new { catalog = "indexed" });

    // Block all bots, allow search engines + social previews
    [HttpGet("{id:int}")]
    [BlockBots(AllowSearchEngines = true, AllowSocialMediaBots = true)]
    public IActionResult Detail(int id) => Ok(new { id });
}

// Entire controller: humans only
[ApiController]
[Route("[controller]")]
[RequireHuman]
public class CheckoutController : ControllerBase
{
    [HttpPost("cart")]
    public IActionResult AddToCart() => Ok();

    [HttpPost("pay")]
    public IActionResult Pay() => Ok();
}

// Infrastructure endpoints
[ApiController]
[Route("[controller]")]
public class InfraController : ControllerBase
{
    // Skip detection entirely
    [HttpGet("health")]
    [SkipBotDetection]
    public IActionResult Health() => Ok("ok");

    // Monitoring bots allowed
    [HttpGet("status")]
    [BlockBots(AllowMonitoringBots = true)]
    public IActionResult Status() => Ok(new { uptime = "99.9%" });
}
```

### Geografisk blockering av nätverk &

De arbetar både med MVC-Attribute och Minimal API-filter. De kräver GeoDetection-koordinatorn för signaldata

```csharp
// Block countries
[BlockBots(BlockCountries = "CN,RU,KP")]
public IActionResult SensitiveApi() => Ok();

// Country whitelist - only these allowed
[BlockBots(AllowCountries = "US,GB,DE,FR")]
public IActionResult DomesticOnly() => Ok();

// Block VPNs + proxies (anti-fraud)
[BlockBots(BlockVpn = true, BlockProxy = true)]
public IActionResult Payment() => Ok();

// Block datacenter IPs + Tor
[BlockBots(BlockDatacenter = true, BlockTor = true)]
public IActionResult FormSubmission() => Ok();

// Combine: SEO-friendly + geo block + VPN block
[BlockBots(AllowSearchEngines = true, BlockCountries = "CN,RU", BlockVpn = true)]
public IActionResult ProtectedContent() => Ok();
```

---


## Utöver blockering

Binärblock/ tillåten är enkel men begränsad . Aktionspolitik separat *vad du upptäcker* från *hur du reagerar*. Definiera reaktionsstrategier i konfigurationen

### appsettings.json

```json
{
  "BotDetection": {
    "BotThreshold": 0.7,
    "ActionPolicies": {
      "api-block": {
        "Type": "Block",
        "StatusCode": 403,
        "Message": "Bot traffic is not allowed."
      },
      "api-throttle": {
        "Type": "Throttle",
        "BaseDelayMs": 500,
        "MaxDelayMs": 5000,
        "ScaleByRisk": true,
        "JitterPercent": 0.3
      },
      "shadow-mode": {
        "Type": "LogOnly",
        "AddResponseHeaders": true,
        "LogFullEvidence": true
      }
    }
  }
}
```

### Spegla regler till slutpunkter

```csharp
// Bots get progressively slower responses (they don't know they're being throttled)
[BotPolicy("default", ActionPolicy = "api-throttle")]
public IActionResult Browse() => Ok();

// Hard block
[BotPolicy("default", ActionPolicy = "api-block")]
public IActionResult Confirm() => Ok();

// Shadow mode: log everything, block nothing (deploy first, tune later)
[BotPolicy("default", ActionPolicy = "shadow-mode")]
public IActionResult PublicApi() => Ok();
```

Fem policytyper: `Block` (HTTP  403), `Throttle` (tydliga fördröjningar `Challenge` (CAPTCHA `Redirect` ( `LogOnly` ( skuggan Modus ). Se den [handlingspolitiker](https://github.com/scottgal/LLMApi/blob/main/Mostlylucid.BotDetection/docs/action-policies.md) för hela referensen.

Skadormodiet är den empfohlena utgångspunkten. Inspeg av detektorn, titta på resultatenM SK2 ton tröskeln , *sedan* börja blockera.

---


## Vad du får gratis

Varje begäran efter `UseBotDetection()` har dessa förlängningar tillgängliga på `HttpContext`:

```csharp
// Am I talking to a bot?
context.IsBot()                    // true if probability >= threshold
context.IsHuman()                  // inverse
context.IsSearchEngineBot()        // Googlebot, Bingbot, etc.
context.IsVerifiedBot()            // DNS-verified bots
context.IsMaliciousBot()           // known bad actors

// How bad is it?
context.GetBotProbability()        // 0.0-1.0: likelihood of being a bot
context.GetDetectionConfidence()   // 0.0-1.0: how certain the system is
context.GetRiskBand()              // Low, Elevated, Medium, High
context.GetRecommendedAction()     // Allow, Challenge, Throttle, Block

// What is it?
context.GetBotType()               // BotType enum
context.GetBotName()               // "Googlebot", "Scrapy", etc.

// Full breakdown
var result = context.GetBotDetectionResult();
```

Två oberoende poäng spelar roll här. **bot sannolikhet** ( hur troligt är det att detta är en robot **detektionsförtroende** ( hur säker är systemet *mänsklig* ( låg sannolikhet , hög självförtroende M SK2 Eller så kan du se en misstänksam begäran men ha låg självförroende eftersom bara ett detektor fungerade

---


## Signal-baserade filtrering

Förutom bottyper, StyloBot visar 100+ skrivna signaler från dess detektorer . Du kan filtrera ändepunkter baserat på specifika signalvärden | - | för både Minimal API och MVC

### Minimala API

```csharp
// Block VPN traffic
app.MapPost("/api/payment", () => Results.Ok())
   .BlockIfSignal(SignalKeys.GeoIsVpn, SignalOperator.Equals, "True");

// Block datacenter IPs
app.MapPost("/api/submit", () => Results.Ok())
   .BlockIfSignal(SignalKeys.IpIsDatacenter, SignalOperator.Equals, "True");

// Only allow US traffic
app.MapGet("/api/domestic", () => Results.Ok())
   .RequireSignal(SignalKeys.GeoCountryCode, SignalOperator.Equals, "US");

// Block high-confidence bots by heuristic score
app.MapGet("/api/premium", () => Results.Ok())
   .BlockIfSignal(SignalKeys.HeuristicConfidence, SignalOperator.GreaterThan, "0.9");
```

### MVC

```csharp
[BlockIfSignal(SignalKeys.GeoIsVpn, SignalOperator.Equals, "True")]
public IActionResult Payment() => Ok();

[RequireSignal(SignalKeys.GeoCountryCode, SignalOperator.Equals, "US")]
public IActionResult DomesticOnly() => Ok();
```

### Att läsa inlinesignaler

```csharp
app.MapGet("/debug", (HttpContext ctx) =>
{
    var country = ctx.GetSignal<string>(SignalKeys.GeoCountryCode);
    var isVpn = ctx.GetSignal<bool>(SignalKeys.GeoIsVpn);
    var isDc = ctx.IsDatacenter();
    var heuristic = ctx.GetSignal<double>(SignalKeys.HeuristicConfidence);

    return Results.Ok(new { country, isVpn, isDc, heuristic });
});
```

Full signal reference: [signaler och anpassade filter](https://github.com/scottgal/LLMApi/blob/main/Mostlylucid.BotDetection/docs/signals-and-custom-filters.md).

---


## Att testa det

```bash
# Normal browser request → low bot score
curl -H "Accept: text/html" -H "Accept-Language: en-US" \
  -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0" \
  http://localhost:5090/

# Googlebot → allowed where AllowSearchEngines=true
curl -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
  http://localhost:5090/products

# Scraper → blocked by .BlockBots()
curl -A "Scrapy/2.7" http://localhost:5090/api/data

# Full detection breakdown → shows all signals and per-detector contributions
curl http://localhost:5090/bot-detection/check

# Simulate bot types via test mode header
curl -H "ml-bot-test-mode: malicious" http://localhost:5090/bot-detection/check
curl -H "ml-bot-test-mode: scraper" http://localhost:5090/api/data
```

Den `/bot-detection/check` Endpoint är din utvecklingsvän, .. Den återskapar varje signal från varje detektor. , Timing data , och per detektor så att du kan se exakt vad

---


## Hur det skalar: från file till full stack

Detta är designprincipen som betyder mest **varje nivå använder samma detektionskanal**. Du, ', skriver aldrig om ditt skyddskod igen.

### Tier 1: Själva - Bevarat | ( | Var du börjar |) |

```
Your App + AddBotDetection()
    └── SQLite (auto-created botdetection.db)
    └── In-process [HNSW](https://en.wikipedia.org/wiki/Hierarchical_navigable_small_world_graphs) similarity search
    └── 21 detectors, <1ms per request
    └── No external services
```

Alla 21 detektorer körs i en våg-baserad pipelineM SK2 snabba - banadetektorer | ( | UserAgent |, | Header ♫ , | IP | МSK7 | Behavior | , | TLS fingerprint | JSK9 | sätter igång parallellt i Wave ♫ ♫ Hjärisistiska uträkningsextrakter ♫ ~50 | egenskaper och kör en lätt scoring-modell ♫. | lärda mönster förblir kvar hos SQLite över hela början ♫

**Bra för:** Enkel app, <100K-ansökningarM SK2dag

### Tier 2: Lägg till Geodetection

Lägg till geo-riktning plus geo-koordinatorn:

```csharp
builder.Services.AddBotDetection();
builder.Services.AddGeoRoutingWithDataHub(); // free local GeoIP DB (no account)
builder.Services.AddGeoDetectionContributor(options =>
{
    options.FlagVpnIps = true;
    options.FlagHostingIps = true;
});
```

Om IP: s geografisk plats är ny: [GeoIP bakgrund](https://en.wikipedia.org/wiki/Geolocation_software#IP_address) och [DataHub GeoIP dataset](https://datahub.io/core/geoip2-ipv4) är bra utgångspunkter. DataHubCsv laddar ned en gratis ~27MB IP-databas i första sträckan och håller den uppdaterad omvecklingsmässigt [MaxMind GeoLite2](https://dev.maxmind.com/geoip/geolite2-free-geolocation-data/).

Nu får du 20+ geosignaler | | ( | land | , | VPN | МSK3 | proxy |, | Tor | , | datacenterdetektion | ) | och robotens ursprungskontroll |( | Googlebot från ett kinesiskt datacenter `BlockCountries`, `BlockVpn`, `BlockDatacenter`, `BlockTor` parametrar aktiveras.

### Niveau 3: PostgreSQL + TimescaleDB

Ersätta SQLite med PostgreSQL för multi-servers gemensamt lärande och lägga till [TimescaleDB](https://docs.timescale.com/) (a PostgreSQL-extension för tid- seriedata ) för analytik

```csharp
builder.Services.AddBotDetection();
builder.Services.AddStyloBotDashboard();
builder.Services.AddStyloBotPostgreSQL(connectionString, options =>
{
    options.EnableTimescaleDB = true;
    options.RetentionDays = 90;
    options.CompressionAfter = TimeSpan.FromDays(7);
});
```

```yaml
# docker-compose.yml
services:
  timescaledb:
    image: timescale/timescaledb:latest-pg16
    environment:
      POSTGRES_DB: stylobot
      POSTGRES_USER: stylobot
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - timescale-data:/var/lib/postgresql/data

  app:
    build: .
    environment:
      ConnectionStrings__BotDetection: "Host=timescaledb;Database=stylobot;Username=stylobot;Password=${DB_PASSWORD}"
    depends_on:
      timescaledb:
        condition: service_healthy
```

TimescaleDB ger dig hypertable partitioning, automatiserad kompression | (90-95% | lagerförminning efter |7 | dagar | МSK3 | kontinuerliga aggregationer för sub |

**Bra för:** >100K begäran, / dag, M SK2 flera server, , behov av analytik-dashboard,.

### Tier 4: Full Stack | - | Gateway |+ | Qdrant | LLM

```
Internet → Caddy (TLS) → Stylobot Gateway ([YARP](https://microsoft.github.io/reverse-proxy/)) → Your App
                              │
                              ├── TimescaleDB (analytics, learning)
                              ├── [Qdrant](https://qdrant.tech/documentation/) (vector similarity search)
                              └── LLamaSharp CPU [LLM](https://en.wikipedia.org/wiki/Large_language_model) (bot classification)
```

Gatewayn är en enskild Dockercontainer (`scottgal/stylobot-gateway`) som driver detektion på alla trafiker och skickar ut resultat som HTTP-Header | . | Din app läser opskrifte **ingen SDK behövs, vilket språk som helst**. Om " utgångspunkt " är obekant , tänk på[omvänd proxy](https://en.wikipedia.org/wiki/Reverse_proxy) som sitter framför din app och tillhandahåller säkerhet

```yaml
services:
  gateway:
    image: scottgal/stylobot-gateway:latest
    environment:
      DEFAULT_UPSTREAM: "http://app:8080"
      StyloBotDashboard__PostgreSQL__ConnectionString: "Host=timescaledb;..."
      StyloBotDashboard__PostgreSQL__EnableTimescaleDB: true
      BotDetection__Qdrant__Enabled: true
      BotDetection__Qdrant__Endpoint: http://qdrant:6334
      BotDetection__Qdrant__EnableEmbeddings: true
      BotDetection__AiDetection__Provider: LlamaSharp
      BotDetection__AiDetection__LlamaSharp__ModelPath: "Qwen/Qwen2.5-0.5B-Instruct-GGUF/qwen2.5-0.5b-instruct-q4_k_m.gguf"

  app:
    build: .
    environment:
      BOTDETECTION_TRUST_UPSTREAM: true

  qdrant:
    image: qdrant/qdrant:latest

  timescaledb:
    image: timescale/timescaledb:latest-pg16

  caddy:
    image: caddy:latest
```

Din app litar på portalen

```csharp
// ASP.NET Core
builder.Services.Configure<BotDetectionOptions>(o => o.TrustUpstreamDetection = true);
```

Eller läsa opskrifte direkt på vilket språk som helst:

```python
# Python/Flask
@app.route('/api/data')
def api_data():
    if request.headers.get('X-Bot-Detected') == 'true':
        return jsonify(error='blocked'), 403
    return jsonify(data='sensitive')
```

```javascript
// Node.js/Express
app.get('/api/data', (req, res) => {
  if (req.headers['x-bot-detected'] === 'true') {
    return res.status(403).json({ error: 'blocked' });
  }
  res.json({ data: 'sensitive' });
});
```

**Koplar som portaal skickar ut:**

| Rubrik | exempel | | | Bemärkelse |
|--------|---------|---------|
| `X-Bot-Detected` | `true` | BotM SK1mänsklig klassificering |
| `X-Bot-Confidence` | `0.91` | Detektorförtroende  |
| `X-Bot-Detection-Probability` | `0.87` | Bot sannolikhet |
| `X-Bot-Type` | `Scraper` | Bot-kategori  |
| `X-Bot-Name` | `AhrefsBot` | Identifiserad robot |
| `X-Bot-Detection-RiskBand` | `High` | Riskklassificering  |

### Vad varje komponent lägger till

| Komponent ♫ | ♫ Vad det gör ♫
|-----------|-------------|-----------|
| **TimescaleDB** | tid - serieanalyser , komprimerad lagerinlagning M SK3 kontinuerliga agregater MSC4 behållarepolitiker МSK5 tillförlitlig för produktion
| **Qdrant** | Vektors likhetssökning - hittar robotar även när de roterar
| **LLamaSharp** | CPU
| **Caddy/Nginx** | TLS slutfördelning , statiska plier | | | Din existerande omvända proxy ||
| **Gateway** | Centraliserad detektion för multi-app- och icke--.-NET-backends.

### Välj din nivå

```
Starting out?
├── Single ASP.NET app → Tier 1 (two lines of code)
│   └── Need geo blocking? → Tier 2 (one more line)
│       └── Need analytics? → Tier 3 (add PostgreSQL)
└── Multiple apps or non-.NET? → Tier 4 (Gateway)
```

Att röra sig mellan våningar är en DI-registrationsförändring. ditt Endpoint-skyddskod - `[BlockBots]` attributes, den `.BlockBots()` filterar, den `context.IsBot()` kontrollerar - stannar exakt samma .

---


## Enterprise Hooks

De två "-" -linjerna är utgångspunkten.

### Response-Header för debugging

Aktivera detektionsголовer globalt så att du kan kontrollera beteendet utan att träffa diagnostiska slutpunkter:

```json
{
  "BotDetection": {
    "ResponseHeaders": {
      "Enabled": true,
      "HeaderPrefix": "X-Bot-",
      "IncludeConfidence": true,
      "IncludeDetectors": true,
      "IncludeProcessingTime": true,
      "SkipPaths": ["/health"]
    }
  }
}
```

Varje respons får `X-Bot-Detected`, `X-Bot-Confidence`, `X-Bot-Processing-Ms`, etc .användbar för gränssnittrutteringsbeslut i Caddy/NginxM SK3 och för avbugning i devMSC4 Deaktivera produktionen eller begränsa till tillförlitliga nätverk

### Utmanande regler (Friktion före blockering )

Don' blockerar inte på osäkerhet - utmaning iställetM SK2 StyloBot har fem byggda utmaningstyper

```json
{
  "BotDetection": {
    "ActionPolicies": {
      "challenge-on-uncertain": {
        "Type": "Challenge",
        "ChallengeType": "JavaScript"
      },
      "captcha-gate": {
        "Type": "Challenge",
        "ChallengeType": "Captcha",
        "RedirectUrl": "/captcha"
      },
      "proof-of-work": {
        "Type": "Challenge",
        "ChallengeType": "ProofOfWork"
      }
    }
  }
}
```

Utmanande typer: `Redirect` ( skicka till utmanande sidan `Inline` (HTML interstitiell), `JavaScript` (JS-tegenskap-av-arbetarM SK3 `Captcha`, `ProofOfWork` (komputationsutmaningM SK1 Spegla till slutpunkter via `[BotPolicy]`:

```csharp
[BotPolicy("default", ActionPolicy = "challenge-on-uncertain")]
public IActionResult Submit() => Ok();
```

### IP tillåter/Neg listor

Globala tillåtna och förneka listor för kända IPs och [CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) intervall:

```json
{
  "BotDetection": {
    "WhitelistedIps": ["203.0.113.10/32", "198.51.100.0/24"],
    "BlacklistedIps": ["1.2.3.4", "5.6.7.0/24"]
  }
}
```

Vallisterade IPs hoppar över att upptäcka helt. svartlistade IPs blir blockerade omedelbart . Båda stödjer CIDR-notationen

### OpenTelemetry-mätrik

StyloBot visar ut mätvärden via `System.Diagnostics.Metrics`, kompatibel med [OpenTelemetry](https://opentelemetry.io/docs/), [Prometheus](https://prometheus.io/docs/introduction/overview/), [Grafana](https://grafana.com/docs/), och alla .NET-mätrik konsumenter

```csharp
builder.Services.AddOpenTelemetry()
    .WithMetrics(metrics => metrics.AddMeter("Mostlylucid.BotDetection"));
```

**Available metrics:**

| Metrik | Typ | Vad det mäter |
|--------|------|-----------------|
| `botdetection.requests.total` | räknar | Gesamtansökningar processerade |
| `botdetection.bots.detected` | Beräkningar | Benomningar som är klassificerade som robotar | |
| `botdetection.humans.detected` | Beräkningar | Människoklassificerade begäran |
| `botdetection.errors.total` | mätare | Detektor av leitungsfehler |
| `botdetection.detection.duration` | Histogram | Upplevnad i detektorn ♫ ♫ ( ♫ ms ♫
| `botdetection.confidence.average` | Gauge | | | Rolling Average confidence ||
| `botdetection.cache.patterns.count` | Gauge | Cached pattern count

Det här är siffrorna du behöver för brädseln, varning , och kapacitetsplaneringM SK2 Detektorns latens-histogram låter dig sätta upp SLOs. BotMSC4 mänskliga mätare ger dig trafikkomposition över tid

### Route Group Defaults

Applicera robotskydd på hela maršrutgrupper istället för att upprepa per-endpointM SK1

```csharp
// All /api routes: block bots, allow search engines
var api = app.MapGroup("/api").WithBotProtection(allowSearchEngines: true);
api.MapGet("/products", () => "data");
api.MapGet("/categories", () => "cats");

// Secured routes: humans only
var secure = app.MapGroup("/secure").WithHumanOnly();
secure.MapPost("/submit", () => "ok");
secure.MapPost("/checkout", () => "done");

// Individual endpoints can still override
api.MapGet("/special", () => "overridden")
   .BlockBots(allowSearchEngines: true, allowSocialMediaBots: true);
```

`WithBotProtection()` tar samma geo/nätverk/förtroende parametrar som `.BlockBots()`, men avsiktligt blockerar alltid scraper och ondskefulla robotar på gruppnivå. `allowScrapers` / `allowMaliciousBots` om grupper). `WithHumanOnly()` är gruppens ekvivalent till `.RequireHuman()`.

### Namerade regler på Minimala API

Använda `.BotPolicy()` att anse namnda handlingspolicyr till Minimal API slutpunkter - samma sak `[BotPolicy]` gör för MVC:

```csharp
// Throttle bots on this endpoint
app.MapGet("/api/data", () => "sensitive")
   .BotPolicy("default", actionPolicy: "api-throttle");

// Block with high-confidence threshold
app.MapPost("/api/submit", () => "ok")
   .BotPolicy("strict", actionPolicy: "block", blockThreshold: 0.8);
```

### Feedback API

rapportera falska positiva och negativa tillbaka till systemet via `POST /bot-detection/feedback`:

```bash
# Mark a detection as a false positive (bot detected but was actually human)
curl -X POST http://localhost:5090/bot-detection/feedback \
  -H "Content-Type: application/json" \
  -d '{"outcome": "Human", "notes": "Known partner integration"}'

# Mark a missed bot (human detected but was actually a bot)
curl -X POST http://localhost:5090/bot-detection/feedback \
  -H "Content-Type: application/json" \
  -d '{"outcome": "Bot", "notes": "Automated scraper spotted in logs"}'
```

Slutpunkten returnerar om återkopplingen representerar ett falskt positivt eller falskt negativt förhållande till det nuvarande upptäcktsresultatet

### Gateway Trust Boundary med HMAC-signatur

När du använder YARP-portaalet, litar din baksida på uppströmsdetektionsspetsar

**Grund tro (nätverk -utrymme isolering bara):**

```json
{
  "BotDetection": {
    "TrustUpstreamDetection": true
  }
}
```

**HMAC-signerad tillit (kryptografisk verifiering**

```json
{
  "BotDetection": {
    "TrustUpstreamDetection": true,
    "UpstreamSignatureHeader": "X-Bot-Signature",
    "UpstreamSignatureSecret": "base64-encoded-shared-secret"
  }
}
```

När `UpstreamSignatureHeader` och `UpstreamSignatureSecret` är ställda, och mellanvaran ser [HMAC-SHA256](https://datatracker.ietf.org/doc/html/rfc2104) handtekening innan man litar på uppströms opskrifte.

Använd det här för **custom gateway/proxy integrationer** som lägger ut signering-header. Den byggda - i Stylobot-portaalen förflyttar roboten framåt M SK2 spårning-headers , men emiterar inte än HMAC-signatur-headering

Benötiga signerade opskrifte:

- `X-Bot-Signature` (bas, 64, HMAC, M SK2
- `X-Bot-Detection-Timestamp` (Unix-epok sekunder , UTCM SK2

Att underteckna kontrakt

- `payload = X-Bot-Detected + ":" + X-Bot-Confidence + ":" + X-Bot-Detection-Timestamp`
- `signature = Base64(HMACSHA256(payload, base64Decoded(UpstreamSignatureSecret)))`

Signaturer utanför ett 5-minuter återspelningsfenster avfärdas . Om undertecknet saknas, ofullständigtM SK3 eller är utgångsdatumsMSC4 uppströmsheader avfärdades och full lokal detektion körs istället

**viktigt:** Aktivera enbart tillit när din baksida ligger bakom en tillitlig omvänd proxy. Om en attacker kan nå din baksidan direkt `X-Bot-Detected: false` och kringgå alla upptäckter. I produktionenM SK1

- Var säkra på att backend inte är allmänt tillgänglig. (Docker-intern nätverk , Kubernetes ClusterIP)
- Stripp `X-Bot-*` opskrifte vid din gräns proxy innan de når portaalet
- Använd HMAC-signatur för bevakning

---


## Vad StyloBot inte är

Vålig att vara uppenbart:

- **Inte en WAF.** StyloBot inte inspekterar payloader för SQL-injiction eller XSS. Det identifierar *som* gör begäran, inte *vad* de' skickar . Använd den tillsammans med en WAF
- **Inte en CAPTCHA gård.** Utmaningspolitiker finns, men designfilosofin är det detekterande, det första, det andra. Målet är att veta vad du har att göra med *före* beslutande om att ifrågasätta
- **Inte perimeter- endastM SK1** Detektorn kör per- slutpunkt med per - slutpunktens policyr `/products` tillåt sökmotorer medan `/api/checkout` kräver människor. Detta är slutpunkters semantik , inte firewall-regler
- **Inte moln** Allt körs själv.
- **Osäkerhet** Två oberoende poäng ( sannolikhet + självförtroende ) betyder att du kan skilja " antagligen en robot M, vi | ' | är säkra på ♫ " | från ♫ " | antagligt en robot

---


## Vad' är nästa

Del 1 visade varför botdetektorn spelar roll . Del ♫ 2 ♫ visade detektorleitungsinternen ♫

**Ta igång:**

- NuGet: `dotnet add package Mostlylucid.BotDetection`
- Gateway Docker: `docker pull scottgal/stylobot-gateway`
- [Hela dokument](https://github.com/scottgal/LLMApi/tree/main/Mostlylucid.BotDetection/docs)
- [Live demo: StyloBot.net](https://stylobot.net)