Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
AA Discord Audit — Аудит согласования интеграции Discord с Alliance Auth: находит участников гильдии, имеющих управляемые AA роли, которые не были назначены Auth, и удаляет или исключает их в соответствии с политикой, контролируемой оператором. Самостоятельное Django-приложение для сообщества. | Kitploit
Инструменты/GitLabGitLab/eveo7/aa-discord-audit
Оборонительные ИнструментыАудит конфигурацииУправление идентификацией и доступом (IAM)Реагирование на Инциденты
GitLabeveo7/aa-discord-audit

AA Discord Audit

Аудит согласования интеграции Discord с Alliance Auth: находит участников гильдии, имеющих управляемые AA роли, которые не были назначены Auth, и удаляет или исключает их в соответствии с политикой, контролируемой оператором. Самостоятельное Django-приложение для сообщества.

Репозиторий
492 месяцев назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

aa-discord-audit

PyPI version Supported Python versions License: MIT

Сверочный аудит интеграции Alliance Auth с Discord. Сравнивает фактические назначения ролей в настроенной гильдии Discord с тем состоянием, которое отражено в Alliance Auth (группы и состояние каждого пользователя), и закрывает лазейку, через которую модераторы могут вручную выдавать роли с именами AA пользователям, о которых AA ничего не знает.

Статус: alpha (0.1.x). Публичный API и настройки могут ещё измениться до 1.0.

Содержание

  • Безопасность по умолчанию
  • Как это работает
  • Требования
  • Установка
  • Быстрый старт
  • Права
  • Настройки
  • Команды управления
  • Периодический аудит (Celery beat)
  • Задачи Celery
  • Панель оператора
  • Наблюдаемость
  • Ограничения
  • Документация
  • Разработка

Безопасность по умолчанию

Аудит безопасен по умолчанию:

  • Самый первый прогон после установки принудительно идёт в режиме «только отчёт», независимо от настроек оператора. Снятие блокировки требует отдельной записи InitialAuditAcknowledgement и доступа в админку или к shell.
  • По умолчанию в каждой категории стоит действие report; разрушительные действия включаются явно.
  • Записи журнала (AuditRun, AuditFinding, AuditInvocation, ConfigChangeLog) защищены от обновлений на уровне менеджера и экземпляра модели — массовые update() и bulk_update() заблокированы.
  • Адрес вебхука считается секретом и затирается в журналах, в сообщениях об ошибках и в сохранённой строке аргументов команды.

Как это работает

Каждый участник гильдии относится к одной из трёх категорий:

КатегорияЗначение
unknown_guestУчастник, о котором AA ничего не знает
linked_no_permЛичность известна AA, но нет права discord.access_discord
bot_filteredУчтённый бот — с ним аудит не делает ничего

Оператор для каждой категории выбирает действие:

ДействиеПоведение
reportТолько зафиксировать находку, без изменений в Discord
stripСнять роли с именами AA
strip_kickСнять роли с именами AA, затем удалить из гильдии

Соответствие задаётся настройкой AA_DISCORD_AUDIT_POLICY. Для каждой категории можно указать переопределения по группе и по состоянию пользователя AA.

Требования

  • Python 3.10–3.13
  • Django 4.2 или 5.2
  • Alliance Auth 4.x или 5.x
  • Discord-сервис-модуль Alliance Auth (allianceauth.services.modules.discord) установлен и настроен (токен бота + гильдия)

Установка

root@kitploit:~
pip install aa-discord-audit

В local.py Alliance Auth:

root@kitploit:~
# `aa_discord_audit` обязан идти ПОСЛЕ
# `allianceauth.services.modules.discord`, чтобы модели discord-модуля
# загрузились первыми; иначе `apps.ready()` поднимет
# `ImproperlyConfigured`.
INSTALLED_APPS += ["aa_discord_audit"]

MIDDLEWARE += [
    "aa_discord_audit.current_user.CurrentUserMiddleware",
]

Затем миграции:

root@kitploit:~
python manage.py migrate aa_discord_audit

CurrentUserMiddleware обязателен — apps.ready() поднимает ImproperlyConfigured, если его нет в MIDDLEWARE. Без него обработчик сигналов ConfigChangeLog не может определить автора правки в админке, и каждое изменение пишется на безличного <system>.

Быстрый старт

  1. Выдайте право aa_discord_audit.run_audit тому, кто будет запускать аудит.

  2. Запустите аудит в режиме отчёта:

    root@kitploit:~
    python manage.py audit_discord_roles --action report
    
  3. Посмотрите находки в разделе Discord Audit → Прогоны аудита на панели Alliance Auth.

  4. Снимите блокировку первого прогона — либо создайте в админке запись InitialAuditAcknowledgement, либо выполните python manage.py audit_acknowledge_initial. И то и другое требует aa_discord_audit.run_audit и aa_discord_audit.acknowledge_initial_audit.

  5. Когда готовы — перезапустите с нужным разрушительным действием.

Права

Группа прав manage_* намеренно разнесена по таблицам — сотрудник, которому выдан только manage_bot_account_uid, не сможет одновременно подменить ManagedRoleException и обезвредить аудит.

Настройки

Все настройки необязательные; значения по умолчанию подобраны безопасно.

root@kitploit:~
# Политика действий. Краткая форма ниже эквивалентна
# {"default": "<действие>"}; для переопределений по группе и по
# состоянию AA-пользователя используется развёрнутая форма.
AA_DISCORD_AUDIT_POLICY = {
    "unknown_guest":  "report",
    "linked_no_perm": "report",
    # "linked_no_perm": {
    #     "default":  "strip",
    #     "by_state": {"Guest": "report"},
    #     "by_group": {"Directors": "report"},
    # },
}

# Рассылка уведомлений через AA-notify обладателям прав.
AA_DISCORD_AUDIT_NOTIFY_ADMINS = True

# Адрес вебхука Discord для итогов запуска. Считайте его секретом.
AA_DISCORD_AUDIT_WEBHOOK_URL = None

# Список идентификаторов учётных записей ботов, которые надо
# пропускать (в дополнение к таблице BotAccountUid в админке).
AA_DISCORD_AUDIT_BOT_UIDS = []

# Автоматическое распознавание ботов по эвристикам Discord-имени.
# Зарезервировано для v2, в MVP не реализовано. Стартовый валидатор
# выбрасывает ImproperlyConfigured при значении True — оставляйте
# False и ведите явную таблицу BotAccountUid в админке.
AA_DISCORD_AUDIT_AUTO_DISCOVER_BY_NICKNAME = False

# Срок хранения записей о прогонах. 0 отключает очистку, но
# валидатор откажется принять 0, пока не выставлен флаг согласия
# ниже.
AA_DISCORD_AUDIT_RUN_RETENTION_DAYS = 180
AA_DISCORD_AUDIT_RETENTION_OPT_OUT_ACKNOWLEDGED = False

# TTL idempotency-ключа. При положительном значении prune_audit_runs
# освобождает AuditRun.idempotency_key на строках старше отсечки,
# но саму строку оставляет на полный RUN_RETENTION_DAYS. 0 (по
# умолчанию) выключает expiry; ключ погибает вместе со строкой.
AA_DISCORD_AUDIT_IDEMPOTENCY_KEY_TTL_DAYS = 0

# Срок одного прогона. Значение `soft_time_limit` у задачи Celery
# подстраивается под этот лимит.
AA_DISCORD_AUDIT_RUN_DEADLINE_MINUTES = 60

# Скользящее ограничение частоты за 24 часа: сколько принятых
# запусков аудита разрешается одному пользователю в сутки.
# DISABLED — флаг полного отключения; срабатывает только при явной
# установке.
AA_DISCORD_AUDIT_RUN_RATE_LIMIT_PER_DAY = 5
AA_DISCORD_AUDIT_RUN_RATE_LIMIT_DISABLED = False

# Параметры доставки вебхука Discord.
AA_DISCORD_AUDIT_WEBHOOK_TIMEOUT = 10
AA_DISCORD_AUDIT_WEBHOOK_MAX_RETRIES = 3

# Включается явно: групповое снятие ролей одним PATCH-запросом.
# Быстрее на больших гильдиях; пока выключено по умолчанию, потому
# что мы собираем отзывы о том, как себя ведёт ограничение частоты
# со стороны Discord.
AA_DISCORD_AUDIT_USE_BULK_ROLE_STRIP = False

# Периодический (Celery beat) аудит. Разрушительные действия в
# беспилотной периодической задаче требуют этого явного согласия,
# независимо от одноразовой блокировки первого прогона: иначе
# beat-прогон со strip/kick приводится к report, с предупреждением на
# старте при расхождении.
AA_DISCORD_AUDIT_BEAT_ALLOW_DESTRUCTIVE = False

# Грубый глобальный нижний порог между beat-прогонами, в минутах. 0
# (по умолчанию) отключает его — основной регулятор частоты — это
# расписание Celery beat. Страховка от ошибочно частого расписания
# (QueueOnce дедуплицирует только одновременные тики, не идущие
# подряд).
AA_DISCORD_AUDIT_BEAT_MIN_INTERVAL_MINUTES = 0

# Закрепить действующего CLI-пользователя за Django-именем (паттерн
# «сервисного принципала»). У команды управления нет HTTP-запроса,
# поэтому актор обычно выводится из OS-логина; задайте это ради
# чистой стабильной атрибуции ConfigChangeLog как из cron, так и из
# ручного CLI. Разрешается и проверяется на права при каждом вызове.
AA_DISCORD_AUDIT_CLI_ACTOR = None

# Выборка присутствия гильдии. Требует extra-пакета [metrics] и
# отдельного scrape-таргета /audit/discord/metrics.
# PRESENCE_ENABLED независим от [metrics]: даже без extra отключение
# подавляет фоновую задачу-сэмплер.
AA_DISCORD_AUDIT_PRESENCE_ENABLED = True

# Желаемый интервал выборки присутствия в минутах. Значения
# меньше 5 приводятся к значению по умолчанию (10).
AA_DISCORD_AUDIT_PRESENCE_SAMPLE_INTERVAL_MINUTES = 10

# Переключатель для агрегата members_by_group. Отключите, если
# количество AA-групп создаёт неприемлемую кардинальность.
AA_DISCORD_AUDIT_METRICS_MEMBERS_BY_GROUP = True

# Переключатель для агрегата members_by_role. По умолчанию
# выключен — гильдии Discord могут содержать сотни ролей;
# включайте только после оценки числа ролей во избежание взрыва
# кардинальности.
AA_DISCORD_AUDIT_METRICS_MEMBERS_BY_ROLE = False

Команды управления

Долгий audit_discord_roles корректно реагирует на SIGTERM и SIGINT: прогон переводится в состояние INTERRUPTED, цикл применения покидает текущую находку на ближайшей границе — частично выполненная работа остаётся в журнале. Команда audit_discord_roles --resume <run_id> затем подхватывает прогон с остатком находок в состоянии PENDING.

Периодический аудит (Celery beat)

audit_orphan_members запускает тот же конвейер построения и применения по расписанию, которое вы заводите в Celery beat (по умолчанию задача не запланирована). Беспилотный путь огорожен ради безопасности:

  • Только отчёт, пока не вооружён. Beat-прогон приводится к report независимо от политики, пока не выставлен AA_DISCORD_AUDIT_BEAT_ALLOW_DESTRUCTIVE — снятие одноразовой блокировки первого прогона ради ручного CLI-запуска не вооружает beat. На старте печатается предупреждение, если политика разрушительна, а beat не включён явно.
  • С атрибуцией. Каждый beat-прогон пишет принятый AuditInvocation от системного актора (triggered_by=BEAT), так что журнал контроля аудитора покрывает и беспилотные запуски.
  • Самовосстановление. Прогон, застрявший из-за soft-time-limit или падения воркера, на следующем тике приводится к восстановимому состоянию INTERRUPTED. AA_DISCORD_AUDIT_BEAT_MIN_INTERVAL_MINUTES — грубый порог против ошибочно частого расписания.

Задачи Celery

Пакет регистрирует пять задач с префиксом имени aa_discord_audit.*. Расписание нужно только beat-задачам; остальные событийные или запускаются по требованию. Ни одна не планируется за вас.

Чтобы запланировать beat-задачи, добавьте их в CELERYBEAT_SCHEDULE в вашем local.py, например:

root@kitploit:~
CELERYBEAT_SCHEDULE["aa_discord_audit_sample_guild_presence"] = {
    "task": "aa_discord_audit.sample_guild_presence",
    "schedule": 600,  # секунды; не точнее пола сэмплера
}

Панель оператора

Подключается к основному меню Alliance Auth пунктом Discord Audit. Разделы только для чтения, повсюду с цветными бейджами действий и состояний и сортируемыми таблицами. В каждом разделе есть серверный поиск по всем строкам — не только по текущей странице — рядом с выпадающими фильтрами:

  • Прогоны аудита — сводная карточка с общей картиной аудита над списком с бейджами и сортировкой; подробности прогона разбиты на карточки вокруг таблицы находок.
  • Объяснение находки — какая категория, какое действие (с итоговой политикой в виде JSON и отметкой «по состоянию на») и какой слой принял решение (переопределение по uid, политика для группы или состояния, ProtectedDiscordMember, блокировка первого прогона).
  • Запуски аудита — каждый запуск из CLI или периодической задачи, включая отказы, с показанным состоянием прогона и разворачиваемой полной строкой аргументов; видно, как используется лимит частоты.
  • Записи журнала изменений настроек — каждая правка оператора в таблицах настроек, для обновлений показанная как пофайловый diff «было/стало» (для создания / удаления — отформатированный JSON), с фильтром по автору без учёта регистра. Журнал контроля действий аудитора.

Запуск аудита через веб-интерфейс

Операторы с правом aa_discord_audit.run_audit видят кнопку Launch Audit на странице Audit runs. По клику открывается модальное окно Bootstrap, в котором отображены режим политики (report-only или destructive), состояние initial-acknowledgement и кнопка Confirm Launch. Подтверждение POST'ит на /run-launch/, который создаёт PENDING AuditRun, ставит process_pending_run в очередь Celery и редиректит на страницу детализации прогона.

Веб-путь зеркалирует CLI-предохранители:

  • Блокировка первого прогона. Если audit_acknowledge_initial не запускался, модальное окно показывает блок отказа (без кнопки отправки) вместо Confirm Launch. POST в обход модального окна (curl) отказывается сервером, отказ пишется в AuditInvocation, оператор редиректится с flash- сообщением.
  • Разрушительное намерение. Может ли запуск снимать роли или кикать участников, решается на сервере по правам оператора и политике: was_confirmation_bypassed = user.has_perm(run_audit_destructive) and policy_has_destructive(policy). На UI нет переключателя — destructive-permission в одиночку определяет намерение. Оператор только с run_audit, нажавший Confirm Launch при destructive- политике, получает молчаливо прогон только в режиме REPORT (та же coercion, что CLI делает без --yes).
  • Суточный лимит на пользователя. Тот же суточный лимит, что у CLI; модальное окно всё ещё открывается, но POST возвращает flash + redirect, когда квота исчерпана.

Пока прогон находится в нетерминальном состоянии (PENDING, RUNNING или INTERRUPTED), страница детализации опрашивает /runs/<pk>/state.json каждые пять секунд и обновляет State-карточку in place. Опрос приостанавливается на скрытых вкладках и останавливается, как только прогон достигает терминального состояния.

Наблюдаемость

Опциональный слой инструментации Prometheus подключается через extra-пакет [metrics]. Модуль придерживается принципа «сотрудничать-не-зависеть»: если установлен django-prometheus, счётчики и гистограммы аудита регистрируются в общем prometheus_client.REGISTRY, и эндпоинт /metrics от django-prometheus отдаёт их вместе со своими сериями. Если extra-пакет не установлен, каждое обращение к метрике превращается в пустую заглушку с почти нулевой стоимостью — место вызова остаётся прежним.

root@kitploit:~
pip install aa-discord-audit[metrics]

Snapshot-гейджи — присутствие гильдии и агрегаты численности по группам и по ролям — идут вторым путём: они живут в выделенном реестре, который отдаёт собственный эндпоинт модуля /audit/discord/metrics. Многопроцессный коллектор django-prometheus читает только mmap-файлы и пропускает кастомные коллекторы, поэтому этим гейджам нужен отдельный scrape-таргет. Как и любой /metrics- таргет, он без аутентификации — ограничьте доступ на уровне обратного прокси или сети. Обе поверхности бездействуют без extra-пакета [metrics].

Каталог метрик, словарь меток и рецепты Grafana — в docs/METRICS.md (русский перевод: docs/METRICS.ru.md).

Ограничения

  • Одна гильдия. Аудит сверяет ту единственную гильдию Discord, на которую настроен AA; на несколько гильдий он не распространяется.
  • Только роли под управлением AA. Strip / kick действуют на роли с именами AA и на членство в гильдии; роли, которыми AA не управляет, никогда не затрагиваются.
  • Нет автораспознавания по нику. Боты определяются только по явной таблице BotAccountUid / AA_DISCORD_AUDIT_BOT_UIDS — AA_DISCORD_AUDIT_AUTO_DISCOVER_BY_NICKNAME зарезервировано для v2 и не реализовано.
  • Alpha-поверхность. Имена настроек и публичный API могут измениться до 1.0.

Документация

  • docs/runbook.md — оперативный справочник: права бота в Discord, чек-лист перед запуском, снятие блокировки первого запуска, сценарии реагирования на инциденты, диагностические переключатели.
  • docs/performance.md — эталонные показатели команды audit_benchmark и выводы по размеру установки.
  • docs/METRICS.md / docs/METRICS.ru.md — каталог метрик Prometheus, словарь меток, рецепты Grafana.
  • Исходный код: https://gitlab.com/eveo7/aa-discord-audit
  • Трекер задач: https://gitlab.com/eveo7/aa-discord-audit/-/issues
  • Журнал изменений: CHANGELOG.md

Разработка

root@kitploit:~
make dev         # uv sync --all-groups + установка хуков pre-commit
make tests       # uv run nox -s tests
make lint        # uv run nox -s lint
make typecheck   # mypy + basedpyright
make coverage    # отчёт о покрытии: терминал + html + xml
make package     # uv build

Инструментарий — только uv. Длина строки: 79 для Python, 120 для Markdown.

Переводы

  • English

Лицензия

MIT — см. LICENSE.

Скачать инструмент
ПравоНа что влияет
aa_discord_audit.run_auditкоманда, периодическая задача, удаление запусков
aa_discord_audit.run_audit_destructiveзапуск strip / strip_kick из веб-интерфейса (отдельно от run_audit)
aa_discord_audit.acknowledge_initial_auditснятие блокировки первого запуска
aa_discord_audit.manage_discord_identityработа с DiscordIdentity в админке
aa_discord_audit.manage_role_exceptionработа с ManagedRoleException в админке
aa_discord_audit.manage_protected_memberработа с ProtectedDiscordMember в админке
aa_discord_audit.manage_bot_account_uidработа с BotAccountUid в админке
aa_discord_audit.manage_finding_overrideработа с FindingActionOverride в админке
aa_discord_audit.view_auditrun и аналогичныепросмотр журнала на панели Alliance Auth
КомандаНазначение
audit_discord_rolesОсновная точка входа. --action {report,strip,strip_kick}.
audit_discord_roles --resume <run_id>Доделать находки в состоянии PENDING для существующего прогона.
audit_discord_roles --abandon <run_id>Пометить зависший прогон как ABANDONED.
audit_discord_roles --diff <run_id>Сравнить текущее состояние с прошлым прогоном.
audit_discord_roles --explain <member_id>Классификация одного участника (без записи).
audit_discord_roles --policy-preview <json>Прогнать гипотетическую политику по текущим находкам.
audit_discord_roles --from-fixture <path>Воспроизведение по JSON-снимку.
audit_acknowledge_initialСнять блокировку первого прогона из консоли.
audit_benchmarkБенчмарк под синтетической нагрузкой (см. docs/performance.md).
prune_audit_runsОчистка устаревших записей по сроку хранения.
audit_abandon_stuck_runsСогласовать зависшие PENDING-прогоны после падения воркера — переводит их в ABANDONED (см. runbook; зависший RUNNING-прогон закрывается через audit_discord_roles --abandon).
ЗадачаКак запускаетсяЧто делает
aa_discord_audit.audit_orphan_membersCelery beat — планируете выБеспилотный аудит построения и применения, описанный выше. Только отчёт, пока не вооружён; разделяет блокировку discord.user_actions.<uid> с update_groups из AA.
aa_discord_audit.retry_pending_kicksCelery beat — планируете выОграниченный проход, повторно отправляющий кики, отложенные временным сбоем Discord, с учётом покейсового кулдауна, чтобы по жёстко падающему участнику не било повторно.
aa_discord_audit.process_pending_runСобытийная — ставится в очередь веб-запускомПодхватывает PENDING-прогон, созданный веб-запуском, переводит его в RUNNING и исполняет конвейер с учётом замороженного флага подтверждения.
aa_discord_audit.prune_audit_runsCelery beat / cron — планируете вы (также команда управления)Хранение: истечение ключа идемпотентности, затем удаление строк (см. Команды управления и runbook).
aa_discord_audit.sample_guild_presenceCelery beat — планируете выЛёгкий REST-only замер счётчиков участников / онлайна / бустов в latest-only снимок присутствия для Prometheus-датчиков. Гейтится AA_DISCORD_AUDIT_PRESENCE_ENABLED; страховка-skip ограничивает ошибочно частое расписание (пол AA_DISCORD_AUDIT_PRESENCE_SAMPLE_INTERVAL_MINUTES, по умолчанию 10). Бездействует, пока не установлены extra [metrics] и запись beat (см. docs/METRICS.md).