Перейти к основному содержимому

Консоль модерации

Каждая версия каждого сета ждёт модератора, прежде чем попасть в каталог. Решение принимается в консоли. Она входит в бинарник b4hub, раздаётся по пути /admin с того же адреса, что и сам хаб, и доступна на английском и русском языках.

Консоль принадлежит хабу, а не зеркалу: у зеркала нет базы модерации, и оно не принимает решений, поэтому консоли у него нет. Разница описана в разделе Запуск хаба.

warning

Одну вещь консоль называет иначе, чем роутер. То, что роутер называет отчётом «работает» или «не работает», в консоли называется голосом. Жалоба называется жалобой в обоих местах. Дальше на этой странице используются слова самой консоли, чтобы названия совпадали с тем, что на экране.

Вход​

Пароль - это B4HUB_ADMIN_PASSWORD из окружения сервиса. Учётных записей и ролей нет; модератор - тот, у кого есть пароль.

СессияCookie в пределах /admin, действует семь дней
Смена пароляСразу завершает все открытые сессии
Попытки входаДесять с адреса за каждые пятнадцать минут, верных и неверных, дальше отказ с указанием времени
Откуда принимаются действияИз самой консоли; запрос на модерацию, пришедший не из неё, отклоняется
к сведению

Cookie помечается как secure, когда запрос пришёл по TLS или нёс заголовок X-Forwarded-Proto: https, который должен выставлять обратный прокси.

Без заданного пароля консоль открывается, но не работает: на странице входа написано, что модерация не настроена, а вход и любое действие модератора отклоняются. Тогда модерировать можно только командой b4hub moderate на хосте, как описано в конце страницы.

Страницы​

СтраницаДля чего
ОбзорЧто требует внимания, что опубликовано и что представляет собой этот хаб
ОчередьВерсии, ждущие решения
СетыВсё решённое: в каталоге, устаревшие, не публикуемые, скрытые и отклонённые
КлючиУчастники, которых видел хаб, их активность и отметки на них
ЗеркалаХабы, объявившие себя зеркалами этого, и их состояние
ОтзывыВсе голоса с весом, который они несут, и входящие жалобы
КаталогОпубликованные файлы, история сборок и операции, которые публикуют заново
СтатистикаАктивность по дням, распределение опубликованных оценок и откуда приходят голоса
ЖурналКаждое действие на хабе: кто и когда его выполнил
НастройкиСуточные и часовые лимиты, сохранённые причины и уведомления

На пунктах меню показаны счётчики: ждущие версии у Очереди, опубликованные сеты, требующие внимания, у Сетов, ждущие зеркала у Зеркал и открытые жалобы у Отзывов. Заголовок вкладки браузера начинается с числа ждущих версий, а цветная точка у Обзора показывает самую серьёзную из открытых проблем.

Сет или ключ, названный в любом месте консоли, - это ссылка. Она открывает боковую панель со своим адресом, /admin/sets/<id>, /admin/sets/<id>/v/<версия> или /admin/keys/<hmac>, поверх страницы, с которой её открыли; кнопка «назад» в браузере её закрывает, а адрес можно передать или сохранить в закладках. Поиск, фильтры, сортировка и страница списков тоже хранятся в адресе.

Каждое действие сообщает, что сделало, уведомлением с формулировкой самого хаба, например approved 01J9.../2.

Публикация​

Решение меняет базу сразу. Каталог, который скачивают роутеры, пересобирается в фоне: сборка начинается через 1,5 секунды после последнего изменения и не позже чем через 10 секунд после первого, так что серия решений заканчивается одной сборкой. Ничто не ждёт сборку, а неудачная сборка не отменяет решение.

Состояние публикации видно на двух страницах:

ГдеЧто показывает
Обзор, карточка КаталогКаталог совпадает с базой или Есть изменения для следующей сборки, пока в базе есть изменения, которые ещё не опубликованы
Обзор, СостояниеПоследняя сборка не удалась, с текстом ошибки
Каталог, Опубликованный каталогТо же, что на карточке Каталог, а также время и текст ошибки неудачной сборки
Каталог, История сборокКаждая сборка, почему она запускалась, её результат и что она изменила

Неудачная сборка остаётся на обеих страницах, пока какая-нибудь сборка не пройдёт успешно, а у роутеров тем временем остаётся предыдущий каталог. Собрать сейчас на странице «Каталог» ставит в очередь новую сборку. Консоль опрашивает состояние сборки и, когда сборка завершается, заново загружает каталог, раздел «Состояние», историю сборок, зеркала, сеты и счётчики в меню.

Обзор​

Первым идёт Состояние - список того, что требует внимания, у каждого пункта ссылка на страницу, где это решается:

ПроблемаУровень
Каталог не опубликованошибка
Последняя сборка не удалась, с текстом ошибкиошибка
Манифест истекает в течение 2 днейошибка; в течение 7 дней - предупреждение
Успешной сборки не было дольше суток и двух интервалов проверкипредупреждение
Версия ждёт решения больше 72 часовпредупреждение
Одобренные зеркала не проходят проверку или отдают старый каталогпредупреждение
Зеркала ждут одобрениязаметка
Есть открытые жалобызаметка
На хабе работает сборка для разработки или сборка из дерева исходников с незакоммиченными изменениямизаметка

Под списком - факты, на которых он основан: когда истекает манифест, последняя успешная сборка, последняя ошибка сборки, версия, которая ждёт дольше всех, и сколько одобренных зеркал в манифесте, с ошибками или отстаёт.

Дальше четыре счётчика, каждый открывает свою страницу: ждущие версии, сеты в каталоге, ключи с числом заблокированных и зеркала с числом объявленных и ждущих. Каталог - то, что роутеры скачивают прямо сейчас: файл, эпоха и порядковый номер, когда он собран и когда истекает, сколько в нём сетов и файлов payload, сколько зеркал в нём указано и ждёт ли что-то следующей сборки. Этот хаб показывает версию, дерево исходников b4, из которого он собран, id ключа, публичный URL и число отозванных ключей. Модерация считает принятые решения.

Очередь​

По карточке на каждую ждущую версию, старые первыми; карточка устроена как карточка сета на странице Сеты роутера.

Полоса по верхнему краю разбита на сегменты по частям сета: Цели, Разделение, Фейки, Маршрут и DNS, а у блокирующего сета вместо сегмента Маршрут стоит Блок. Эскалация не передаётся в общем сете, поэтому сегмента для неё в полосе нет. Сегмент подсвечен, если сет настраивает эту часть, а щелчок по нему открывает её настройки под карточкой. Если карточек больше одной, Сравнить по сетам над ними открывает одну и ту же часть на всех карточках, а Свернуть всё и Развернуть всё закрывают и снова открывают то, что открыто.

Версия стоит в правом верхнем углу, v1 - первая версия нового сета. Её подсказка показывает id сета и версию и объясняет, что будет означать одобрение:

ПодсказкаЧто означает
Первая версия нового сетаНичего из этого сета не опубликовано
Новая версия сета, опубликованного как vNОдобрение заменит опубликованную
Новая версия сета, у которого сейчас ничего не опубликованоОдобрение вернёт сет в каталог
Старше опубликованной vNОдобрение ничего не изменит в каталоге: опубликованной остаётся самая новая активная версия. Версия обведена оранжевым

В строке под названием - автор, семейство техник, версия b4, которая нужна сету, и время получения версии. Её подсказка добавляет точное время, сеть, из которой хаб увидел загрузку, сеть, которую заявил отправитель, и версию b4 с движком захвата, из которых сет был отправлен. Дальше идут сводка целей и маршрут: маршрут по умолчанию, маршрут по умолчанию с DNS-пинами или блокировка с её действием. У сета, который не разбирается версией b4 этого хаба, полосы нет, а вместо маршрута стоит пояснение.

к сведению

Хаб никогда не хранит ключ участника. Он хранит, а консоль показывает как автора, HMAC этого ключа под собственным секретом хаба: 16 символов везде, где назван автор, полное значение - в панели ключа. Два сета одного участника несут одну и ту же метку; сам ключ из неё не восстановить.

Ниже идёт ряд отметок:

ОтметкаЧто означает
нужен payload, блокирует трафик, закрепляет адреса, только категории, шаблонФлаги, каждый объяснён в подсказке. блокирует трафик красный, только категории и шаблон оранжевые
автор заблокированПока блокировка не снята, из сета ничего не публикуется
сет снят с каталогаМодератор снял весь сет с каталога
изменёнВерсию изменил модератор. Подсказка показывает время и заметку, а щелчок сравнивает версию с полученным сетом
похожие сеты: N или похожие сеты не провереныУ хаба уже есть сеты, похожие на эту версию, или проверить это не удалось; щелчок открывает список или ошибку
открытые жалобы: NНа версию есть открытые жалобы; подсказка их считает, а щелчок открывает панель сета

В списке - сеты, которые уже есть у хаба, с теми же целями, той же стратегией, общими или перекрывающимися доменами, тем же или похожим названием или тем же автором, каждый со статусом, голосами и принятым решением. Те же цели или то же название, что у другого сета, означают вероятный дубликат, и отметка похожие сеты: N становится оранжевой. Отклонить как дубликат заполняет причину отклонения ссылкой на сет, который дублируется.

Щелчок по карточке или Открыть подробности в меню в её углу открывает панель сета на этой версии со всем, что содержит версия: сводка целей, стратегия, записанная предложениями, флаги, имена серверов в фейковых пакетах, пины, хост DoH, файлы payload с размерами и ссылками на скачивание, Голоса и Жалобы на неё, отпечаток и версия b4, которая нужна сету. Проекция раскрывает сет в виде JSON. Если опубликованная версия есть, Сравнить с опубликованной vN в том же меню показывает под карточкой построчную разницу между ней и ждущей. В меню также есть Заблокировать автора; Одобрить, Изменить, Отклонить и Скрыть - кнопки внизу карточки.

Решения​

ДействиеПричинаРезультат
Одобритьне нужнаВерсия становится активной и попадает в каталог при следующей сборке
ОтклонитьобязательнаВерсия отклоняется, причина записывается
Скрытьпо желаниюВерсия уходит из каталога при следующей сборке
Изменитьне нужнаОткрывает редактор в диалоге
Заблокировать авторапо желаниюСм. Блокировка ключа

Каждый диалог до подтверждения показывает, что будет с каталогом: какая версия в него попадёт, какую заменит, уйдёт ли сет из каталога или ничего не изменится. Если скрыть опубликованную версию, вместо неё публикуется самая новая из более старых активных версий; Также снять весь сет с каталога этого не допускает. Если на версию есть открытые жалобы, диалог говорит, сколько из них будет отклонено или отмечено обработанными, а Оставить открытые жалобы открытыми оставляет их как есть.

Одобрение версии сета, снятого с каталога, или версии заблокированного автора требует второго подтверждения: версия становится активной, но остаётся вне каталога, пока сет не вернут или блокировку не снимут.

к сведению

Причина отклонения записывается на хабе и читается в этой консоли. Каталог несёт только одобренные версии, поэтому до автора причина не доходит: его роутер лишь сообщает, что сета нет в каталоге.

Отклонение и скрытие говорят о разном. Отклонение - вердикт по присланному. Скрытие выводит из оборота, не требуя новой версии, и скрытая версия продолжает считаться дубликатом для последующих отправок с той же стратегией.

Несколько сразу​

Флажок на каждой карточке или Выбрать все собирают версии для одного решения. Диалог пакетного действия показывает, что будет с каталогом для каждой выбранной версии, и называет те, к которым действие неприменимо, например версию, которая уже не ждёт решения; они пропускаются, а остальные меняются вместе, в одной транзакции, за которой следует одна сборка. Пакетное действие принимает не больше 200 версий.

Сохранённые причины​

Каждый диалог, где спрашивается причина, предлагает сохранённые для этого действия причины в виде чипов, самые используемые первыми. Введённую причину можно сохранить кнопкой Сохранить как шаблон. Список правится в Настройках, отдельно для каждого действия: отклонения и скрытия версии, снятия сета, блокировки ключа, отклонения зеркала и отклонения жалобы.

Правка ждущей версии​

Присланное с хорошей стратегией и неудачными целями можно исправить, а не отклонять. Редактор открывается только на ждущей версии: как только версия попала в каталог, отклонена или скрыта, у неё можно изменить лишь название и описание, как описано ниже.

В диалоге есть Название, Описание, Цели и Заметка модератора. У каждого вида целей своё поле:

ПолеЧто принимает
ДоменыПо одной записи в строке
АдресаIP-адреса и диапазоны CIDR, по одной записи в строке или через запятые и пробелы
ASNПо одной записи в строке, в виде AS13335 или 13335; правильная запись сохраняется как число
Категории geosite, Категории GeoIPИмена из файлов geosite и GeoIP самого хаба или введённые вручную; каждый роутер ищет их в своём файле
Версия TLSЛюбая, TLS 1.2 или TLS 1.3
Версия IPЛюбая, IPv4 или IPv6
Только по доменуДомены сопоставляются только по имени из хендшейка и никогда по их IP-адресу

Показать полный JSON сета открывает всё, что несёт сет, одним JSON-документом; там меняются настройки вне этих полей. Поля и JSON держатся в согласии: правка поля переписывает в JSON только его ключ, а правка JSON заново заполняет поля. Пока JSON некорректен, поля целей заблокированы.

к сведению

Описание - единственное поле, которое кнопка публикации на роутере оставляет пустым. Обычно сет приходит с именем в качестве названия и без описания, хотя точка входа /api/hub/share на роутере описание принимает, а хаб его сохраняет; поэтому описание на карточке либо пришло с публикацией, либо написано здесь.

Проверить прогоняет присланное через те же проверки, что и свежую публикацию, и отвечает одним из трёх вердиктов:

ВердиктЧто означает
Ничего не отличается от текущей версииПравка пустая, сохранение отклоняется
Отличаются только цели, название или описаниеОтпечаток не меняется, поэтому уже записанные голоса продолжают считаться
Стратегия отличается от присланной авторомОтпечаток меняется, голоса этой версии удаляются, и опубликованный сет перестаёт совпадать с копией автора

Результат, дублирующий сет, который у хаба уже есть, отклоняется сразу, с указанием этого сета. Проверка сообщает и о смене версии b4, которая нужна сету, и о каждом флаге, который правка добавляет или снимает; новый флаг блокирует трафик, шаблон или только категории превращает это сообщение в предупреждение.

Проверка также сообщает, что сделала очистка. Предупреждение, которое касается одного поля, стоит под этим полем:

ПолеПредупреждения
ДоменыЗаписи, кроме шаблонов regexp:, в которых есть пробел, запятая или точка с запятой и которые поэтому ни с чем не совпадают, домены, похожие на внутренние, слишком много доменов, блокирующий сет с сопоставлением по шаблону, пин, отброшенный потому, что его домена нет в целях или он указывает на внутренний адрес
АдресаАдреса, похожие на внутренние, записи, которые не являются ни IP-адресом, ни диапазоном CIDR и которые роутеры пропускают, диапазон /0, покрывающий все адреса, слишком много адресов
ASNСлишком много ASN, значения, которых b4 не принимает
Категории geosite, Категории GeoIPИмена, которых нет в файле самого хаба; у автора может быть другой источник

Предупреждения проверки перечисляют остальное: поля, которых b4 не знает, другие значения, которых он не принимает, хост DoH вне публичного списка, пины, отсутствующий payload. Отброшенные поля перечисляют то, что вообще не переносится общим сетом, с причиной. Адреса, категории и ASN, а также пробелы, запятые и точки с запятой в записях доменов проверяются по мере ввода; после проверки вердикт хаба заменяет эти пометки у каждого поля, которое с тех пор не менялось.

Если проверка отклоняет сет, Проверка отклонила сет: перечисляет каждую причину с её полем, а под полем цели та же причина видна красным, например ASN, который не является публичным номером AS.

Проверки списка доменов​

Синтаксиса со звёздочкой в b4 нет, а обычная запись и так покрывает все поддомены. Под полем Домены редактор отмечает четыре способа ошибиться в списке, а Применить предложения переписывает его одним действием.

ПроверкаПримерЧто предлагается
Запись, которая никогда не совпадёт*.example.comЗаменить на example.com или убрать, если он уже в списке
Запись www. без доменаодин www.example.comЗаменить на example.com, который покрывает оба. Другие поддомены не отмечаются
ПовторExample.com. после example.comУбрать
Запись, уже покрытая другойcdn.example.com рядом с example.comУбрать

Запись regexp: никогда не считается покрывающей что-либо и никогда не отмечается как покрытая; единственная проверка, которая её касается, - проверка на повтор, убирающая один и тот же шаблон, указанный дважды.

Что изменит сохранение, последняя часть результата проверки, сравнивает изменённый сет с версией в её нынешнем виде, поле за полем, со строкой на каждую добавленную или убранную запись списка.

Сохранить оставляет версию ждущей. Сохранить и одобрить одобряет её в той же транзакции. Обе кнопки недоступны, пока проверка текущего содержимого не покажет изменение и отсутствие дубликата, и ни одна не примет сет, у которого нет ни домена, ни адреса, ни ASN, ни категории или есть версия TLS или IP, которой b4 не знает. Обе записывают заметку модератора, видимую только в консоли, и сохраняют присланное, чтобы карточка в очереди и панель сета могли показать, что было изменено; запись в журнале также перечисляет добавленные и убранные цели и версию b4, которая нужна сету, если она сменилась. Версия, которую кто-то изменил после открытия диалога, не перезаписывается, а отклоняется.

Правка текста опубликованной версии​

Изменить название на любой версии вне очереди меняет её название и описание и больше ничего. Стратегия, цели, отпечаток и номер версии остаются прежними, поэтому роутеры не видят новой версии, а голоса продолжают считаться. Каталог несёт новый текст со следующей сборки: роутеры, которые уже применили сет, сохраняют своё имя, а новые получают новое название. Название обязательно и ограничено 120 символами, описание - 2000.

Сеты​

Пять вкладок:

ВкладкаЧто на ней
В каталогеВерсия каждого сета, которая сейчас в каталоге
УстаревшиеБолее старые одобренные версии, которые ещё хранятся, с версией, которая их заменила
Не публикуютсяСеты, целиком убранные из каталога, потому что их сняли или их автор заблокирован, с причиной
СкрытыеСкрытые версии с причиной; скрытые по жалобам и ещё не разобранные помечены
ОтклонённыеОтклонённые версии с причиной

Каждая вкладка показывает сеты карточками, как в очереди, и постранично загружается с хаба, по 25, 50, 100 или 200 сетов на странице. Сортировка упорядочивает их по пунктам Последнее обновление, Дата получения, Название, Автор, Оценка, Вес голосов, Устройства или Жалобы, а стрелка рядом меняет направление; на вкладках Скрытые и Отклонённые оценки нет, поэтому пунктов Оценка, Вес голосов и Устройства там нет. Поиск находит название, описание, id сета, метку и HMAC автора, семейство и коды техник, причину решения, каждый целевой домен, каждую категорию geosite и каждый ASN в виде AS15169.

У карточки, как и в очереди, есть полоса частей сета, версия, название, цели и маршрут, а кроме того:

ЧастьЧто показывает
Версияid сета и версия в подсказке, а на вкладке В каталоге ещё и все активные версии, если их больше одной
Строка под названиемАвтор, семейство техник и время последнего изменения версии. Подсказка добавляет имя и метку автора, метку, которую видят роутеры, доверен ли ключ или заблокирован, сеть, из которой пришла загрузка, и время получения и обновления версии
Строка под маршрутомЗаменён версией vN со временем или причина, по которой версия скрыта, отклонена или не публикуется
ОтметкиФлаги, автор заблокирован, сет снят с каталога, скрыта до одобрения, изменён, отметки внимания и жалобы
ОценкаОценка, которую роутеры получили в последней сборке, а у версии, которую эта сборка не публиковала, например на вкладках Устаревшие и Не публикуются, - оценка на текущий момент: зелёная от 70%, оранжевая от 40% и красная ниже, или без оценки. Если следующая сборка изменит опубликованную оценку, за ней идёт далее: с текущим значением. Дальше независимые голоса «работает» и «не работает». В подсказках взвешенные голоса и устройства за каждой цифрой, голоса самого автора и сколько других сетов делят голоса этой стратегии. На вкладках Скрытые и Отклонённые не показывается

Три переключателя сужают список: С открытыми жалобами, Изменённые и, на вкладке В каталоге, Требуют внимания. Отметки внимания на опубликованном сете - сигнал только для консоли, роутеры по-прежнему видят сет:

ОтметкаКогда
низкая оценкаНе меньше 3 взвешенных голосов и оценка ниже 30%
устарел60 дней без голосов, и вес почти не остался
ниже 50%Независимых голосов достаточно для оценки, и она ниже 50%
открытые жалобыНа опубликованную версию есть открытые жалобы

На карточке они сводятся в одну отметку, которая называет самую серьёзную и добавляет +N за остальные; подсказка перечисляет все. Открытые жалобы показывает отдельная отметка жалоб: открытые жалобы: N, ждёт проверки у версии, скрытой по жалобам, на которую ещё есть открытые, или жалобы: N, когда все жалобы разобраны. Щелчок по ней открывает панель сета.

На вкладках, где это применимо, карточки можно выбрать для пакетного действия, по одной или все на странице кнопкой Выбрать все: скрыть опубликованные и устаревшие версии, вернуть скрытые и одобрить отклонённые.

Карточка открывает панель сета на своей версии. В панели все версии сета, у каждой статус, факты и действия, которые допускает её статус. Скрытую версию можно вернуть, а отклонённую - всё-таки одобрить. В панели также все голоса за сет и его История: каждое действие над сетом, кто его выполнил и с какой причиной. В меню в углу карточки есть Открыть подробности, которое открывает ту же панель, и Открыть ключ автора.

Снятие сета с каталога​

Снять сет в панели убирает весь сет из каталога при следующей сборке, каким бы ни был статус его версий. Версии сохраняют свои статусы, поэтому Вернуть в каталог возвращает ровно то, что было опубликовано. Снятие отмечает открытые жалобы на сет обработанными. Новая версия снятого сета по-прежнему принимается и ждёт в очереди, как любая другая.

осторожно

Удалить навсегда внизу панели удаляет сет со всеми версиями, голосами, жалобами и файлами payload, которые не использует другой сет. Для подтверждения нужно ввести id сета. Убрать сет из каталога можно снятием; удаление - для записи, которой не должно было быть. Роутеры, применившие сет, сохраняют свою копию и теряют связь с хабом.

Ключи​

По строке на каждого участника, которого видел хаб, по HMAC, с временем первого и последнего появления, числом подписанных им сетов, голосов и жалоб и сетью последней записи. Поиск принимает начало HMAC, имя, заметку или собственный id ключа роутера, который хаб переводит в HMAC. Фильтры сужают список по статусу (заблокирован, доверенный, ни то ни другое), по метке и по сетам (любые, в каталоге, ждущие, нет).

Строка открывает панель ключа:

РазделЧто в нём
АктивностьОтправки, голоса, жалобы и объявления зеркал по дням за последние 90 дней
СетыКаждый отправленный ключом сет, с его статусом и жалобами на него
ГолосаГолоса ключа с весом каждого
Отправленные жалобыЖалобы, которые подал ключ, и их состояние
СетиСети, из которых приходили его записи
Версии b4Версии b4 и движки захвата, о которых он сообщал
Объявленные им зеркалаЗеркала, которые он объявил
ИсторияКаждое действие над ключом

Заметки оператора добавляют имя, которое везде в консоли показывается вместо начала HMAC, свободную заметку и метку:

МеткаДействие
свойТолько метка; голоса ключа учитываются как обычно
тестГолоса ключа перестают учитываться в опубликованных оценках со следующей сборки, его жалобы - в автоматическом скрытии, а его активность не попадает в статистику
ДействиеРезультат
ЗаблокироватьСм. ниже
РазблокироватьКлюч снова принимается; его сеты возвращаются при следующей сборке, голоса и жалобы снова учитываются
ДоверятьКлюч перестаёт учитываться в суточных лимитах на ключ
Снять довериеСнова учитывается
к сведению

Доверие снимает лимиты и ничего больше. Сеты доверенного участника ждут модератора, как и все остальные, а лимиты на сеть продолжают действовать.

Блокировка ключа​

Блокировка - обратимый карантин. С момента блокировки:

  • каждая новая запись, подписанная ключом, отклоняется;
  • при следующей сборке его сеты уходят из каталога на вкладку Не публикуются;
  • его голоса перестают учитываться в опубликованных оценках, а жалобы - в автоматическом скрытии;
  • его ждущие версии можно одобрить только со вторым подтверждением, и пока блокировка действует, они остаются вне каталога.

Ничего не удаляется, и разблокировка возвращает всё. До подтверждения диалог блокировки считает, что затронет блокировка: сеты в каталоге, ждущие версии, голоса и стратегии, в которые они идут, и открытые жалобы. Он также называет зеркала, объявленные ключом; блокировка оставляет их в манифесте, а убирает их отклонение на странице «Зеркала».

Зеркала​

Все хабы, объявившие себя зеркалами этого, ждущие первыми, в столбцах Зеркало, Статус, Проверка, Отдаёт и, на широком экране, Последнее объявление. Зеркало - это URL, который открывает зеркало в новой вкладке, а под ним версия b4hub из последнего объявления зеркала и ключ, которым оно объявлено. Подробности каждого столбца - в его подсказках. Статус объединяет решение с тем, что делает с зеркалом манифест:

СтатусЧто означает
ожидаетЖдёт решения
отклоненоНикогда не объявляется; причина в подсказке
в манифестеОдобрено и есть в манифесте
добавляетсяОдобрено и попадёт в манифест при следующей сборке
уходитУйдёт из манифеста при следующей сборке
остаётсяНе проходит проверку, но остаётся в манифесте, пока ни одно зеркало не проходит проверку
нет в манифестеОдобрено и попадёт в манифест после следующей успешной проверки

Проверка - результат последней проверки состояния: ок или сбой с тем, как давно она была, или ещё не проверялось.

ДействиеРезультат
ОдобритьСразу запускается проверка, и зеркало попадает в манифест, как только проверка пройдена
ОтклонитьОстаётся в списке с причиной и никогда не объявляется. Причина обязательна
УдалитьЗабывается и может объявить себя снова
Проверить сейчасПроверяет одно зеркало; Проверить все - все одобренные

Хаб проверяет каждое одобренное зеркало раз в 10 минут и ещё раз перед первой сборкой после запуска. Проверка запрашивает у зеркала адрес состояния и манифест и убеждается, что манифест подписан этим хабом; подсказка неудачной проверки называет шаг, на котором произошёл сбой. Одобренное зеркало остаётся в манифесте 24 часа после последней успешной проверки, и подсказка его статуса показывает, когда оно выпадет без новой. Если сбой у всех одобренных зеркал сразу, зеркала из предыдущего манифеста остаются в нём, пока одно из них снова не пройдёт проверку или модератор их не отклонит или не удалит; их статус - остаётся, а времени выпадения нет. Если после очередного круга проверок меняется набор зеркал, которые следует объявлять, запрашивается сборка.

Столбец Отдаёт сравнивает каталог, который был у зеркала при последней проверке, с каталогом этого хаба: актуально, отстаёт на сколько-то номеров, устарело, если отставание держится 15 минут после публикации нового каталога или у зеркала старая эпоха, или новее этого хаба. Подсказка называет манифест, который отдавало зеркало.

Отзывы​

Две вкладки.

Голоса - все голоса, новые первыми, более старые подгружаются по запросу. В строке: когда пришёл голос, сет и версия, вид, сеть, которую увидел хаб, и сеть, которую заявил роутер, участник, домен, по которому был отфильтрован список, версия b4 и движок, и вес голоса. Фильтры сужают список по «работает» или «не работает», по тому, голосует ли автор сета, по известной или неизвестной сети, а также полями ASN и Страна, значения которых выбираются из сетей и стран, откуда приходили голоса, с общим числом голосов у каждого; выбранная страна оставляет в списке ASN только сети, у которых есть голоса из неё, и сбрасывает выбранный ASN, у которого таких голосов нет. Ссылка на сет или ключ добавляет фильтр по нему.

Столбец веса показывает, что голос вносит в опубликованную оценку: базовый вес, множители за сеть, молодой ключ и давность и итог на момент последней сборки. Если голос не учитывается, указано почему: ни один опубликованный сет не использует его стратегию, голос пришёл после последней сборки, ключ заблокирован или помечен как тестовый, или автоматические голоса перевесили бы ручные.

Виды голосов - «работает» и «не работает», поданные вручную, загрузка, которая засчитывается автору как «работает», и те, которые роутер мог бы отправлять сам из детектора DPI, watchdog доменов и Дискавери. Эти автоматические виды хаб определяет и взвешивает, но b4 их пока не отправляет.

Жалобы - входящие с тремя состояниями:

СостояниеЧто означает
открытаЖдёт модератора; учитывается в автоматическом скрытии
отклоненаПризнана необоснованной
обработанаПо ней приняты меры

У каждой жалобы время, сет и версия, сеть, участник, введённая причина и учитывается ли она. Отклонить и Обработана принимают необязательную заметку и применяются к одной жалобе или к выбранным; Открыть снова возвращает жалобу во входящие. Скрытие, отклонение, возврат и снятие сета закрывают открытые жалобы на то, что они затрагивают, и записывают причину.

к сведению

Опубликованная версия скрывается автоматически, когда на неё набирается три открытые жалобы от независимых ключей и сетей. Жалоба учитывается, только пока она открыта, если её сеть известна, а её ключ не заблокирован и не помечен как тест. У жалобы, которую одобренное зеркало передало с верной подписью пересылки, сеть неизвестна, поэтому она не учитывается никогда. Возврат версии отклоняет её открытые жалобы, поэтому счёт начинается с нуля.

Каталог​

Опубликованные файлы, зеркала в манифесте, ключ, которым подписывает этот хаб, и ключи, которые манифест отзывает.

История сборок записывает каждую сборку: когда и почему она запускалась, удалась ли, порядковый номер, число сетов, сколько она длилась и что изменилось в каталоге: сеты добавлены, убраны, получили новую версию, новый текст или новую оценку, изменился список зеркал или отозванных ключей. Сборка, изменившая только оценки, так и отмечается. Список можно сузить до изменений и сбоев или только до сбоев.

Три операции, каждая публикует заново:

ОперацияЧто делает
Собрать сейчасСтавит в очередь сборку, которая публикует из базы, даже если ничего не менялось
Начать новую эпохуСбрасывает порядковый номер. Каждый роутер считает новую эпоху главной и скачивает каталог заново
Отозвать ключ подписи хабаДобавляет id ключа в список, который несёт каждый манифест. Роутеры перестают доверять всему, что им подписано

Сборка отклоняется, а причина видна в истории сборок, в двух случаях: когда её эпоха и порядковый номер не окажутся больше уже опубликованного каталога или каталога, который отдаёт одобренное зеркало, - так выглядит база, восстановленная из старой резервной копии, - и когда база, ещё ни разу не публиковавшая каталог, заменила бы опубликованный каталог или подписала бы пустой ключом, встроенным в b4. Второй случай подтверждает флаг --new-database у serve или build.

warning

Новая эпоха нужна, чтобы опубликовать каталог после восстановления базы из старой резервной копии: всё, что старше уже имеющегося у них, роутеры отклоняют, а хаб отказывается такое собирать, пока эпоха не сменится. В остальных случаях она лишь заставляет каждый роутер заново скачать каталог.

осторожно

Роутеры хранят каждый отзыв навсегда; если позже убрать ключ из списка хаба, отзыв не отменится. Хаб отказывается отзывать ключ, которым сам подписывает, а для отзыва ключа, встроенного в b4, нужно отдельное подтверждение, потому что это отрезает все роутеры, доверяющие этому ключу.

к сведению

Отзыв и блокировка - разные инструменты. Отзыв называет ключ подписи хаба или зеркала и через манифест доходит до каждого роутера. Блокировка называет участника и влияет только на то, что этот хаб принимает и учитывает.

Статистика​

Счётчики за последние 7, 30, 90 или 365 дней, по дням UTC. Ключи с меткой тест не учитываются нигде на этой странице.

РазделЧто показывает
ИтогиОтправки с числом дубликатов, голоса «работает» и «не работает», новые ключи, жалобы и скрытые по ним сеты
АктивностьОтправки, дубликаты и новые ключи по дням; голоса «работает», «не работает» и жалобы по дням
Модерация и публикацияОдобрения, отклонения, скрытия, автоматические скрытия и снятия по дням; сборки, неудачные сборки и объявления зеркал по дням
Опубликованные оценкиГлобальная оценка каждого сета текущего каталога в десяти интервалах, отдельно сеты с голосами хотя бы с двух устройств и остальные; медиана и сколько сетов с отметкой низкой оценки или устаревания
Сеты с наибольшим числом голосовСеты, за которые проголосовало больше всего ключей за период
Откуда приходят голосаГолоса и ключи по странам и по сетям, по адресу, с которого пришёл голос, кроме голосов, переданных одобренным зеркалом с верной подписью пересылки, у которых сети нет; и ключи по версии b4 и движку их последней записи

Журнал​

Каждое действие на хабе записывается со временем, исполнителем, объектом, причиной и изменёнными полями. Исполнитель - консоль, вход по паролю (basic-аутентификация вместо сессии), командная строка или автоматически, например автоматическое скрытие; у записей консоли и входа по паролю есть ещё адрес, с которого пришёл запрос.

Журнал фильтруется по виду объекта, по исполнителю и по точному id объекта, более старые записи подгружаются по запросу. Действия, выполненные вместе в пакетном диалоге, помечены пакет, и по этой отметке показывается весь пакет. Та же история есть в панели каждого сета и каждого ключа.

Настройки​

Шесть лимитов, каждый - целое число от 1 до 1000000, применяются со следующего запроса; то, что ключ уже израсходовал сегодня, сохраняется.

ЛимитПериодПо умолчанию
Сетов на ключсутки5
Голосов на ключсутки20
Жалоб на ключсутки20
Объявлений зеркал на ключсутки48
Новых ключей на сетьсутки5
Запросов на сетьчас2000

Сутки - календарный день UTC, час - часовой интервал, поэтому лимит, исчерпанный в 22:00 UTC, сбрасывается в полночь. Счётчики хранятся в памяти и обнуляются при перезапуске сервиса. Сеть здесь - /24 отправителя, для IPv6 - /48.

Запись, которую хаб отклонил, и отправленный сет, оказавшийся дубликатом уже имеющегося, не расходуют квоту участника. Ключ, отмеченный как доверенный, не учитывается в лимитах на ключ, но учитывается в лимитах на сеть.

к сведению

Что видит роутер, упёршись в один из лимитов, описано в разделе Отчёты и жалобы.

Сохранённые причины хранят готовые причины, которые предлагаются в диалогах решений, отдельный список на каждый вид действия, у каждой короткая метка, текст и число использований.

Уведомления​

Хаб может отправлять сводку о поступившем в чат Telegram, на webhook или туда и туда.

КаналНастройки
TelegramТокен бота и id чата: число или @имя публичного канала. Бот должен состоять в чате
WebhookURL, https:// или обычный http:// к loopback или частному адресу, и необязательный секрет для подписи

Каждую настройку можно задать и в окружении сервиса, B4HUB_TELEGRAM_TOKEN, B4HUB_TELEGRAM_CHAT, B4HUB_WEBHOOK_URL и B4HUB_WEBHOOK_SECRET; значение оттуда важнее консоли, и она показывает такое поле только для чтения. Значения, введённые в консоли, хранятся зашифрованными ключом, выведенным из файла secret хаба, и никогда не отправляются обратно в браузер: страница показывает лишь, что значение сохранено, с id бота или схемой и хостом URL.

СобытиеКогда отправляется
Новые сеты в очередиОтправка принята и ждёт решения
ЖалобыЖалоба принята
Скрыто по жалобамОпубликованная версия скрыта автоматически
Неудачные сборкиСборка каталога завершилась ошибкой, с текстом ошибки
Новые зеркалаЗеркало объявило о себе и ждёт одобрения

До первого сохранения настроек выбраны новые сеты и жалобы. Отправки и жалобы от ключей с меткой тест не пересылаются.

Первое событие после затишья уходит сразу, следующие собираются не чаще одного сообщения за интервал сводки: по умолчанию 60 секунд, допустимо от 30 до 3600. Сообщение считает события каждого вида, перечисляет до десяти событий каждого, заканчивается ссылкой на страницу консоли, где они разбираются, и пишется на английском или русском. Включение канала или события не пересылает то, что пришло раньше.

Неудачная доставка повторяется с растущей задержкой, от 30 секунд до 30 минут, с учётом Retry-After; пока доставка не удаётся, ничего не теряется, потому что каждый канал хранит свою позицию в потоке событий. Для каждого канала видно, когда он последний раз доставил сообщение, сколько отправил и последнюю ошибку, пока сбои продолжаются. Отправить тест доставляет тестовое сообщение через сохранённый канал, включён он или нет.

Webhook получает POST с телом в JSON:

{
"hub": "https://hub.example",
"sent_at": "2026-09-27T12:41:15Z",
"counts": { "share": 2, "report": 1 },
"events": [
{ "kind": "share", "at": "2026-09-27T12:40:58Z", "set_id": "01J9...", "version": 1, "title": "Example", "author": "70837b639d58b777", "asn": "12389", "country": "RU", "url": "https://hub.example/admin/sets/01J9.../v/1" }
],
"more": 0,
"console": "https://hub.example/admin/queue"
}

Каждый запрос несёт X-B4hub-Timestamp - Unix-время отправки. Если задан секрет, есть и X-B4hub-Signature: sha256=<hex> - HMAC-SHA256 под секретом от времени, точки и тела запроса как есть. Перенаправления не выполняются, а любой статус вне 2xx считается сбоем.

Без консоли​

b4hub moderate делает из командной строки то же, что и консоль, через те же проверки и с теми же записями в журнале. Команда открывает ту же базу напрямую, в режиме WAL с таймаутом ожидания, поэтому сервис может продолжать работать. Сама она ничего не публикует: каждое изменение оставляет запрос на сборку, который запущенный b4hub serve подхватывает примерно за десять секунд.

КомандыЧто делают
list, approve, reject, hide, restoreОчередь и решения по версиям. Сет указывается как <id> или <id>/<версия>; можно указать несколько сразу, и approve применяется ко всем или ни к одному
withdraw, reinstate, deleteСеты целиком. delete требует --confirm <id>
ban, unban, trust, untrustКлючи, по HMAC
reports, dismiss-report, resolve-report, reopen-reportВходящие жалобы
mirrors, approve-mirror, reject-mirror, remove-mirror, check-mirrorЗеркала
status, builds, epoch, revokeПубликация, история сборок, новая эпоха и отзыв ключа подписи хаба с --confirm <key_id>
auditЖурнал

Правка версии, имени, заметки и метки ключа, сохранённые причины, уведомления и лимиты доступны только в консоли.