Satelit Shield
Oprește boții și scraperele, nu oamenii
Shield recunoaște automatizarea, browserele antidetect și scraperele, în pagină și pe server; un om vede cel mult o verificare care trece singură în circa o secundă.
Primele 7 zile sunt de probă, cu 100 000 de verificări.
Se verifică browserul
Senzorul Shield rulează în această pagină, ca pe site-ul unui client.
Browser realscor …/100
Niciun semn de automatizare sau de amprentă falsă. Pe un site protejat, paginile se deschid ca de obicei.
Câteva semne de riscscor …/100
Semne slabe, nu sigure. Pe un site protejat ai vedea cel mult verificarea care trece singură.
Automatizare găsităscor …/100
Semne sigure de automatizare sau de mascare. Pe un site protejat, accesul ar fi oprit.
Crawler de căutarescor …/100
Un crawler declarat. Cei verificați, ca Google și Bing, nu sunt opriți niciodată.
Browserul a trecut
Shield nu a cerut nicio verificare pentru acest browser.
Testul nu a răspuns
Un blocant de conținut sau o rețea lentă a oprit scriptul. Prin proxy first-party, el vine de pe domeniul tău.
Ce a văzut senzorul
Semnele apar după primul raport al senzorului.
Sunt ID-urile verificărilor, așa cum le trimite senzorul. Sensul fiecăruia este în panoul Shield.
Același script pe care îl pui pe site. Trimite doar ID-uri de verificări, fără poziții, taste sau text.
- Verificarea trece singură în circa o secundă. Omul nu apasă nimic.
- Întâi observare: vezi ce ar opri Shield, apoi pornești protecția.
- Crawlerele de căutare verificate nu sunt atinse niciodată.
Ce oprește
Automatizare, amprente false, scrapere și abuz
Fiecare card spune ce caută Shield și regulile care decid.
-
Automatizare de browser
Selenium, Puppeteer, Playwright, Cypress, TestCafe și Chrome headless, recunoscute după urmele pe care le lasă în pagină.
automation -
Pluginuri stealth și build-uri „undetected”
Automatizarea peticită ca să pară om. Shield caută chiar peticele: funcții înlocuite, ferestre detașate, un Chromium care se dă drept Chrome.
stealth -
Browsere antidetect
Amprente falsificate. Shield compară ce declară browserul cu ce face motorul lui: ecranul, fusul orar, limba, fonturile, desenul pe canvas.
antidetectbrowser-soft -
Scrapere HTML
Programele care cer pagini fără să le ruleze: niciun raport al senzorului, prea multe pagini, prea repede.
no-proofratewalk -
Googlebot fals
Un nume de crawler e crezut doar dacă lista IP oficială și DNS-ul invers îl confirmă. Crawlerele verificate trec mereu.
fake-crawlerrobotstrap -
Flote de adrese și centre de date
Browsere din rețele de hosting, User-Agent-uri care mint, antete care nu se potrivesc. IPv6 se numără pe rețeaua /64.
datacenterua-claimclient-hintsstale-browser -
Voturi, comentarii și înregistrări false
Formularul trimite un token al senzorului, iar serverul tău îl verifică o singură dată, în 300 de secunde. Verificat cu adresa vizitatorului, un token copiat pe altă adresă este refuzat.
POST /verify{ "success": true, "verdict": "human", "score": 3, "action": "allow", "age_s": 4 }
Cum funcționează
Două straturi, o singură decizie
Senzorul vede browserul, serverul tău vede cererile. Shield le adună pentru fiecare adresă și decide o dată.
-
În pagină
Senzorul
- Un script ES5 pe paginile tale, încărcat async: nu oprește afișarea paginii.
- Trimite doar ID-urile verificărilor: fără poziții, taste, text sau hash de amprentă.
- Rezolvă pagina de verificare: o dovadă de lucru de 14 biți.
- Păstrează permisul 12 ore, într-un cookie pe domeniul tău.
-
Pe server
Cererile
- Serverul sau edge-ul tău spune ce cereri vin: una câte una la
/assess, în loturi la/ingest. - Shield numără pe adresă: IPv4, sau rețeaua /64 la IPv6.
- Un nume de crawler este verificat la lista IP oficială și prin DNS invers.
- Antetele Sec-Fetch, Client Hints și User-Agent trebuie să spună același lucru.
- Serverul sau edge-ul tău spune ce cereri vin: una câte una la
Trei rezultate posibile
- 200 Trece Oamenii și crawlerele verificate. Nimic nu se schimbă.
- 429 Verificare de o secundă Semne slabe: o pagină care trece singură. Omul nu apasă nimic.
- 403 Oprit Semne sigure: 24 de ore, apoi 7 zile, apoi 30 de zile la o repetare în 90 de zile.
Întâi observare, apoi protecție
Fiecare regulă are un mod: off, shadow (observare: Shield doar notează ce ar face) sau enforce (protecție). Un site nou pornește cu toate regulile în observare; le treci pe protecție una câte una.
Crawlerele verificate trec mereu
Google, Bing, Apple, Yandex, DuckDuckGo, Baidu, OpenAI, Perplexity, Anthropic și altele: nicio decizie, niciodată. La fel lista ta de permise.
Instalare
Trei pași, primul e o linie
Cheia site-ului (shp_…) e publică și stă în pagină. Secretul (shs_…) stă doar pe server; îl vezi o singură dată.
-
Pune senzorul pe pagini
Direct, o linie în pagină. Recomandat: prin proxy first-party, de pe domeniul tău. Nicio cerere către terți, merge sub
script-src 'self', iar blocantele de reclame nu îl văd.<!-- in every page, direct --> <script src="https://api.satelit.md/shield/v1/sensor.js" data-site="shp_XXXXXXXXXXXXXXXXXXXXXXXX" async></script># Caddyfile: /_sh/* goes to Shield, with your secret and the visitor's address example.md { handle_path /_sh/* { rewrite * /shield/v1{uri} reverse_proxy https://api.satelit.md { header_up Host {upstream_hostport} header_up X-Shield-Secret {env.SHIELD_SECRET} header_up X-Shield-Client-IP {client_ip} header_up -Cookie header_up -Authorization } } # ... the rest of your site } # in every page: # <script src="/_sh/sensor.js" data-site="shp_XXXXXXXXXXXXXXXXXXXXXXXX" data-base="/_sh" async></script># nginx: /_sh/ goes to Shield, with your secret and the visitor's address location /_sh/ { proxy_pass https://api.satelit.md/shield/v1/; proxy_ssl_server_name on; proxy_set_header Host api.satelit.md; proxy_set_header X-Shield-Secret "shs_..."; # keep this file out of your repository proxy_set_header X-Shield-Client-IP $remote_addr; # behind Cloudflare: $http_cf_connecting_ip proxy_set_header Cookie ""; proxy_set_header Authorization ""; } # in every page: # <script src="/_sh/sensor.js" data-site="shp_XXXXXXXXXXXXXXXXXXXXXXXX" data-base="/_sh" async></script> -
Verifică tokenul la formulare
La un vot, un comentariu sau o înregistrare, pagina cere un token cu
SatelitShield.token()și îl trimite cu formularul. Serverul tău îl verifică o singură dată, în 300 de secunde.// a fresh token goes with the form, in a hidden field form.addEventListener("submit", function (e) { e.preventDefault(); SatelitShield.token(function (token) { form.elements.shield_token.value = token; form.submit(); }); });curl https://api.satelit.md/shield/v1/verify \ -H "Authorization: Bearer $SHIELD_SECRET" \ -H "Content-Type: application/json" \ -d '{ "token": "<the token from the form>", "ip": "203.0.113.9" }'// Node 18+: the token came with the form, ip is the visitor's address async function fromPerson(token, ip) { const res = await fetch("https://api.satelit.md/shield/v1/verify", { method: "POST", headers: { Authorization: `Bearer ${process.env.SHIELD_SECRET}`, "Content-Type": "application/json" }, body: JSON.stringify({ token, ip }), }); const v = await res.json(); return v.success === true && v.action !== "block"; }import json, os, urllib.request def from_person(token, ip): req = urllib.request.Request( "https://api.satelit.md/shield/v1/verify", data=json.dumps({"token": token, "ip": ip}).encode(), headers={"Authorization": f"Bearer {os.environ['SHIELD_SECRET']}", "Content-Type": "application/json"}, ) with urllib.request.urlopen(req, timeout=5) as res: v = json.load(res) return v.get("success") is True and v.get("action") != "block"<?php function from_person(string $token, string $ip): bool { $ch = curl_init("https://api.satelit.md/shield/v1/verify"); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_TIMEOUT => 5, CURLOPT_HTTPHEADER => ["Authorization: Bearer " . getenv("SHIELD_SECRET"), "Content-Type: application/json"], CURLOPT_POSTFIELDS => json_encode(["token" => $token, "ip" => $ip]), ]); $v = json_decode(curl_exec($ch), true); curl_close($ch); return ($v["success"] ?? false) === true && ($v["action"] ?? "") !== "block"; } -
Pune decizia în server
Opțional, pentru tot site-ul. Un middleware ține deciziile în memorie, le citește din
/decisionso dată la 15–30 de secunde și trimite cererile în loturi la/ingest. Nicio cerere a unui vizitator nu așteaptă rețeaua.// Satelit Shield in a Node server: Express or any (req, res, next) stack. Node 18+, no packages. // The decisions stay in memory and are read again every 20 s, so a visitor's request never waits for the network. // Every request is sent to /ingest in batches. /_sh/ (the sensor) is served by the proxy in front, step 1. import { clientKey, passValid } from "./shield-pass.mjs"; const API = process.env.SHIELD_API || "https://api.satelit.md/shield/v1"; const SECRET = process.env.SHIELD_SECRET; // shs_..., never in a page const SITE = process.env.SHIELD_SITE; // shp_..., the public site key const HEADERS = { Authorization: `Bearer ${SECRET}`, "Content-Type": "application/json" }; const decisions = new Map(); // client key -> { a: "b" | "g", rule, until } const lines = []; let cursor = "0"; export async function poll() { const res = await fetch(`${API}/decisions?since=${cursor}`, { headers: HEADERS }); if (!res.ok) return; const body = await res.json(); if (body.full) decisions.clear(); for (const d of body.items) { if (d.a === "-") decisions.delete(d.key); else decisions.set(d.key, d); } cursor = body.cursor; } export async function flush() { while (lines.length) { const batch = lines.splice(0, 500); await fetch(`${API}/ingest`, { method: "POST", headers: HEADERS, body: JSON.stringify({ lines: batch }) }).catch(() => {}); } } export function start() { const quiet = (job) => () => job().catch(() => {}); quiet(poll)(); setInterval(quiet(poll), 20_000).unref(); setInterval(quiet(flush), 5_000).unref(); } const cookie = (req, name) => new RegExp(`(?:^|;\\s*)${name}=([^;]*)`).exec(req.headers.cookie ?? "")?.[1] ?? ""; const page = (mode, text) => `<!doctype html><html data-shield="${mode}"><head><meta charset="utf-8">` + `<meta content="noindex" name="robots"><meta name="viewport" content="width=device-width">` + `<script src="/_sh/sensor.js" data-site="${SITE}" data-base="/_sh" async></script></head><body><p>${text}</p></body></html>`; export function shield(req, res, next) { const ip = req.ip ?? req.socket.remoteAddress; // behind a proxy: Express's "trust proxy" gives the visitor's address const ua = req.headers["user-agent"] ?? ""; const path = (req.originalUrl ?? req.url).split("?")[0]; const shp = cookie(req, "__shp"); const pass = !shp ? 0 : passValid(shp, SECRET, ip, ua) ? 1 : 2; const d = decisions.get(clientKey(ip)); const on = d && (!d.until || Date.parse(d.until) > Date.now()) ? d.a : ""; // a ban is a 403; a check is a 429 unless the browser holds a valid pass (a pass never opens a ban) const gate = on === "b" ? 403 : on === "g" && pass !== 1 ? 429 : 0; res.on("finish", () => { const type = String(res.getHeader("content-type") ?? ""); const kind = /\.(css|js|mjs|png|jpe?g|gif|svg|webp|avif|ico|woff2?)$/i.test(path) ? "asset" : /json/.test(type) ? "api" : "html"; const h = (name) => req.headers[name] ?? ""; lines.push({ t: Date.now(), ip, ua, m: req.method, p: path, s: res.statusCode, k: kind, h: { sfs: h("sec-fetch-site"), chua: h("sec-ch-ua"), chm: h("sec-ch-ua-mobile"), chp: h("sec-ch-ua-platform"), al: h("accept-language"), ref: h("referer") }, pass, seen: cookie(req, "__shs") === "1" ? 1 : 0, g: gate === 429 ? 1 : 0, }); }); if (!gate) return next(); res.statusCode = gate; res.setHeader("Content-Type", "text/html; charset=utf-8"); res.setHeader("Cache-Control", "no-store"); res.end(gate === 429 ? page("check", "Checking your browser.") : page("ban", "Access blocked.")); }// Satelit Shield: check a pass (the __shp cookie) on your own server, with no call to Shield. Node 18+. // A pass is p1.{exp}.{token}.{sig}; sig is the first 22 characters of // base64url(HMAC-SHA256(pass key, "p1|{exp}|{token}|{client key}|{User-Agent}")). import { createHash, createHmac, timingSafeEqual } from "node:crypto"; // The pass key: HMAC-SHA256 with the key sha256_hex(secret) over "satelit-shield-pass-v1", in hex. export function passKey(secret) { const key = createHash("sha256").update(secret).digest("hex"); return createHmac("sha256", key).update("satelit-shield-pass-v1").digest("hex"); } // The client key: an IPv4 address as it is, an IPv6 address as its /64 (the first four groups and "::"). export function clientKey(ip) { const v4 = /^(?:::ffff:)?(\d{1,3}(?:\.\d{1,3}){3})$/i.exec(ip); if (v4) return v4[1]; const [head, tail = ""] = ip.toLowerCase().split("%")[0].split("::"); const a = head ? head.split(":") : []; const b = tail ? tail.split(":") : []; const groups = [...a, ...Array(Math.max(0, 8 - a.length - b.length)).fill("0"), ...b]; return groups.slice(0, 4).map((g) => parseInt(g, 16).toString(16)).join(":") + "::"; } // True when the pass has not expired and was signed for this address and this browser. export function passValid(pass, secret, ip, userAgent, now = Date.now() / 1000) { const m = /^p1\.(\d+)\.([0-9a-f]{16})\.([A-Za-z0-9_-]{22})$/.exec(pass ?? ""); if (!m || Number(m[1]) <= now) return false; const message = `p1|${m[1]}|${m[2]}|${clientKey(ip)}|${userAgent}`; const sig = createHmac("sha256", passKey(secret)).update(message).digest("base64url").slice(0, 22); return timingSafeEqual(Buffer.from(sig), Buffer.from(m[3])); }
Reguli
15 reguli, fiecare cu modul ei
Regulile dure opresc o adresă neprotejată. Cele slabe arată doar verificarea. O regulă care trece de 50 de opriri pe oră, sau un site care trece de 200, revine singură la observare, iar tu primești un eveniment.
-
automationWebDriver, ChromeDriver, Selenium, PhantomJS, Nightmare, Playwright, Puppeteer, Cypress, TestCafe, HeadlessChrome.
-
stealthAutomatizare peticită: Function.toString înlocuit, fereastră din iframe detașat, webdriver redefinit, Chromium deghizat în Chrome, un worker care spune HeadlessChrome.
-
antidetectAmprentă falsificată: motor JS mai vechi decât browserul declarat, zgomot pe canvas, ecran diferit de CSS, fus orar, limbă, fonturi de sistem lipsă, worker sau Client Hints în dezacord.
-
fake-crawlerUn nume de crawler infirmat de două surse independente: lista IP oficială și DNS-ul invers.
-
robotsUn bot declarat care cere căi interzise grupului său din robots.txt.
-
trapCalea-capcană ascunsă a site-ului, interzisă în robots.txt.
Încă 9 reguli
-
challenge-ignoredPagina de verificare servită de 6 sau mai multe ori aceleiași adrese, fără răspuns.
-
browser-softDouă sau mai multe semne slabe: fără pluginuri pe Chrome desktop, fără window.chrome, limbi goale, WebGL software, protocolul DevTools.
-
no-proof12 sau mai multe pagini în 10 minute, fără raport al senzorului și fără cookie-ul __shs.
-
rate60 sau mai multe pagini pe minut.
-
walk40 sau mai multe pagini diferite în 10 minute.
-
stale-browserChrome desktop cu 8 sau mai multe versiuni în urmă, fără permis și fără __shs.
-
ua-claimChrome 101+ cu numărul complet de build (Chrome real scrie N.0.0.0) sau fără Sec-Fetch-Site pe Chrome 80+.
-
client-hintsAntetele Sec-CH-UA contrazic User-Agent-ul: mobil, platformă, versiune, sau lipsesc pe Chrome 90+.
-
datacenterUn User-Agent de browser dintr-o rețea de hosting sau cloud (ASN), fără permis.
- Nu sunt judecați niciodată
- Crawlerele verificate și lista ta de permise.
- Doar verificare, niciodată oprire
- Ieșirile Tor, adresele comune (3 sau mai multe browsere reale pe aceeași adresă în 24 de ore) și adresele în care ai încredere.
Confidențialitate
ID-uri, nu amprente
Shield vede cât îi trebuie ca să deosebească un browser de un program. Nimic în plus.
- Doar ID-uri de verificări. Senzorul trimite ID-urile verificărilor, numărul de interacțiuni (fără poziții sau taste) și prima limbă a browserului. Niciun hash de amprentă.
- Cookie-uri doar pe domeniul tău.
__shp, permisul după o verificare, și__shs, semnul că browserul a rulat senzorul. Satelit nu pune niciun cookie al său. - Păstrare scurtă. Cheia clientului (adresa sau rețeaua /64), User-Agent-ul, regula și dovada ei: 30 de zile. Contoarele pe oră: 90 de zile.
- Secretul rămâne pe server. Cheia site-ului e publică. Secretul îl vezi o singură dată, iar Satelit păstrează doar hash-ul lui.
Prețuri
Plătești verificările, nu traficul
O verificare este un raport al senzorului sau un apel /assess. Liniile trimise la /ingest sunt gratuite, până la 10 pentru fiecare verificare.
-
Shield Start
Un site: un magazin, un blog, o redacție mică.
19 € / lună
381,72 lei
- Site-uri
- 1
- Verificări pe lună
- 250 000
-
Shield Pro
RecomandatCâteva site-uri cu formulare, voturi sau conturi.
79 € / lună
1 587,15 lei
- Site-uri
- 5
- Verificări pe lună
- 2 500 000
-
Shield Business
Rețele de site-uri și platforme cu trafic mare.
249 € / lună
5 002,53 lei
- Site-uri
- 25
- Verificări pe lună
- 15 000 000
-
Enterprise
Volume mari, condiții și facturare prin contract.
de la 990 € / lună
de la 19 889,59 lei
- Site-uri
- prin contract
- Verificări pe lună
- de la 50 000 000
Fiecare site nou are 7 zile de probă, cu 100 000 de verificări. Lei la cursul BNM de 2 noiembrie 2026: 1 euro = 20,0905 lei.
Întrebări despre Shield
Strică Shield poziția în Google?
Nu. Crawlerele verificate (Google, Bing, Apple, Yandex, DuckDuckGo, Baidu, OpenAI, Perplexity, Anthropic și altele) nu primesc nicio decizie: numele lor e confirmat de lista IP oficială și de DNS-ul invers. Senzorul se încarcă async și nu oprește afișarea paginii.
Merge împreună cu Cloudflare?
Da. Shield nu ține locul regulilor Cloudflare, adaugă stratul care vede browserul. Dacă site-ul e după Cloudflare, proxy-ul tău trimite adresa din CF-Connecting-IP în X-Shield-Client-IP, ca Shield să judece vizitatorul, nu Cloudflare.
Ce se întâmplă cu un om confundat cu un bot?
Semnele slabe arată doar verificarea, care trece singură în circa o secundă. Ieșirile Tor, adresele comune și adresele în care ai încredere nu sunt oprite niciodată. O regulă cu prea multe opriri într-o oră revine singură la observare, iar orice decizie o poți ridica din panou.
Cum pornesc fără risc?
Un site nou pornește cu toate regulile în observare: Shield doar notează ce ar opri. Citești evenimentele în panou și treci pe protecție regulile în care ai încredere, una câte una.
Încetinește site-ul?
Senzorul se încarcă async, după pagină. Un middleware ține deciziile în memorie și le citește o dată la 15–30 de secunde, așa că o cerere nu așteaptă rețeaua. Doar /assess, dacă îl folosești, este un apel pe cerere.
Ce date colectează Shield?
ID-urile verificărilor, numărul de interacțiuni fără poziții sau taste și prima limbă a browserului. Shield păstrează cheia clientului, User-Agent-ul, regula și dovada ei 30 de zile, iar contoarele pe oră 90 de zile. Fără hash de amprentă și fără cookie-uri ale Satelit: le poți descrie exact în politica ta de confidențialitate.
Ce face Shield dacă scriptul e blocat?
Stratul de server lucrează și fără el: un client care cere multe pagini fără raport al senzorului primește verificarea. Prin proxy first-party, scriptul vine de pe domeniul tău și blocantele de reclame nu îl văd.
Cât durează o oprire?
24 de ore, apoi 7 zile, apoi 30 de zile, dacă adresa repetă în 90 de zile. Un permis valabil deschide o verificare, niciodată o oprire.
Vezi ce ar opri Shield pe site-ul tău
Un site nou pornește în observare: Shield doar notează. Pornești protecția când ești sigur, regulă cu regulă.