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

Обоснование надёжности

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

Пути к файлам ниже указаны относительно корня репозитория.

  1. Читать или изменять конфигурацию, оповещения и измерения может только аутентифицированный пользователь, чья роль это разрешает.
  2. Учётные данные, которые DumbMonit хранит для ваших мониторов, нельзя прочитать ни из файла базы данных, ни из резервной копии без парольной фразы, ни через API.
  3. Передавать измерения может только машина с действительным токеном, а утёкший токен можно отозвать отдельно.
  4. DumbMonit нельзя превратить в средство доступа к сервисам, к которым доступа быть не должно, в частности к собственному дочернему процессу VictoriaMetrics без аутентификации.
  5. Страница, отданная браузеру, не может выполнить скрипт, которого она с собой не поставляла, а сторонний сайт не может заставить вошедший в систему браузер что-либо изменить.
ЗлоумышленникВозможностиВ рамках модели
Анонимный сетевой клиентДостигает HTTP-портаДа
Вошедший пользователь с низкой рольюДействительный сеанс или токен API только для чтенияДа (повышение привилегий)
Вредоносная веб-страницаРаботает в браузере администратораДа (CSRF, XSS, clickjacking)
Скомпрометированный или вредоносный отслеживаемый мониторОтвечает на опросы враждебным содержимымДа (парсеры, перенаправления)
Вредоносный или украденный агентВладеет одним токеном агентаДа (область действия одного токена)
Администратор, вводящий враждебный URLНастраивает вебхук или адрес монитораДа, для собственных адресов сервера
Тот, кто контролирует хост, том /data или среду выполнения контейнеровПолный контрольНет: вне модели, как и в политике безопасности
Уязвимости внутри VictoriaMetrics или отслеживаемых мониторовСторонний кодНет: сообщайте разработчикам upstream
ГраницаЧто её пересекаетКак защищенаПодтверждения
Браузер — /api/*Сеансовый cookie или токен API, JSONОдин слой аутентификации, три роли, заголовок CSRF для записи с аутентификацией по cookiecrates/server/src/auth/middleware.rs; тесты auth_api.rs, operator_role_api.rs, api_open_security_api.rs, cors_policy_api.rs
Браузер — отдаваемые страницыHTML, скрипты, стилиContent Security Policy с nonce для каждого ответа, nosniff, Referrer-Policy: same-origin, X-Frame-Options: DENYcrates/server/src/api/mod.rs (слой заголовков безопасности)
Провайдер идентификации — серверПеренаправление OpenID Connect и ID-токенState, nonce и PKCE (S256); привязка локальной учётной записи выполняется явноcrates/server/src/auth/oidc/; тест oidc_api.rs
Агент — /api/ingestИзмерения, результаты командТокен каждого агента, хранится как хеш SHA-256 (префикс dmon_)crates/server/src/api/ingest.rs, crates/server/src/collectors/agent/token.rs; тест agent_binding_api.rs
Агент-ретранслятор — серверРезультаты опросов из другой сетиТа же проверка токена агента (agent_commands::authenticate)crates/server/src/api/relay.rs; тест relay_api.rs
Сервер — отслеживаемые мониторыЗапросы опроса, враждебные ответыПеренаправления только в пределах того же хоста, ограниченное число перенаправлений, парсеры ответов с модульными тестами, проверка сертификатов включена по умолчаниюcrates/collectors/src/http.rs (same_host_redirects)
Сервер — каналы уведомленийЗапросы вебхуков и SMTPТа же политика перенаправлений плюс защита, отклоняющая собственные адреса сервера; проверка выполняется перед отправкой, при каждом перенаправлении и при разрешении DNScrates/server/src/notify/guard.rs; тест notify_guard_api.rs
Сервер — VictoriaMetricsЗаписи и запросы на чтениеВстроенный дочерний процесс по умолчанию слушает 127.0.0.1:8428; Prometheus-совместимый прокси пропускает только маршруты чтения (query, query_range, series, labels)crates/server/src/config.rs (DUMBMONIT_VM_LISTEN), crates/server/src/api/prometheus.rs (readable_segments)
Сервер — SQLiteКонфигурация и состояниеПривязанные параметры через sqlxcrates/server/src/db/
Сервер — /dataБаза данных, секретный ключСекреты шифруются AES-256-GCM; пользователь контейнера владеет только /datacrates/server/src/crypto.rs, Dockerfile

Аргументация безопасного проектирования

Заголовок раздела «Аргументация безопасного проектирования»

Аргументация следует принципам проектирования Зальцера и Шрёдера.

  • Экономичность механизма. Один бинарный файл, один файл SQLite, один дочерний процесс на loopback, один вход для всех клиентов (/api/*).
  • Безопасные значения по умолчанию. На свежем экземпляре каждый маршрут под защитой аутентификации отвечает 401; отвечают только health, статус аутентификации, setup и login, поэтому никто не может подготовить экземпляр раньше его владельца (auth/middleware.rs, тест api_open_security_api.rs). VictoriaMetrics слушает loopback, пока оператор не изменит это. Сертификаты TLS наблюдаемых сервисов проверяются, если оператор не задал insecure_tls (crates/collectors/src/http.rs).
  • Полное посредничество. Слой аутентификации работает на каждом маршруте API, а не оставляет проверку каждому обработчику.
  • Открытое проектирование. Код, описание API (crates/server/src/api/openapi.yaml) и эта страница общедоступны. Безопасность не зависит от секретности устройства системы.
  • Разделение привилегий. Сеансы, токены API и токены агентов — разные учётные данные. Токены API имеют область read или write (auth/token.rs), а у пользователей роль наблюдателя, оператора или администратора.
  • Наименьшие привилегии. Образ работает с UID 65532 (Dockerfile). Запущенный от root (user: "0:0", для bind mount), сервер лишь передаёт каталог данных этому пользователю, не переходя по ссылкам, затем навсегда отказывается от root и проверяет, что вернуть его нельзя, прежде чем открывать что-либо ещё (privileges.rs). Файл Compose оставляет только четыре capabilities, нужные этому шагу, делает корневую файловую систему доступной только для чтения и задаёт no-new- privileges (docker-compose.yml).
  • Наименьший общий механизм. Агенты аутентифицируются собственным токеном, поэтому отзыв одной машины не затрагивает ни пользователей, ни других агентов.
  • Психологическая приемлемость. Безопасное поведение включено по умолчанию и не требует лишних шагов: cookie имеет флаги HttpOnly и SameSite=Lax, заголовок CSRF добавляется веб-клиентом, секреты в интерфейсе доступны только для записи.
  • Эшелонированная защита. Шифрование при хранении поверх контроля доступа; заголовок CSRF поверх SameSite; ограничение частоты входа поверх хеширования Argon2; политика перенаправлений поверх защиты от собственных адресов.
  • Пароли: Argon2 (auth/password.rs). Секреты сеансов и токенов API хранятся в виде хешей SHA-256 от случайных значений (auth/session.rs, auth/token.rs).
  • Секреты при хранении: AES-256-GCM со свежим nonce при каждом шифровании (crypto.rs). Ключ получается с помощью Argon2id из DUMBMONIT_SECRET или сгенерированного файла ключа с постоянной солью; секрет короче 16 символов отклоняется, а контрольное значение при запуске выявляет неверный ключ.
  • Резервные копии: ключ выводится из парольной фразы оператора с помощью Argon2id, параметры хранятся в самом архиве, поэтому алгоритм можно менять, не ломая старые архивы (backup/bundle.rs).
  • Второй фактор: TOTP с хешированными одноразовыми резервными кодами (auth/totp.rs).
  • OpenID Connect: state, nonce и PKCE S256 (auth/oidc/pkce.rs).
  • Все примитивы взяты из поддерживаемых библиотек (aes-gcm, argon2, sha2); ничего самодельного. Встроенный обработчик принимает только HTTPS (обычный HTTP-запрос получает перенаправление), а cookie получает флаг Secure (auth/cookie.rs).

Меры противодействия распространённым уязвимостям

Заголовок раздела «Меры противодействия распространённым уязвимостям»
Уязвимость (OWASP Top 10, CWE)Мера противодействияПодтверждения
Нарушенный контроль доступа, CWE-862, CWE-285Слой аутентификации, роли, области токеновoperator_role_api.rs, api_tokens_api.rs, api_open_security_api.rs
Криптографические сбои, CWE-327, CWE-312AES-256-GCM при хранении, Argon2, API не возвращает секретымодульные тесты crypto.rs; has_secret / credential_kind вместо секрета
SQL-инъекция, CWE-89Привязанные параметры через sqlxcrates/server/src/db/
Межсайтовый скриптинг, CWE-79Svelte экранирует вывод; CSP с default-src 'none', скрипты только из 'self' и с nonce; base-uri 'none'api/mod.rs
Межсайтовая подделка запросов, CWE-352Запись через cookie требует X-Requested-With: DumbMonit или метаданные fetch того же источника; CORS не разрешает этот заголовок никому; SameSite=Laxauth/middleware.rs, auth/cors.rs; тест cors_policy_api.rs
Clickjacking, CWE-1021X-Frame-Options: DENY и frame-ancestors 'none', кроме публичных страниц статуса, которые включены явно и предназначены для встраиванияapi/mod.rs
Подделка запросов со стороны сервера, CWE-918Перенаправления только в пределах того же хоста; защита уведомлений отклоняет собственные адреса сервера и VictoriaMetrics, в том числе после разрешения DNS (rebinding). Loopback и частные диапазоны намеренно остаются доступными, потому что там живут сервисы домашней лабораторииnotify/guard.rs; тест notify_guard_api.rs
Сбои аутентификации, CWE-307, CWE-287Ограничение частоты входа с растущей задержкой по адресу и по учётной записи, необязательный TOTP, OIDC с PKCE, сброс второго фактора администраторомauth/rate_limit.rs, auth/totp.rs, auth/oidc/
Небезопасная десериализация, исчерпание ресурсов, CWE-400Типизированный JSON через serde, тела запросов ограничены 16 МиБ, число перенаправлений ограниченоapi/mod.rs, collectors/src/http.rs
Безопасность памяти, CWE-787, CWE-416Rust; unsafe встречается только в коде счётчиков производительности агента для Windows (crates/agent/src/collect/perf_counters.rs)поиск unsafe через grep
Уязвимые компоненты, CWE-1104cargo deny (лицензии, запреты, рекомендации); Dependabot; сканирование опубликованных образов Trivy; actions закреплены по коммиту; сборки с --locked.github/workflows/ci.yml, security.yml, .github/dependabot.yml, deny.toml
Целостность программ и данных, CWE-494Установщики агента проверяют SHA-256 загруженного бинарного файлаcrates/agent/install/install.sh, install.ps1
Сбои журналирования и мониторинга, CWE-778Журнал безопасности входов и важных измененийauth/audit.rs; тест security_audit_api.rs

Известные остаточные риски перечислены в модели безопасности (самоподписанный сертификат по умолчанию, незашифрованные параметры мониторов, встроенная VictoriaMetrics без аутентификации). CSP допускает встроенные стили (style-src 'unsafe-inline'), что ослабляет защиту от внедрения стилей, но не от выполнения скриптов. Существует одна принятая рекомендация, RUSTSEC-2023-0071, которая игнорируется в deny.toml с указанием причины: крейт rsa проверяет подписи RS256 открытым ключом провайдера и никогда не использует закрытый ключ.

  • Непрерывная интеграция (.github/workflows/ci.yml): cargo fmt --check, clippy -D warnings, полный набор тестов Rust, cargo deny check licenses bans и cargo deny check advisories, проверка типов веб-части, веб-тесты и сборка, а также сборка образа Docker при каждом push и pull request.
  • Сканирование по расписанию (.github/workflows/security.yml): Trivy для опубликованных образов сервера и агента и OpenSSF Scorecard — еженедельно и после каждой публикации :edge. Результаты отображаются на вкладке Security репозитория, куда также поступают отчёты GitHub code scanning (CodeQL).
  • Тесты: тесты API, аутентификации, ролей, CORS, OIDC, защиты и аудита в crates/server/tests/, модульные тесты рядом с кодом и веб-тесты в web/tests/. Покрытие строк Rust, измеренное с помощью cargo-llvm-cov, составляет 91 %.
  • Политика регрессий: исправление сопровождается тестом, который без него не проходит (см. политику тестирования в CONTRIBUTING.md).
  • Публичная запись: исправления безопасности публикуются как advisories и перечисляются в примечаниях к релизу.