UK

Тема

Колір акценту

Тема й колір збережуться на satelit.md і в застосунку.

Панель Обрати тариф

Satelit Shield

Зупиняйте ботів і парсери, а не людей

Shield розпізнає автоматизацію, антидетект-браузери й парсери, на сторінці й на сервері; людина бачить щонайбільше перевірку, яка проходить сама приблизно за секунду.

Перші 7 днів: пробний період, 100 000 перевірок.

Справжній сенсор

Ваш браузер очима Shield

Перевіряємо браузер

Сенсор 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

    Відповідь POST /verify
    {
      "success": true,
      "verdict": "human",
      "score": 3,
      "action": "allow",
      "age_s": 4
    }

Як це працює

Два шари, одне рішення

Сенсор бачить браузер, ваш сервер бачить запити. Shield зводить їх для кожної адреси й вирішує один раз.

  1. На сторінці

    Сенсор

    • Один скрипт ES5 на ваших сторінках, завантажується async: не затримує показ сторінки.
    • Надсилає лише ID перевірок: без координат, клавіш, тексту й хешу відбитка.
    • Розв'язує сторінку перевірки: доказ роботи на 14 біт.
    • Зберігає перепустку 12 годин, у cookie на вашому домені.
  2. На сервері

    Запити

    • Ваш сервер або edge повідомляє, які запити надходять: по одному в /assess, пакетами в /ingest.
    • Shield рахує за адресою: IPv4 або мережа /64 для IPv6.
    • Ім'я робота перевіряється за офіційним списком IP і через зворотний DNS.
    • Заголовки Sec-Fetch, Client Hints і User-Agent мають казати одне й те саме.

Три можливі результати

  1. 200 Проходить Люди й перевірені роботи. Нічого не змінюється.
  2. 429 Перевірка на секунду Слабкі ознаки: сторінка, що проходить сама. Людина нічого не натискає.
  3. 403 Зупинено Точні ознаки: 24 години, потім 7 днів, потім 30 днів при повторі протягом 90 днів.

Спершу спостереження, потім захист

Кожне правило має режим: off, shadow (спостереження: Shield лише відзначає, що зробив би) або enforce (захист). Новий сайт починає з усіма правилами в спостереженні; ви переводите їх у захист по одному.

Перевірені роботи проходять завжди

Google, Bing, Apple, Yandex, DuckDuckGo, Baidu, OpenAI, Perplexity, Anthropic та інші: жодних рішень, ніколи. Так само ваш список дозволених.

Встановлення

Три кроки, перший в один рядок

Ключ сайту (shp_…) публічний і стоїть на сторінці. Секрет (shs_…) зберігається лише на сервері; ви бачите його один раз.

  1. Поставте сенсор на сторінки

    Напряму: один рядок на сторінці. Радимо через 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>
  2. Перевіряйте токен у формах

    Під час голосування, коментаря чи реєстрації сторінка бере токен через 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();
      });
    });
    POST /shield/v1/verify
    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";
    }
  3. Перенесіть рішення на сервер

    За бажанням, для всього сайту. 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, саме повертається до спостереження, а ви отримуєте подію.

  • automation жорсткесенсор

    WebDriver, 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-proof м'якезапити

    12 і більше сторінок за 10 хвилин без звіту сенсора й без cookie __shs.

  • rate м'якезапити

    60 і більше сторінок за хвилину.

  • walk м'якезапити

    40 і більше різних сторінок за 10 хвилин.

  • stale-browser м'якезапити

    Десктопний Chrome, старший на 8 і більше версій, без перепустки й без __shs.

  • ua-claim м'якезапити

    Chrome 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 на кожну перевірку.

  1. Shield Start

    Один сайт: магазин, блог, невелика редакція.

    19 € / міс.

    381,72 лей

    Сайти
    1
    Перевірки на місяць
    250 000
    Почати з Shield Start Почати з Shield Start
  2. Shield Pro

    Радимо

    Кілька сайтів із формами, голосуваннями чи акаунтами.

    79 € / міс.

    1 587,15 лей

    Сайти
    5
    Перевірки на місяць
    2 500 000
    Почати з Shield Pro Почати з Shield Pro
  3. Shield Business

    Мережі сайтів і платформи з великим трафіком.

    249 € / міс.

    5 002,53 лей

    Сайти
    25
    Перевірки на місяць
    15 000 000
    Почати з Shield Business Почати з Shield Business
  4. Enterprise

    Великі обсяги, умови й рахунки за договором.

    від 990 € / міс.

    від 19 889,59 лей

    Сайти
    за договором
    Перевірки на місяць
    від 50 000 000
    Призначити зустріч

Кожен новий сайт має 7 днів пробного періоду і 100 000 перевірок. Леї за курсом НБМ на 2 листопада 2026 р.: 1 євро = 20,0905 лея.

Питання про Shield

Уся документація 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 лише робить нотатки. Захист ви вмикаєте, коли впевнені, правило за правилом.