Suveren: подробное руководство¶
Здесь всё, что не поместилось в README: что именно смотрит каждая проверка, все параметры, форматы для CI и источники данных. Список проверок с ID — в checks.md.
Содержание¶
- Все команды
- Параметры проверки
- 1. Иностранные зависимости
- 2. Персональные данные и блокировки
- 3. Защита почты от подделки
- 4. Поддомены и их захват
- 5. Безопасность сайта
- 6. Проверка компании
- PDF и отчёты под брендом студии
- Массовая проверка
- Исследование по многим сайтам
- Слежение за сайтами
- Отслеживание импортозамещения
- CI и другие инструменты
- Режим
--browser - Источники данных
- Ограничения
- Как добавить сервис в базу
- Разработка
Все команды¶
| Команда | Что делает |
|---|---|
suveren scan сайт.ru |
полная проверка сайта |
suveren batch sites.txt |
проверка списка сайтов: сводная таблица, CSV и отчёт по каждому |
suveren company <ИНН, ОГРН или сайт> |
ЕГРЮЛ, санкционные списки, реестр операторов ПДн |
suveren diff old.json new.json |
что изменилось между двумя проверками |
suveren checks [ID или тег] |
все проверки с ID и тегами |
suveren services [фильтр] |
база распознаваемых сервисов |
suveren update |
скачать свежие санкционные списки и реестр блокировок |
suveren doctor |
проверить, что все источники данных отвечают |
suveren audit reports/ |
не противоречат ли отчёты сами себе |
suveren unknown |
внешние домены, которых нет в базе сервисов |
suveren watch sites.txt --every 24h |
следить за сайтами: проверять снова и сообщать, что изменилось (можно в Telegram) |
suveren research sites.txt |
исследование: много сайтов, на выходе только сводка — доли по каждой находке, CSV и HTML с графиками; названия сайтов скрыты |
suveren draft отчёт.json |
черновик политики или согласия по найденному (проверьте с юристом) |
suveren verify сайт.ru |
подтвердить, что сайт ваш, — для --own-site и --form-leaks |
suveren menu |
меню (то же, что двойной клик по exe) |
Главные параметры scan (полный список — suveren scan --help):
| Параметр | Что делает |
|---|---|
--browser, -b |
открыть сайт в браузере (Edge или Chrome): видны скрипты, которые подгружаются динамически |
--profile quick\|standard\|deep |
quick — только иностранные сервисы; standard — все проверки (по умолчанию); deep — в браузере, до 12 страниц и с экспериментом --cutoff |
--checks mail,SUV-LAW-001 |
только нужные проверки: по ID, префиксу или тегу |
--pages N |
сколько внутренних страниц проверить кроме главной (по умолчанию 6) |
--cutoff |
эксперимент: открыть сайт без иностранных сервисов и показать, что сломается |
--form-leaks |
эксперимент: уходят ли данные из форм сторонним сервисам до отправки (только вместе с --own-site, после suveren verify) |
--own-site |
режим «свой сайт»: .git и .env, шифры TLS, STARTTLS почты (после suveren verify) |
--pdf файл.pdf |
сохранить отчёт ещё и в PDF |
--docx файл.docx |
отчёт в Word: оценка, что сделать, штрафы, все проверки |
--summary файл.html |
сводка на одну страницу для руководителя: оценка, главные риски, штрафы, что сделать |
--brand-name, --brand-logo, --brand-url |
отчёт под брендом вашей студии |
--json файл.json, --sarif файл.sarif |
результат для diff, CI и сканеров безопасности |
--since прошлый.json |
что изменилось с прошлой проверки |
--fail-under C, --fail-on fail |
ненулевой код выхода для CI |
--ignore файл |
принятые находки с причиной, автором и сроком (по умолчанию .suveren-ignore) |
--dns ru |
DNS-запросы только через Яндекс DNS. Остальные источники не меняются: имя сайта уходит в crt.sh, Cert Spotter и rdap.org, IP-адреса — в Team Cymru |
--no-mail, --no-security, --no-subdomains, --no-152fz, --no-blocklist |
пропустить раздел |
--dkim-selector ИМЯ |
свой селектор DKIM (s= в заголовке DKIM-Signature ваших писем), можно несколько раз; проверяется вместе с распространёнными |
--verbose, -v |
печатать каждый сетевой шаг со временем (есть и у company, batch, research, doctor) |
Параметры проверки¶
Полезные параметры scan: --pages N (сколько внутренних страниц проверить, по умолчанию 6),
--details (все найденные сервисы в терминале), --quick (только иностранные сервисы, без 152-ФЗ, блокировок, почты, поддоменов и безопасности), --json file.json (сохранить для diff), --fail-under C (код выхода 3, если общая оценка хуже C,
для CI), --no-open (не открывать браузер), --dns ru (DNS-запросы только через Яндекс DNS;
это касается только DNS: имя сайта всё равно уходит в crt.sh, Cert Spotter и rdap.org, IP-адреса —
в Team Cymru).
Отчёты сохраняются в reports/ в HTML и открываются в браузере.
Где зависает. --verbose (-v) у scan, company, batch, research и doctor печатает
каждый шаг (этапы проверки, запросы DNS, HTTP, TLS, WHOIS, страницы в браузере) при начале и
конце, со временем от запуска:
7.1 с → HTTP GET exoway.ru/
8.7 с ← HTTP GET exoway.ru/: код 200, 1.6 с
12.4 с → DNS MX exoway.ru (system)
Если сеть что-то блокирует, последней будет строка → с хостом, ответа от которого ждут.
Строки идут в stderr (--json - остаётся чистым) и показывают только хост и путь: без
параметров запроса, заголовков и токенов, их можно приложить к сообщению об ошибке.
Профили и выбор проверок. --profile quick — только иностранные сервисы (то же, что
--quick), standard — все проверки (по умолчанию), deep — все проверки в браузере и до 12
внутренних страниц. У каждой проверки есть постоянный ID: SUV-MAIL-003 (DMARC),
SUV-LAW-001 (вход через иностранные сервисы) и т. д., он показан в HTML-отчёте, JSON и SARIF.
Под каждой проблемой в отчёте раскрывается «Доказательство»: на чём основан вывод, ровно так,
как это увидел Suveren. Это DNS-запись (TXT _dmarc… — v=DMARC1; p=none), заголовок ответа
(пустой, если его нет), адрес скрипта с уязвимой версией, форма с её полями, цитата из
соглашения, запрос, в котором ушли данные из формы, запись реестра блокировок. Секреты из кода
показаны замаскированными.
--checks оставляет только нужные: по ID, префиксу или тегу через запятую, и запускает
только те модули, которые для них нужны:
suveren checks # все проверки, ID и теги
suveren scan example.ru --checks mail,headers # только почта и заголовки безопасности
suveren scan example.ru --checks SUV-LAW-001,SUV-PD
Иностранные зависимости тоже имеют ID по категории: SUV-DEP-HOSTING, SUV-DEP-DNS,
SUV-DEP-MAIL…
Описание всех проверок с ID, модулями и тегами — в checks.md.
1. Иностранные зависимости¶
| Что | Как определяется | Чем грозит |
|---|---|---|
| DNS-серверы | NS-записи и сеть их IP-адресов | блокировка аккаунта кладёт сайт и почту сразу |
| Почта | MX-записи | потеря входящих писем и архива переписки |
| Хостинг | IP сайта → сеть (ASN) и страна её владельца | удаление аккаунта вместе с данными |
| Конструктор / CMS | код страницы и сеть | Tilda, Wix, Webflow, Shopify: перенести сайт непросто |
| CDN и анти-DDoS | IP сайта | недоступность и замедление для пользователей из РФ |
| Регистратор | RDAP / WHOIS | отказ в продлении домена |
| Доменная зона | TLD | санкционные требования иностранного реестра |
| SSL-сертификат | TLS-рукопожатие | отзыв сертификата иностранным УЦ |
| Скрипты и виджеты | код главной и внутренних страниц, в режиме --browser все сетевые запросы |
аналитика, реклама, капча, шрифты, чаты, формы, карты, видео, оплата, вход через соцсети |
Отдельно отмечаются сервисы, которые в России заблокированы или не работают: Meta (Facebook, Instagram), LinkedIn, X (Twitter), YouTube, Google Ads, а также скомпрометированный polyfill.io.
В базе около 300 сервисов, иностранных и российских (suveren services). Страной сервиса
считается юрисдикция компании-владельца, а не место дата-центра: санкции применяются к компании.
Оценка. Каждая категория с иностранной зависимостью даёт один риск: высокий −20, средний −10, низкий −4. A от 90, B от 75, C от 60, D от 40, ниже — F. Если в категории есть и иностранный, и российский сервер (например, резервный NS), риск понижается на ступень. Если страницу сайта увидеть не удалось (ничего не пришло, стена от ботов или страница ошибки), скрипты и виджеты не проверены, и обе оценки не выше B: A означает «проверено и чисто», а не «ничего не увидели».
Как переехать. У каждого риска в HTML-отчёте раскрывается план: 2–5 шагов, российские
варианты, сложность (легко / средне / сложно) и ориентир по стоимости — без цен в рублях, они
быстро устаревают. В конце отчёта — сводный «План переезда»: сначала то, что опаснее и проще
перенести. В JSON — поле migration. Данные — в src/suveren/data/migration.json.
Что сломается при отключении: эксперимент --cutoff¶
suveren scan example.ru --cutoff # или --profile deep
Не прогноз, а опыт. Сайт открывается в браузере четыре раза: как обычно, без иностранных
сервисов (все их запросы отклоняются, как при отключении), снова как обычно и, наконец, с
зависшими иностранными сервисами: их запросы остаются без ответа, как при блокировке,
которая отбрасывает пакеты. В отчёте — два скриншота рядом и что именно перестало работать:
ошибки JavaScript в коде сайта (например, jQuery с Google CDN, без которого падают меню и
формы), пропавшие кнопки, формы с иностранной капчей, которые не отправятся, карты и видео,
картинки, шрифты, доля пропавшего текста. Отдельно — что будет при зависании: успел ли браузер
хоть что-то нарисовать за 10 секунд и загрузилась ли страница до конца (обычно мешают Google
Fonts или скрипты в <head>). Изменения, которых нет в обоих обычных прогонах (лента новостей, ротация
баннеров, «5 минут назад»), не считаются, чтобы не было ложных тревог.
Иностранный ли хост, решает база сервисов, а для неизвестных — сеть, в которой находится его
IP-адрес. Свой домен сайта не отключается: что будет при потере иностранных DNS, хостинга, CDN и
почты, показывает отдельная проверка «сайт и почта целиком». Нужен Playwright (как для
--browser).
Утекают ли данные из форм до отправки: эксперимент --form-leaks¶
suveren scan example.ru --form-leaks
Запись сессий, «ловцы брошенных заявок», рекламные пиксели с автоматическим сопоставлением читают то, что человек печатает в форме, и отправляют это ещё до нажатия «Отправить», то есть до согласия. Suveren открывает главную и до двух страниц с формами в браузере, печатает в поля имени, телефона, почты и пароля тестовые значения и ищет их во всём, что страница отправляет: открытым текстом, в base64, в сжатом виде (gzip) и как хеши MD5, SHA-1 и SHA-256. Методика — как в исследовании Leaky Forms (Senol и др., USENIX Security 2022). Проверка SUV-PD-012: пароль у стороннего сервиса или данные у иностранного — «проблема», у российского — «внимание» (152-ФЗ, ст. 7 и ст. 6 ч. 3: без согласия раскрывать данные третьим лицам и поручать им обработку нельзя).
Эксперимент трогает формы сайта, поэтому включается только своим флагом: ни профиль deep,
ни --checks pd его не запускают. Формы не отправляются: событие отправки отменяется раньше
обработчиков сайта. Тестовые значения никуда не дойдут: почта на example.com (RFC 2606),
у телефона код 100, которого нет в плане нумерации, а номер, который маска поля превратила в
другой, стирается до выхода из поля. Маски многих форм принимают только номера на 9: тогда
отчёт так и говорит, что телефон не проверен, а для своего сайта можно указать свой номер —
--form-phone +7XXXXXXXXXX (номера не должно быть на страницах сайта; в отчёте он скрыт).
Виджет «брошенных заявок» может показать владельцу сайта тестовую заявку, поэтому запускайте
эксперимент на своих сайтах или с согласия владельца.
Видно то, что уходит в распознаваемом виде; зашифрованное найти нельзя, поэтому «в порядке»
значит «не нашли», а не «точно нет».
2. Персональные данные и блокировки¶
Проверяются главная и внутренние страницы: формы чаще всего стоят в «Контактах», корзине и оформлении заказа, поэтому они проверяются в первую очередь. Одинаковая форма из шапки сайта считается один раз, а в отчёте видно, на какой странице найдена проблема.
| Проверка | Что смотрится |
|---|---|
| Политика обработки ПДн | ссылка на главной (ст. 18.1); если ссылки нет — раздел о ПДн в пользовательском соглашении |
| Содержание политики | 10 разделов из рекомендаций Роскомнадзора от 31.07.2017: сведения об операторе, цели, правовые основания, какие данные и чьи, действия и способы, сроки, уничтожение, права субъекта, порядок запросов, меры защиты; трансграничная передача, если на сайте есть иностранные сервисы. Если по ссылке пришла оболочка сайта без текста политики — «не проверено» |
| Политика и реальность | сходится ли политика с сайтом: оператор с тем же ИНН, что в реквизитах, и этот сайт, а не другой (скопированная политика); все данные, которые просят формы, в перечне (ст. 18.1 ч. 1 п. 2); cookies, если на сайте счётчики и нет отдельной политики cookies; нет категоричных «не передаём третьим лицам» при сервисах, которые данные получают |
| Согласие в формах | формы с телефоном, почтой или именем без согласия; заранее отмеченные галочки |
| Отдельное согласие | с 1 сентября 2025 года согласие оформляется отдельно от других документов (ст. 9 ч. 1 в ред. 156-ФЗ): одна фраза «принимаю условия оферты и даю согласие на обработку» в форме или «использование сайта означает согласие на обработку» в политике и соглашении дают «внимание»; отдельный документ согласия — «в порядке» |
| Уведомление о cookies | есть ли баннер, если на сайте аналитика, реклама или чаты |
| Трансграничная передача | иностранные скрипты, получающие данные посетителей (ст. 12) |
| Хранение данных в России | где физически стоит сервер сайта (база DB-IP), если на нём собираются данные (ст. 18 ч. 5); адреса CDN не в счёт |
| Защищённое соединение | HTTPS и адреса отправки форм |
| Реестр операторов ПДн | ИНН ищется на сайте и странице контактов, затем — в реестре Роскомнадзора |
| Реестр блокировок | домен и IP сайта в выгрузке реестра РКН от antifilter.download (не официальный источник) |
| Вход через иностранные сервисы | кнопки и ссылки «Войти через Google / Apple / Facebook / GitHub / Microsoft / X / Telegram» и др. (149-ФЗ, ст. 8 ч. 10; штраф по ст. 13.55 КоАП с 7 июля 2026 года) |
| Рекомендательные технологии | блоки «Персональные рекомендации», «Вам может понравиться», «Вы недавно смотрели» и ссылка на правила их применения (149-ФЗ, ст. 10.2-2; штраф по ст. 13.56 ч. 3 КоАП с 7 июля 2026 года). Нет правил — «внимание»: снаружи не видно, строится ли подборка по интересам |
Вход через иностранные сервисы. С 1 декабря 2023 года российский сайт может авторизовать
пользователей из России только по номеру телефона, через Госуслуги, ЕБС или российские системы
(VK ID, Яндекс ID, Сбер ID, Т-ID). Suveren смотрит главную, внутренние страницы и страницу
«Войти» / «Личный кабинет»: ссылки на OAuth-адреса (accounts.google.com/o/oauth2,
appleid.apple.com/auth/authorize и т. п.), собственные адреса сайта вида /auth/google,
виджеты входа (Google One Tap, «Вход с Apple», Telegram Login, uLogin) и надписи на кнопках.
Обычные ссылки на Google Карты, App Store, канал в Telegram или кнопка «Поделиться» входом не
считаются, как и статья о том, как войти через Google. Если найден только скрипт или только
надпись, без ссылки, которая начинает вход, это «внимание», а не нарушение. Иностранная почта в
качестве логина требованием не запрещена.
Потенциальные штрафы. Над разделом 152-ФЗ отчёт показывает блок «Потенциальные штрафы: до N ₽»: для каждого нарушения — статья КоАП и вилка для юрлица, ИП, должностного лица и при повторном нарушении, если закон его выделяет. В сумму входят только безусловные штрафы за найденные проблемы, по одной статье на нарушение: сейчас это «нет политики» (ст. 13.11 ч. 3). Если квалификация зависит от обстоятельств, которых Suveren не видит, штраф показан с условием, но в сумму не входит: база за рубежом (ч. 8, «если заявки с сайта хранятся на этом сервере»), вход через иностранные сервисы (ст. 13.55, «если владелец сайта — российская компания или гражданин»). Предупреждения «форма без согласия» (ч. 1, «если для этой обработки нужно согласие»: для заявки на договор или обращения в госорган оно не нужно) и «нет в реестре операторов» (ч. 10) показываются, но в сумму не входят. «Не проверено» в расчёт не попадает. Суммы сверены с текстом КоАП на consultant.ru (ред. от 04.08.2026). Это оценка максимального риска, а не юридическое заключение. В терминале — одна строка с итогом, в JSON — поле fines.
Крупные сайты часто отдают роботам пустую страницу или проверку «вы не робот». Suveren это
распознаёт и честно пишет «не проверено» вместо ложной ошибки, а режим --browser в большинстве
таких случаев получает настоящую страницу.
3. Защита почты от подделки¶
Фишинг и поддельные счета чаще всего приходят «от директора» или «от бухгалтерии» настоящего домена компании. Suveren читает DNS-записи домена, как это делает почтовый сервер получателя, и отвечает простым языком: можно ли подделать письмо от имени @ваш-домен — да, частично или нет, и что исправить.
| Проверка | Что смотрится |
|---|---|
| Вердикт | DMARC с политикой reject — нет; quarantine или pct < 100 — частично (письма уйдут в спам); p=none или нет DMARC — да. Отдельно отмечается sp=none, при котором не защищены поддомены |
| SPF | одна ли запись, +all / ?all, лимит в 10 DNS-запросов по всей цепочке include и redirect. Если DNS не ответил на include или redirect, запрос повторяется один раз, и только потом проверка говорит, что цепочку проверить не удалось |
| DMARC | политика, pct, адрес для отчётов rua |
| DKIM | ключи по распространённым селекторам (Яндекс 360, VK WorkSpace, Microsoft 365, Google, рассыльщики) и по вашим (--dkim-selector); если не найдены — «не проверено», а не ошибка. Список ключей домена снаружи не получить: свой селектор видно в заголовке DKIM-Signature (s=) любого письма |
| MTA-STS, TLS-RPT | шифрование входящей почты |
| BIMI | для сведения: есть ли запись default._bimi с логотипом и покажут ли его (нужен DMARC quarantine или reject для всех писем, а Gmail и Apple Mail ещё требуют сертификат VMC или CMC). Никогда не «внимание»: на защиту от подделки BIMI не влияет; если DNS не ответил, проверки нет |
Домену, который не принимает почту, тоже нужна защита: Suveren подскажет записи v=spf1 -all
и p=reject. Проверка только читает DNS и публичный файл политики MTA-STS, писем не
отправляет. Отключить её можно параметром --no-mail.
4. Поддомены и их захват¶
Каждый публичный SSL-сертификат попадает в журналы Certificate Transparency, поэтому список поддоменов компании виден любому, включая давно забытые промо-сайты. Если такой поддомен по-прежнему ведёт (CNAME) на сервис, где проект уже удалён, его может подключить к себе другой клиент сервиса и показывать на настоящем домене компании свою страницу: фишинг, кража cookies.
| Признак | Как определяется |
|---|---|
| CNAME ведёт на свободный домен | домена нет в DNS, и реестр (RDAP, для .ru/.рф — WHOIS) подтверждает, что он не зарегистрирован. Если реестр не ответил — только предупреждение |
| Ресурс в облаке удалён | CNAME на Azure, Elastic Beanstalk и т. п., а имя больше не существует |
| Сервис отвечает «такого проекта нет» | страница-заглушка GitHub Pages, Heroku, Netlify, AWS S3, Yandex Object Storage, Shopify, Read the Docs и ещё 32 сервиса |
Сигнатуры взяты из открытого справочника can-i-take-over-xyz
(CC BY 4.0); тексты заглушек для 13 сервисов сверены вживую. Каждая находка подаётся как
«возможный захват, проверьте вручную». Поддомены берутся из crt.sh (запасной источник — Cert
Spotter, результат кэшируется на сутки), проверяются первые 300. Имя домена при этом уходит в
эти сервисы; отключить проверку можно параметром --no-subdomains. Список поддоменов к сайту не
обращается, а проверка захвата прощупывает: DNS и по одному запросу к страницам поддоменов,
которые ведут на известный сервис.
5. Безопасность сайта¶
| Проверка | Что смотрится |
|---|---|
| Сторонний код | с каких чужих адресов страницы загружают скрипты: каждый из них может выполнить на сайте любой код |
| Брошенные и скомпрометированные домены | домен скрипта не зарегистрирован (подтверждается через RDAP/WHOIS) — его может купить кто угодно; домены, раздававшие вредоносный код в 2024 году (polyfill.io и связанные с ним) |
| Ключи и секреты в коде | собственные скрипты сайта и скрипты внутри страниц: приватные ключи, токены Telegram-ботов, ключи AWS, Stripe, GitHub, Slack, SendGrid, OpenAI, Anthropic, OAuth-токены Яндекса и ключи Yandex Cloud — «проблема»; ключ Google API, публичный по задумке, — «внимание», его нужно ограничить по домену. Значения в отчёте замаскированы (AKIA…4D) |
| Уязвимые версии библиотек | jQuery, jQuery UI, Bootstrap, lodash, Moment.js, AngularJS, Vue.js, React — только если версия написана явно (в имени файла, пути CDN или в заголовке самой библиотеки). Версия сверяется с базой retire.js: она скачивается раз в сутки, а без сети берётся встроенная копия (src/suveren/data/retire.json); какая копия и от какого числа — в доказательствах. Неподдерживаемые ветки (jQuery 1–2, Bootstrap 3, AngularJS 1.x) отмечаются отдельно; уязвимости, которые бывают только на сервере (в том числе при отрисовке React и Vue на сервере), не учитываются. Статус — «внимание»: можно ли воспользоваться уязвимостью, зависит от того, как сайт вызывает библиотеку |
| Версия CMS | WordPress и 1С-Битрикс по тегу generator и путям их файлов (/wp-content/, /bitrix/) на уже загруженных страницах, без лишних запросов к сайту. Версия показывается, если видна (у WordPress — по тегу generator или по своим файлам вроде wp-emoji-release.min.js?ver=), но статус всегда «не ясно»: открытой базы уязвимостей по версиям этих CMS без ключа API нет, и Suveren не гадает. В совете — где проверить обновления |
| Цепочки сторонних скриптов | в режиме --browser: кто какой скрипт подключил (по данным браузера). Код, который подключил не сайт, а чужой скрипт (тег-менеджер, рекламная сеть), — «внимание»; в HTML-отчёте — схема цепочек |
| SRI | атрибут integrity у библиотек с публичных CDN (cdnjs, jsDelivr, unpkg и др.). Скрипты аналитики и виджетов меняются постоянно, у них SRI быть не может, и Suveren его не требует |
| CSP | есть ли политика, нет ли в ней 'unsafe-inline' без nonce, 'unsafe-eval', разрешения скриптов отовсюду, запрещены ли плагины (object-src 'none' или строгий default-src) |
| HSTS | заголовок и срок не меньше 180 дней |
| Защитные заголовки | защита от встраивания в чужие страницы (X-Frame-Options или frame-ancestors) и X-Content-Type-Options: nosniff |
| Permissions-Policy | какие функции браузера (камера, микрофон, геолокация, оплата) разрешены странице и встроенным в неё чужим фреймам. Заголовка нет — мягкое «внимание» (совет OWASP Secure Headers, срочность низкая); заголовок в синтаксисе старого Feature-Policy (camera 'none') браузер отбрасывает целиком — тоже «внимание» |
| Cookies | флаги Secure, HttpOnly и SameSite у cookies, похожих на сессионные (CSRF-токены не трогаются: их должны читать скрипты) |
| TLS | срок сертификата и не принимает ли сервер устаревшие TLS 1.0 и 1.1 |
Сценарии атак. Отчёт открывается разделом, где находки из разных модулей собраны в то, что сделал бы злоумышленник: «фишинг от имени компании» (почту можно подделать + на сайте есть формы или оплата), «чужой код у всех посетителей» (брошенный домен скрипта или CDN без SRI и CSP), «захват поддомена», «перехват при первом заходе» (нет HSTS + формы), «утёкший ключ», «отключение сайта и почты». Сценарий появляется, только если найдена вся цепочка; каждый шаг ссылается на ID проверки, а совет называет одно действие, которое цепочку рвёт.
Если вместо сайта ответила защита от ботов или сайт перенаправил на другой домен, заголовки
не оцениваются: у заглушки они свои. TLS проверяется у того адреса, который вы указали, а не у
сервера, куда ведёт перенаправление. Отключить раздел можно параметром --no-security.
6. Проверка компании¶
suveren company 7707083893 # по ИНН
suveren company 1027700132195 # по ОГРН
suveren company example.ru # ИНН будет найден на сайте
- ЕГРЮЛ / ЕГРИП (ФНС): название, статус, дата регистрации, руководитель. Ликвидированная или слишком молодая компания отмечается.
- Санкционные списки США (OFAC SDN), ЕС и Великобритании. Совпадение по ИНН/ОГРН точное; совпадение по названию учитывает транслитерацию («СБЕРБАНК РОССИИ» = «Sberbank of Russia»). Руководитель проверяется по фамилии и имени, такие совпадения помечаются как возможные.
- Реестр операторов ПДн Роскомнадзора.
- Сверка с сайтом: указан ли ИНН на сайте и совпадает ли владелец домена в WHOIS.
Списки (около 110 МБ) скачиваются при первой проверке и обновляются раз в сутки. Кэш хранится в
%LOCALAPPDATA%\suveren\cache на Windows и в ~/.cache/suveren на Linux и macOS.
PDF и отчёты под брендом студии¶
suveren scan example.ru --pdf example.pdf --brand-name "Студия Север" --brand-logo logo.png --brand-url sever.ru
suveren company 7707083893 --pdf company.pdf --brand-name "Студия Север"
--pdf печатает отчёт в PDF (A4) тем же браузером, что и --browser (нужен Playwright),
блоки «Как переехать» в нём раскрыты. --brand-name, --brand-logo (PNG, JPEG или SVG до 512 КБ,
встраивается в отчёт) и --brand-url ставят в шапку и подвал вашу студию вместо Suveren; строка
«Сделано с помощью Suveren» остаётся. Работает в scan, batch и company. Чтобы не повторять
параметры, задайте переменные окружения SUVEREN_BRAND_NAME, SUVEREN_BRAND_LOGO,
SUVEREN_BRAND_URL.
Массовая проверка¶
Для веб-студий и аудита нескольких сайтов: файл со списком, по одному домену в строке.
suveren batch sites.txt --browser
В папке reports/batch-… появятся index.html со сводной таблицей, summary.csv для Excel и
отчёт по каждому сайту. Сайты идут от худшей общей оценки к лучшей, независимость — в соседней
колонке. В summary.csv прежние колонки grade и score по-прежнему означают независимость,
общая оценка добавлена в конец: overall_grade и overall_score. Сайты, которые проверить не
удалось, тоже есть в таблице: причина — в последней колонке error.
Исследование по многим сайтам¶
suveren research sites.txt проверяет список сайтов (можно сотни) и собирает только сводку:
какая доля сайтов с каждой находкой, а если в списке указан тип сайта — то и по типам.
Сайты проверяются параллельно (по умолчанию по 4); прерванный прогон продолжается с того же
места. Сырые отчёты лежат в reports/research/raw/, сводка — в summary.csv и summary.html
с графиками, без внешних скриптов. «Не проверено» в доли не входит. Названия сайтов в сводке
скрыты; --show-domains показывает их — только для себя, такой список не публикуют.
shop.ru, магазин
clinic.ru, медицина
Слежение за сайтами¶
suveren watch sites.txt проверяет сайты из списка снова и сравнивает с прошлым разом: какие
сервисы появились или пропали, какие проверки стали лучше или хуже. Изменения пишутся в
reports/watch/changes.log. Если изменений нет, ничего не приходит.
Чтобы изменения приходили в Telegram, создайте бота у @BotFather и задайте его токен и чат (токен не попадает ни в отчёты, ни в журнал):
suveren watch sites.txt --once --telegram-token 123456:ABC... --telegram-chat 123456789
# или через переменные окружения (так токена нет в истории команд):
setx SUVEREN_TELEGRAM_TOKEN "123456:ABC..."
setx SUVEREN_TELEGRAM_CHAT "123456789"
Каждый день в 9:00 через Планировщик заданий Windows (один круг за запуск):
schtasks /Create /SC DAILY /ST 09:00 /TN "Suveren watch" ^
/TR "\"C:\Suveren\Suveren.exe\" watch C:\Suveren\sites.txt --once --state C:\Suveren\watch"
Или вручную: Планировщик заданий → «Создать простую задачу» → «Ежедневно» → «Запустить
программу»: программа C:\Suveren\Suveren.exe, аргументы
watch C:\Suveren\sites.txt --once --state C:\Suveren\watch. В меню (Suveren.exe или
Suveren.bat) это пункт 9 «Следить за сайтами».
Отслеживание импортозамещения¶
suveren scan example.ru --json before.json
# ... переехали на российские сервисы ...
suveren scan example.ru --json after.json
suveren diff before.json after.json
example.ru: независимость D → A, 52 → 96 из 100
− убран DNS-серверы: Cloudflare
− убран Почта: Google Workspace
+ добавлен DNS-серверы: Selectel
+ добавлен Почта: Яндекс 360
✓ Уведомление о cookies: warn → ok
CI и другие инструменты¶
suveren scan example.ru --no-open --sarif suveren.sarif --fail-on fail
--sarif файл— результат в SARIF 2.1.0, стандартном формате сканеров безопасности: его читают GitHub и GitLab code scanning, DefectDojo и другие системы. В файл попадают проблемы (error), «внимание» (warning), «не проверено» и иностранные зависимости низкого риска (note); пройденные проверки — нет. Оценки лежат вruns[0].properties: общая (overallGrade,overallScore,overallIncomplete— почему неполная) и независимость от иностранных сервисов (grade,score).--json -или--sarif -выводят результат в stdout, а всё остальное — в stderr:suveren scan example.ru --json - --no-report | jq .overall_grade. Ошибки всегда идут в stderr.--json файл— полный результат, в том числе пройденные проверки (нужен дляdiff). Формат описан JSON-схемойsrc/suveren/data/report.schema.json; полеschema_versionрастёт по semver, проверки различайте поid(SUV-…), а не по названию. С версии схемы 1.4 у каждой проверки естьevidence: список{kind, what, value}(тот же список — вproperties.evidenceрезультата SARIF).--since прошлый.json— раздел «С прошлой проверки»: какие сервисы убраны или добавлены и какие проверки стали лучше или хуже (то же сравнение, что вsuveren diff).--plugin файл.py— свои проверки, см. plugins.md.--ignore файл— принятые находки (по умолчанию.suveren-ignoreв текущей папке, если он есть; работает и вbatch). Одна строка — одно исключение: ID проверки, сайт (домен, его поддомены тоже подходят, или*— любой), последний день действия, автор одним словом и причина до конца строки. Строки с#пропускаются:
# ID сайт до автор причина
SUV-MAIL-005 example.ru 2027-01-31 ivanov MTA-STS настроим после переезда почты
SUV-WEB-004 * 2026-12-31 petrova CSP готовим в задаче WEB-123
Принятая проблема остаётся в отчёте со своим статусом и пометкой «Принято до … (автор):
причина», но не входит в «Что сделать», общую оценку, --fail-on и --fail-under. В JSON у
неё есть accepted (схема 1.9), в SARIF — suppressions со статусом accepted, и code
scanning показывает её закрытой. Принять можно только «проблему» или «внимание»: «не
проверено» ничего не скрывает. Возможный штраф за принятую проблему остаётся в расчёте:
закону решение команды не важно. После срока исключение перестаёт действовать, и в
замечаниях отчёта написано, какое истекло. Исключение для проверки, которая уже в порядке,
тоже названо: его можно удалить. Файл с ошибкой (нет причины, дата не ГГГГ-ММ-ДД,
неизвестный ID) не читается целиком, и проверка не начинается.
Коды выхода:
| Код | Когда |
|---|---|
| 0 | проверка прошла |
| 1 | проверка не выполнена (сайт не найден, сеть); batch — хотя бы один сайт не проверен или строка списка пропущена (отчёты по остальным всё равно записаны) |
| 2 | неверные параметры |
| 3 | --fail-under C: общая оценка хуже C |
| 4 | --fail-on fail: есть проверки со статусом «проблема»; --fail-on warn — ещё и «внимание» |
| 5 | suveren audit: в отчётах есть противоречия |
| 6 | задан --fail-under или --fail-on, пороги не нарушены, но оценка неполная (стена от ботов, не ответил реестр или журнал сертификатов): то, чего не видно, порог не проверяет. --allow-incomplete принимает неполную оценку |
В batch пороги --fail-under и --fail-on действуют по худшему сайту, код 1 (сайт не
проверен) важнее кодов 3, 4 и 6. --timeout — таймаут одного сетевого запроса, --max-time — предел на
всю проверку сайта (у scan по умолчанию 600 с, у batch — 300 с на сайт); не уложилась —
код 1 у scan, «не проверен» у сайта в batch. В CI (переменная CI) и при выводе не в
терминал отчёт в браузере не открывается. В summary.csv колонка grade — оценка
независимости от иностранных сервисов, общая оценка — overall_grade.
Режим --browser¶
Обычная проверка читает HTML главной страницы. Современные сайты часто собирают страницу
скриптами, а аналитику подключают через менеджеры тегов, и в исходном HTML этого не видно.
С --browser Suveren открывает сайт в настоящем браузере (Edge или Chrome, которые уже стоят
в системе) и учитывает все сетевые запросы страницы.
Нужен пакет Playwright: pip install playwright (уже входит в suveren[browser] и ставится
Suveren.bat). Если в системе нет ни Edge, ни Chrome: playwright install chromium.
Источники данных¶
| Данные | Источник |
|---|---|
| DNS | системный резолвер; если он отвечает неполно — Яндекс DNS по DNS-over-TLS, и только если не ответил и он — DNS-over-HTTPS Google и Cloudflare (об этом пишется в отчёте) |
| Сети и страны IP-адресов | Team Cymru IP-to-ASN (через DNS) |
| Регистратор | RDAP, WHOIS реестров |
| ЕГРЮЛ / ЕГРИП | egrul.nalog.ru (ФНС России) |
| Операторы ПДн | pd.rkn.gov.ru (Роскомнадзор) |
| Реестр блокировок | выгрузка реестра РКН от antifilter.download |
| Поддомены | журналы Certificate Transparency: crt.sh, запасной — Cert Spotter |
| Санкции | OFAC SDN (США), сводный список ЕС, UK Sanctions List |
| Уязвимые библиотеки | база retire.js (раз в сутки; без сети — встроенная копия с датой) |
| Адреса облаков | списки AWS, Google Cloud, Oracle Cloud, DigitalOcean (раз в неделю) |
Все источники открытые и бесплатные, ключи API не нужны. Государственные сайты иногда меняются без
предупреждения, поэтому suveren doctor проверяет каждый источник, а на GitHub эта проверка
запускается ежедневно.
Ограничения¶
- Кроме главной проверяются до 6 внутренних страниц (
--pages): в первую очередь «Контакты», заявки, корзина, доставка, услуги. Сервисы, которые есть только на остальных страницах, могут не попасть в отчёт. - Часть сайтов блокирует даже браузерный режим: тогда проверки по коду страницы помечаются как «не проверено».
- Если сайт за CDN, настоящий хостинг скрыт, и Suveren об этом предупреждает.
- Совпадения по названию и ФИО в санкционных списках нужно проверять вручную.
- Suveren в основном смотрит: публичные DNS-записи, WHOIS, открытые реестры и обычная загрузка
страниц. Прощупывает он в двух местах (соединения по TLS 1.0 и 1.1, страницы поддоменов), а
--form-leaksвводит тестовые данные в формы. Метки каждой проверки — в checks.md и в разделе README «Что Suveren делает с сайтом». Никакого сканирования портов и подбора. - Отчёт помогает расставить приоритеты и не является юридическим заключением. У каждой проверки 152-ФЗ указано основание (статья закона) со ссылкой на текст, чтобы вывод можно было перепроверить.
Как добавить сервис в базу¶
База — это файл данных src/suveren/data/services.json,
программировать не нужно. Инфраструктура (DNS, почта, хостинг) лежит в разделе infra:
{
"name": "Hetzner",
"country": "DE",
"ns": ["hetzner.com"],
"mx": ["your-server.de"],
"asn": [24940],
"as_names": ["hetzner"]
}
country — страна компании (ISO 3166), ns и mx — суффиксы серверов, asn — номера
автономных систем, as_names — фрагменты названия сети. Сервисы, подключаемые на странице, лежат
в разделе page: у них есть категория и регулярные выражения по коду страницы:
{"name": "Яндекс Метрика", "country": "RU", "category": "analytics", "page": ["mc\\.yandex\\.(?:ru|com)"]}
Тест test_data_file_entries_are_valid проверит, что запись корректна. Добавьте тест в
tests/test_services.py и откройте pull request. Если не хотите ничего править, откройте issue
«Добавить сервис»: там простая форма. Подсказка, что добавлять: suveren unknown показывает
домены, которые встречались при проверках, но которых нет в базе (список хранится только на
вашем компьютере).
Разработка¶
pip install -e ".[dev,browser]"
pytest
ruff check . && ruff format --check .
Тесты не ходят в сеть: ответы реестров и фрагменты санкционных списков лежат в tests/fixtures.
Проверка на случайных данных. tests/test_fuzz.py гоняет разборщики SPF (вместе с обходом
include и redirect), DMARC, MTA-STS, CSP, Set-Cookie и карты сайта на мусоре: настоящий синтаксис
вперемешку со случайным текстом, кавычками, управляющими символами и битым UTF-8
(Hypothesis). Разборщик должен ответить, а не упасть. В
обычном прогоне 200 примеров на разборщик, каждый раз одни и те же; для долгой охоты:
SUVEREN_FUZZ=20000 pytest tests/test_fuzz.py
Найденный пример Hypothesis сокращает до минимального и печатает. Его стоит сохранить отдельным
тестом рядом с исправлением, как test_a_broken_sitemap_line_in_robots_does_not_crash_the_scan.
Эталонный корпус. Проверки по страницам (152-ФЗ, согласие, вход через иностранные сервисы) ошибаются на реальной вёрстке, которой нет в fixtures. Поэтому реальные сайты можно записать один раз, байт в байт, и прогонять на них каждую правку офлайн:
python tests/golden.py record habr.com drom.ru # записать сайты в corpus/
pytest tests/test_corpus.py # упадёт и покажет разницу, если выводы изменились
python tests/golden.py update # принять новые выводы, если так и задумано
Корпус хранится только локально (corpus/ в .gitignore): это чужие страницы. Без него тест
пропускается.