SecureExec
ГлавнаяО насБлогЦены
ВойтиРегистрация
← Назад к блогу

Техническое описание: как работает SecureExec

11 марта 2026 г.

SecureExec — self-hosted платформа обнаружения и реагирования (EDR) для Linux. Эта статья — техническое описание: полный путь данных от хука в ядре до алерта, архитектура агента, серверный движок детекции и механизмы реагирования.

Архитектура

┌─────────────────────────────────────────┐
│              Linux-хост                 │
│                                         │
│  eBPF-программы (ядро)                  │
│    ├── tracepoints (хуки syscall'ов)    │
│    └── kprobes (хуки функций ядра)      │
│            │                            │
│    Ring buffers (4 канала)              │
│            │                            │
│  Агент (userspace, один бинарник Rust)  │
│    ├── eBPF consumer (парсинг + обогащ.)│
│    ├── Таблица процессов (pid→guid)     │
│    ├── Цепочка фильтров (дедупл. + конф)│
│    ├── SQLite spool (устойчивость)      │
│    └── gRPC transport                   │
└────────────┬────────────────────────────┘
             │ TLS / gRPC stream
             ▼
┌─────────────────────────────────────────┐
│           Сервер SecureExec             │
│  ├── Приём событий (gRPC)               │
│  ├── Alert engine (21 встроенное правило)│
│  ├── Кастомные Starlark-правила         │
│  ├── Таблица процессов (lineage/агент)  │
│  ├── Индексация в Elasticsearch         │
│  └── Диспетчер реагирования             │
│           │                             │
│    Веб-консоль (Next.js)                │
│    ├── Дашборд алертов + поиск          │
│    ├── Визуализация дерева процессов     │
│    ├── Таймлайн инцидентов              │
│    └── UI действий реагирования         │
└─────────────────────────────────────────┘

Сбор событий через eBPF

Агент использует eBPF-программы, подключённые к tracepoints и kprobes ядра, для перехвата событий, значимых для безопасности, с минимальными накладными расходами. Kernel module не требуется — eBPF-программы загружаются при старте агента и корректно удаляются при остановке.

События проходят через четыре выделенных ring buffer'а, каждый с размером, подобранным под ожидаемую нагрузку:

Ring BufferРазмерТипы событий
PROCESS_EVENTS512 КБprocess_exec, process_fork, process_exit, exec_argv
FILE_EVENTS256 КБfile_create, file_modify, file_delete, file_rename, file_link, file_perm_change
NETWORK_EVENTS256 КБnetwork_connect, network_listen, dns_query
SECURITY_EVENTS1 МБprivilege_change, process_vm_access, memfd_create, kernel_module_load, namespace_change, capability_change, bpf_program, process_signal, keyctl

Каждая запись в ring buffer'е начинается с байта event_tag: u8, определяющего тип события. Userspace-consumer читает тег, приводит оставшиеся байты к соответствующей #[repr(C)] структуре и конвертирует в типизированный вариант enum'а BpfEvent.

Что мы перехватываем

Примеры syscall'ов и функций ядра, на которые установлены хуки:

  • sched_process_exec — перехватывает каждый exec, включая полный argv через связанное событие EXEC_ARGV для длинных командных строк
  • sched_process_fork / sched_process_exit — отслеживание создания и завершения процессов для in-memory таблицы процессов
  • sys_enter_openat / security_file_open — файловые операции, фильтруются в ядре для исключения высокочастотного шума из /proc и /sys
  • sys_enter_connect / sys_enter_bind — сетевые соединения и прослушивающие сокеты с полным парсингом sockaddr
  • udp_sendmsg — извлечение DNS-запросов (UDP порт 53)
  • sys_enter_setuid / sys_enter_setreuid — изменения привилегий
  • sys_enter_process_vm_writev — кросс-процессная запись в память (process injection)
  • sys_enter_memfd_create — fileless-выполнение через in-memory файловые дескрипторы
  • sys_enter_init_module / sys_enter_finit_module — загрузка модулей ядра
  • sys_enter_unshare / sys_enter_setns — изменения namespace'ов (сигналы побега из контейнера)

Все eBPF-программы написаны на Rust с использованием фреймворка Aya.

Архитектура агента

Агент — это один статически скомпонованный бинарник на Rust с нулевыми зависимостями. Работает как systemd-сервис (secureexec-agent.service) и обычно потребляет менее 1% CPU и < 50 МБ RAM на production-сервере, генерирующем 50 000+ событий в минуту.

Пайплайн событий

eBPF ring buffers
  → parse_*_event()          (тег → BpfEvent вариант)
  → convert_bpf_events()     (BpfEvent → EventKind)
  → ProcessTable.resolve()   (pid → process_guid, username, container_id)
  → FilterChain              (дедупликация по content_hash, настраиваемые фильтры по типам)
  → SQLite spool             (устойчивая очередь на диске, переживает рестарт агента)
  → gRPC transport           (streaming или batch режим)
  → Сервер

Таблица процессов

Агент ведёт in-memory таблицу процессов, индексированную по PID. При старте выполняется перечисление /proc для построения базового снимка. По мере поступления событий process_exec, process_fork и process_exit таблица обновляется в реальном времени.

Каждая запись хранит:

  • PID и PPID (parent PID из procfs, не из tracepoint — tracepoint ненадёжен для PPID)
  • start_time (из /proc/{pid}/stat)
  • process_guid — стабильный SHA-256 хеш от (agent_id, pid, start_time), уникально идентифицирующий процесс даже при повторном использовании PID
  • username — разрешённый из карты UID→name, спарсенной из /etc/passwd при старте
  • container_id — извлечённый из /proc/{pid}/cgroup, если процесс работает внутри контейнера

process_guid — ключ, связывающий события с визуализацией дерева процессов в консоли. Благодаря включению start_time он различает два разных процесса, повторно использующих один PID.

Spool и повторная отправка

При потере gRPC-соединения с сервером события сохраняются в локальную базу SQLite (spool). При восстановлении соединения накопленные события переотправляются в порядке sequence number'ов. Heartbeat агента (AgentHeartbeat) сообщает значение spool_pending, чтобы операторы могли отслеживать backlog через веб-консоль.

Дедупликация по содержимому

Тело каждого события хешируется SHA-1 (трейт ContentHash). Агент поддерживает LRU-фильтр дедупликации на 65 536 записей. Если одинаковое содержимое события встречается дважды в пределах окна фильтра, дубликат отбрасывается до попадания в spool. Это устраняет избыточный шум от inotify-штормов и частых перезапусков процессов.

Схема событий (Protobuf)

Все события используют общий конверт:

message AgentEvent {
  string id          = 1;   // UUIDv4
  uint64 seqno       = 2;   // монотонный, per-agent
  string timestamp   = 3;   // ISO-8601
  string agent_id    = 4;
  string hostname    = 5;
  string os          = 6;
  string content_hash = 7;  // SHA-1 тела события
  string process_guid = 8;  // стабильный ID процесса
  string process_name = 9;
  uint32 process_pid  = 38;
  string username     = 40;
  string container_id = 41;

  oneof kind {
    ProcessEvent        process_create    = 10;
    ProcessEvent        process_fork      = 25;
    ProcessEvent        process_exit      = 11;
    FileEvent           file_create       = 12;
    FileEvent           file_modify       = 13;
    FileEvent           file_delete       = 14;
    FileRenameEvent     file_rename       = 15;
    NetworkEvent        network_connect   = 16;
    NetworkEvent        network_listen    = 17;
    DnsEvent            dns_query         = 18;
    UserLogonEvent      user_logon        = 20;
    PrivilegeChangeEvent  privilege_change  = 26;
    ProcessVmEvent      process_vm_access  = 31;
    MemfdCreateEvent    memfd_create       = 32;
    KernelModuleEvent   kernel_module_load = 30;
    NamespaceChangeEvent namespace_change  = 36;
    CapabilityChangeEvent capability_change = 34;
    // ... и другие
  }
}

Поле seqno — монотонно возрастающий счётчик per-agent. Обеспечивает полную упорядоченность событий внутри хоста и служит вторичным ключом сортировки (после @timestamp) в запросах Elasticsearch, что даёт корректный порядок событий с субмиллисекундной точностью.

Серверный движок детекции

Сервер оценивает каждое входящее событие по набору правил алертов. Правила бывают двух типов:

Встроенные правила (21 правило)

Нативные Rust-правила, скомпилированные в бинарник сервера. Каждое правило реализует трейт AlertRule:

pub trait AlertRule: Send + Sync {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    fn severity(&self) -> &str;        // "low" | "medium" | "high" | "critical"
    fn evaluate(&self, ctx: &AlertContext, events: &[AgentEvent]) -> Vec<AlertEvent>;
}

Правила получают батчи событий и AlertContext, включающий серверную таблицу процессов для разрешения lineage. Примеры:

  • Reverse Shell — матчит shell-процессы (bash, sh, zsh, dash, ksh), устанавливающие исходящие соединения к не-приватным IP
  • SSH Brute-Force — stateful-правило со sliding window счётчиком per (source_ip, agent_id) и cooldown-таймером для предотвращения флуда алертов
  • Ransomware — multi-signal правило: создание ransom note, переименование файлов в encrypted-расширения, детекция скорости массового переименования (20+ за 60с) и паттерны команд уничтожения бэкапов
  • Криптомайнер — cross-event-type правило, матчащее имена процессов, stratum-паттерны в командных строках, порты майнинг-пулов и DNS-запросы к известным доменам пулов

Каждое правило включает allowlist для известных легитимных процессов. Например, правило Privilege Escalation исключает sshd (privilege separation), su, sudo, cron и systemd-executor.

Кастомные Starlark-правила

Пользователи могут писать правила детекции на Starlark (Python-подобный конфигурационный язык). Кастомные правила хранятся в PostgreSQL и перезагружаются без перезапуска сервера. Они имеют доступ к тому же AlertContext и данным событий, что и встроенные правила.

Правила подавления

Starlark-based правила подавления позволяют отфильтровать известные ложные срабатывания. Они оцениваются после правил алертов и могут подавить конкретные алерты по имени правила, severity, имени процесса или любому полю события.

Хранение в Elasticsearch

События и алерты индексируются в Elasticsearch с отдельными шаблонами индексов:

  • События: secureexec-events-{org_id}-* — ежедневная ротация, 7-дневное хранение (настраивается)
  • Алерты: secureexec-alerts-{org_id}-* — ежедневная ротация, 90-дневное хранение

Сервер использует _bulk API для высокопроизводительной индексации. Каждое событие индексируется со всеми полями конверта и типо-специфичным payload'ом, что позволяет выполнять полнотекстовый поиск по командным строкам, путям файлов, IP-адресам и DNS-запросам.

Возможности реагирования

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

  • Сетевая изоляция — агент настраивает правила iptables для блокировки всего трафика, кроме gRPC-канала агент↔сервер. Хост эффективно изолирован, но остаётся управляемым.
  • Уничтожение дерева процессов — отправляет SIGKILL всей группе процессов от PID-предка, завершая полную цепочку атаки.
  • Блокировка по хешу или пути — использует fanotify для запрета exec-разрешений для конкретных хешей файлов или путей. Правила мгновенно применяются ко всем агентам организации.
  • Глобальный блок-лист — централизованно управляемые правила блокировки, распространяемые на все конечные точки.

Команды реагирования доставляются агентам через gRPC control channel (CommandStream). Агент опрашивает наличие ожидающих команд на каждом heartbeat-интервале.

Таймлайн инцидентов

Таймлайн инцидентов восстанавливает хронологическую историю атаки из любой точки входа — алерта, процесса или временного окна на конкретном хосте.

Сервер запрашивает Elasticsearch на события, соответствующие scope (agent_id + process_guid + временной диапазон), опционально разрешает lightweight lineage процессов (one-hop lookup родителя из process_create/fork событий) и объединяет события с соответствующими алертами. Каждая запись размечается фазой атаки (Initial Access, Execution, Persistence, C2) на основе эвристик — например, исходящие соединения к внешним IP размечаются как C2, а записи в cron-директории — как Persistence.

Развёртывание

Агент поставляется как .deb или .rpm пакет и устанавливается менее чем за 60 секунд:

dpkg -i secureexec-agent.deb
systemctl start secureexec-agent

Поддерживаемые дистрибутивы: Ubuntu 20.04+, Debian 11+, RHEL 8+, Amazon Linux 2. Единственное требование к ядру — поддержка eBPF (kernel 5.4+). Для более старых ядер доступен опциональный kernel module fallback.

Серверные компоненты (API-сервер, Elasticsearch, PostgreSQL) разворачиваются через Docker Compose для single-node установок или Kubernetes для production-кластеров.

Открытые вопросы и roadmap

Активные направления разработки:

  • File integrity monitoring со сравнением с baseline
  • Интеграция YARA-сканирования для анализа файлов на хосте
  • Библиотека Starlark-правил с community-контрибуциями
  • Поддержка агентов для macOS и Windows (Endpoint Security framework и ETW соответственно)

По вопросам или для guided walkthrough на вашей инфраструктуре — запросите демо. Демо проходит на реальном Linux-хосте, без слайдов.

SecureExec

Лёгкая платформа безопасности конечных точек. Мониторинг процессов, файлов и сетевой активности в режиме реального времени по всему вашему парку устройств.

Продукт
  • Цены
Компания
  • О нас
  • Блог
  • Связаться с отделом продаж
  • Поддержка
Аккаунт
  • Войти
  • Регистрация
Правовая информация
  • Политика конфиденциальности
  • Условия использования

© 2026 SecureExec. Все права защищены.

Built with Rust & Next.js