Satelit Shield
Зупиняйте ботів і парсери, а не людей
Shield розпізнає автоматизацію, антидетект-браузери й парсери, на сторінці й на сервері; людина бачить щонайбільше перевірку, яка проходить сама приблизно за секунду.
Перші 7 днів: пробний період, 100 000 перевірок.
Перевіряємо браузер
Сенсор Shield працює на цій сторінці, як на сайті клієнта.
Справжній браузербал …/100
Жодних ознак автоматизації чи підробленого відбитка. На захищеному сайті сторінки відкриваються як зазвичай.
Кілька ознак ризикубал …/100
Слабкі ознаки, не точні. На захищеному сайті ви побачили б щонайбільше перевірку, яка проходить сама.
Знайдено автоматизаціюбал …/100
Точні ознаки автоматизації або маскування. На захищеному сайті доступ було б зупинено.
Пошуковий роботбал …/100
Заявлений робот. Перевірених, як-от Google і Bing, не зупиняють ніколи.
Браузер пройшов
Shield не попросив від цього браузера жодної перевірки.
Тест не відповів
Блокувальник вмісту або повільна мережа зупинили скрипт. Через first-party проксі він іде з вашого домену.
Що побачив сенсор
Ознаки з'являться після першого звіту сенсора.
Це ID перевірок у тому вигляді, в якому їх надсилає сенсор. Що означає кожен, написано в панелі Shield.
Той самий скрипт, що ви ставите на сайт. Він надсилає лише ID перевірок: без координат, клавіш і тексту.
- Перевірка проходить сама приблизно за секунду. Людина нічого не натискає.
- Спершу спостереження: видно, що зупинив би Shield, потім вмикаєте захист.
- Перевірені пошукові роботи не зачіпаються ніколи.
Що зупиняє
Автоматизація, підроблені відбитки, парсери й зловживання
Кожна картка каже, що шукає Shield і які правила вирішують.
-
Автоматизація браузера
Selenium, Puppeteer, Playwright, Cypress, TestCafe і headless Chrome, впізнавані за слідами, які вони лишають на сторінці.
automation -
Stealth-плагіни та збірки «undetected»
Автоматизація, залатана, щоб здаватися людиною. Shield шукає самі латки: підмінені функції, від'єднані вікна, Chromium, що видає себе за Chrome.
stealth -
Антидетект-браузери
Підроблені відбитки. Shield порівнює те, що браузер заявляє, з тим, що робить його рушій: екран, часовий пояс, мову, шрифти, малюнок на canvas.
antidetectbrowser-soft -
HTML-парсери
Програми, що запитують сторінки, не виконуючи їх: жодного звіту сенсора, забагато сторінок, надто часто.
no-proofratewalk -
Підробний Googlebot
Імені робота вірять, лише коли його підтверджують офіційний список IP і зворотний DNS. Перевірені роботи проходять завжди.
fake-crawlerrobotstrap -
Пули адрес і дата-центри
Браузери з хостингових мереж, User-Agent, що бреше, заголовки, що не збігаються. IPv6 рахується за мережею /64.
datacenterua-claimclient-hintsstale-browser -
Фальшиві голоси, коментарі й реєстрації
Форма надсилає токен сенсора, а ваш сервер перевіряє його один раз, протягом 300 секунд. Під час перевірки з адресою відвідувача токен, скопійований на іншу адресу, відхиляється.
POST /verify{ "success": true, "verdict": "human", "score": 3, "action": "allow", "age_s": 4 }
Як це працює
Два шари, одне рішення
Сенсор бачить браузер, ваш сервер бачить запити. Shield зводить їх для кожної адреси й вирішує один раз.
-
На сторінці
Сенсор
- Один скрипт ES5 на ваших сторінках, завантажується async: не затримує показ сторінки.
- Надсилає лише ID перевірок: без координат, клавіш, тексту й хешу відбитка.
- Розв'язує сторінку перевірки: доказ роботи на 14 біт.
- Зберігає перепустку 12 годин, у cookie на вашому домені.
-
На сервері
Запити
- Ваш сервер або edge повідомляє, які запити надходять: по одному в
/assess, пакетами в/ingest. - Shield рахує за адресою: IPv4 або мережа /64 для IPv6.
- Ім'я робота перевіряється за офіційним списком IP і через зворотний DNS.
- Заголовки Sec-Fetch, Client Hints і User-Agent мають казати одне й те саме.
- Ваш сервер або edge повідомляє, які запити надходять: по одному в
Три можливі результати
- 200 Проходить Люди й перевірені роботи. Нічого не змінюється.
- 429 Перевірка на секунду Слабкі ознаки: сторінка, що проходить сама. Людина нічого не натискає.
- 403 Зупинено Точні ознаки: 24 години, потім 7 днів, потім 30 днів при повторі протягом 90 днів.
Спершу спостереження, потім захист
Кожне правило має режим: off, shadow (спостереження: Shield лише відзначає, що зробив би) або enforce (захист). Новий сайт починає з усіма правилами в спостереженні; ви переводите їх у захист по одному.
Перевірені роботи проходять завжди
Google, Bing, Apple, Yandex, DuckDuckGo, Baidu, OpenAI, Perplexity, Anthropic та інші: жодних рішень, ніколи. Так само ваш список дозволених.
Встановлення
Три кроки, перший в один рядок
Ключ сайту (shp_…) публічний і стоїть на сторінці. Секрет (shs_…) зберігається лише на сервері; ви бачите його один раз.
-
Поставте сенсор на сторінки
Напряму: один рядок на сторінці. Радимо через first-party проксі, з вашого домену. Жодних запитів до третіх сторін, працює при
script-src 'self', а блокувальники реклами його не бачать.<!-- 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> -
Перевіряйте токен у формах
Під час голосування, коментаря чи реєстрації сторінка бере токен через
SatelitShield.token()і надсилає його з формою. Ваш сервер перевіряє його один раз, протягом 300 секунд.// 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"; } -
Перенесіть рішення на сервер
За бажанням, для всього сайту. Middleware тримає рішення в пам'яті, читає їх з
/decisionsраз на 15–30 секунд і надсилає запити пакетами в/ingest. Жоден запит відвідувача не чекає на мережу.// 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])); }
Правила
15 правил, у кожного свій режим
Жорсткі правила зупиняють незахищену адресу. М'які лише показують перевірку. Правило, що перевищило 50 зупинок на годину, або сайт, що перевищив 200, саме повертається до спостереження, а ви отримуєте подію.
-
automationWebDriver, ChromeDriver, Selenium, PhantomJS, Nightmare, Playwright, Puppeteer, Cypress, TestCafe, HeadlessChrome.
-
stealthЗалатана автоматизація: підмінений Function.toString, вікно з від'єднаного iframe, перевизначений webdriver, Chromium під виглядом Chrome, worker, що називає себе HeadlessChrome.
-
antidetectПідроблений відбиток: рушій JS старший за заявлений браузер, шум на canvas, екран не збігається з CSS, часовий пояс, мова, немає системних шрифтів, worker або Client Hints суперечать.
-
fake-crawlerІм'я робота, спростоване двома незалежними джерелами: офіційним списком IP і зворотним DNS.
-
robotsЗаявлений бот, що запитує шляхи, заборонені його групі в robots.txt.
-
trapПрихований шлях-пастка сайту, заборонений у robots.txt.
Ще 9 правил
-
challenge-ignoredСторінку перевірки показано одній адресі 6 і більше разів без відповіді.
-
browser-softДві й більше слабких ознак: немає плагінів у десктопному Chrome, немає window.chrome, порожні мови, програмний WebGL, протокол DevTools.
-
no-proof12 і більше сторінок за 10 хвилин без звіту сенсора й без cookie __shs.
-
rate60 і більше сторінок за хвилину.
-
walk40 і більше різних сторінок за 10 хвилин.
-
stale-browserДесктопний Chrome, старший на 8 і більше версій, без перепустки й без __shs.
-
ua-claimChrome 101+ з повним номером збірки (справжній Chrome пише N.0.0.0) або без Sec-Fetch-Site у Chrome 80+.
-
client-hintsЗаголовки Sec-CH-UA суперечать User-Agent: мобільний, платформа, версія, або їх немає в Chrome 90+.
-
datacenterБраузерний User-Agent з хостингової чи хмарної мережі (ASN), без перепустки.
- Ніколи не оцінюються
- Перевірені роботи й ваш список дозволених.
- Лише перевірка, ніколи не зупинка
- Виходи Tor, спільні адреси (3 і більше справжніх браузерів на одній адресі за 24 години) та адреси, яким ви довіряєте.
Конфіденційність
ID, а не відбитки
Shield бачить рівно стільки, скільки потрібно, щоб відрізнити браузер від програми. Нічого зайвого.
- Лише ID перевірок. Сенсор надсилає ID перевірок, кількість взаємодій (без координат і клавіш) і першу мову браузера. Жодного хешу відбитка.
- Cookie лише на вашому домені.
__shp, перепустка після перевірки, і__shs, знак того, що браузер виконав сенсор. Власних cookie Satelit не ставить. - Коротке зберігання. Ключ клієнта (адреса або її мережа /64), User-Agent, правило та його доказ: 30 днів. Погодинні лічильники: 90 днів.
- Секрет лишається на сервері. Ключ сайту публічний. Секрет ви бачите один раз, а Satelit зберігає лише його хеш.
Ціни
Ви платите за перевірки, а не за трафік
Одна перевірка: один звіт сенсора або один виклик /assess. Рядки в /ingest безкоштовні, до 10 на кожну перевірку.
-
Shield Start
Один сайт: магазин, блог, невелика редакція.
19 € / міс.
381,72 лей
- Сайти
- 1
- Перевірки на місяць
- 250 000
-
Shield Pro
РадимоКілька сайтів із формами, голосуваннями чи акаунтами.
79 € / міс.
1 587,15 лей
- Сайти
- 5
- Перевірки на місяць
- 2 500 000
-
Shield Business
Мережі сайтів і платформи з великим трафіком.
249 € / міс.
5 002,53 лей
- Сайти
- 25
- Перевірки на місяць
- 15 000 000
-
Enterprise
Великі обсяги, умови й рахунки за договором.
від 990 € / міс.
від 19 889,59 лей
- Сайти
- за договором
- Перевірки на місяць
- від 50 000 000
Кожен новий сайт має 7 днів пробного періоду і 100 000 перевірок. Леї за курсом НБМ на 2 листопада 2026 р.: 1 євро = 20,0905 лея.
Питання про Shield
Чи не зашкодить Shield позиціям у Google?
Ні. Перевірені роботи (Google, Bing, Apple, Yandex, DuckDuckGo, Baidu, OpenAI, Perplexity, Anthropic та інші) не отримують жодних рішень: їхнє ім'я підтверджують офіційний список IP і зворотний DNS. Сенсор завантажується async і не затримує показ сторінки.
Чи працює разом із Cloudflare?
Так. Shield не замінює правила Cloudflare, а додає шар, що бачить браузер. Якщо сайт за Cloudflare, ваш проксі передає адресу з CF-Connecting-IP у X-Shield-Client-IP, щоб Shield оцінював відвідувача, а не Cloudflare.
Що буде з людиною, яку прийняли за бота?
Слабкі ознаки лише показують перевірку, яка проходить сама приблизно за секунду. Виходи Tor, спільні адреси й адреси, яким ви довіряєте, не зупиняються ніколи. Правило із забагатьма зупинками за годину саме повертається до спостереження, а будь-яке рішення можна зняти в панелі.
Як почати без ризику?
Новий сайт починає з усіма правилами в спостереженні: Shield лише відзначає, що зупинив би. Ви читаєте події в панелі й переводите в захист правила, яким довіряєте, по одному.
Чи сповільнить це сайт?
Сенсор завантажується async, після сторінки. Middleware тримає рішення в пам'яті й читає їх раз на 15–30 секунд, тож запит не чекає на мережу. Лише /assess, якщо ви його використовуєте, викликається на кожен запит.
Які дані збирає Shield?
ID перевірок, кількість взаємодій без координат і клавіш та першу мову браузера. Shield зберігає ключ клієнта, User-Agent, правило та його доказ 30 днів, а погодинні лічильники 90 днів. Без хешу відбитка й без cookie Satelit: це можна точно описати у вашій політиці конфіденційності.
Що робить Shield, якщо скрипт заблоковано?
Серверний шар працює й без нього: клієнт, що запитує багато сторінок без звіту сенсора, отримує перевірку. Через first-party проксі скрипт іде з вашого домену, і блокувальники реклами його не бачать.
Скільки триває зупинка?
24 години, потім 7 днів, потім 30 днів, якщо адреса повторює протягом 90 днів. Дійсна перепустка відкриває перевірку, але ніколи не зупинку.
Подивіться, що Shield зупинив би на вашому сайті
Новий сайт починає в спостереженні: Shield лише робить нотатки. Захист ви вмикаєте, коли впевнені, правило за правилом.