osquery на Linux в 2026: SQL-запросы к endpoint'ам, Fleet и интеграция с SIEM

Практическое руководство по osquery на Linux в 2026 году: установка osqueryd, SQL-запросы к процессам, файлам и сети, управление через Fleet и отправка результатов в SIEM.

osquery на Linux: Fleet, SIEM (2026)

Обновлено: 17 сентября 2026 г.

osquery — это open-source агент от Meta, который превращает Linux в реляционную БД: процессы, сокеты, файлы, пакеты и ядро становятся SQL-таблицами, к которым можно писать обычные SELECT-запросы для расследований, compliance-проверок и обнаружения аномалий. В 2026 году osquery 5.14 работает на всех крупных дистрибутивах, а связка с Fleet позволяет опрашивать тысячи endpoint'ов параллельно и отправлять результаты в SIEM. Честно говоря, для меня это самый быстрый способ получить ответ на вопрос «что сейчас происходит на 500 хостах»: пишешь SQL, получаешь строки. В этой статье разберу установку, конфигурацию, packs, интеграцию с Wazuh/Elastic и типовые запросы, которые мы реально используем в проде.

  • osquery 5.14 (июль 2026) официально поддерживает Debian 12, Ubuntu 24.04, RHEL 9 и Flatcar; собирается для x86_64 и arm64.
  • osqueryd работает как systemd-сервис и логирует результаты запросов в /var/log/osquery/osqueryd.results.log в формате JSON, готово к отправке в SIEM.
  • Fleet 4.50+ (open-source) — это единый манипулятор для управления парком: single-pane-of-glass, live queries, packs, YAML-конфиг как код.
  • Таблицы process_events, socket_events и file_events требуют включённой опции --disable_audit=false и работают через Linux Audit subsystem.
  • osquery не заменяет Wazuh или Falco, он дополняет их: Wazuh делает корреляцию и алертинг, Falco ловит runtime-события через eBPF, а osquery отвечает за глубокие точечные запросы.
  • SQL-запросы можно мапить на MITRE ATT&CK: T1053 (cron), T1136 (создание учётки), T1543 (persistence через systemd) покрываются штатными таблицами.

Что такое osquery и зачем он нужен

osquery — это агент, который экспонирует состояние ОС как набор виртуальных SQL-таблиц. Пишете SELECT pid, name, cmdline FROM processes WHERE on_disk = 0; и получаете список процессов, чей бинарник удалён с диска (классический признак rootkit'а или процесса, запущенного из tmpfs). За кулисами osquery опрашивает /proc, netlink, sqlite-каталоги пакетного менеджера и сотни других источников, но интерфейс всегда один: SQL.

Проект был опубликован Facebook (Meta) в 2014 году, а в 2019 передан в Linux Foundation. В 2026 году актуальная ветка это 5.14, с полной поддержкой ARM64 и нативным пакетом для Flatcar/RHEL 9 (см. GitHub releases). Я использую osquery в паре с Wazuh SIEM для обнаружения вторжений на Linux: Wazuh делает корреляцию и алерты, а osquery отвечает на конкретный вопрос по инциденту вроде «какие бинарники запустились из /tmp за последние 24 часа». Так и живём.

В отличие от auditd, osquery не сырой поток событий, а высокоуровневая абстракция. Вы не разбираете type=SYSCALL msg=audit(...), а пишете SELECT * FROM process_events WHERE cmdline LIKE '%curl%bash%';. Это резко снижает time-to-detect и делает knowledge-transfer в команде на порядок легче: любой аналитик, знающий SQL, может писать запросы. И это, честно, огромное преимущество, когда у тебя на смене только один синьор.

Установка osquery на Ubuntu, Debian и RHEL

Официальные репозитории osquery подписаны и обновляются вместе с релизами. На Ubuntu 24.04 и Debian 12 установка выглядит так.

# Подключаем официальный APT-репозиторий osquery
export OSQUERY_KEY=1484120AC4E9F8A1A577AEEE97A80C63C9D8B80B
sudo apt-key adv --keyserver hkps://keyserver.ubuntu.com --recv-keys $OSQUERY_KEY
sudo add-apt-repository 'deb [arch=amd64] https://pkg.osquery.io/deb deb main'
sudo apt update
sudo apt install -y osquery

# Проверяем версию
osqueryi --version
# osqueryi version 5.14.1

Для RHEL 9 / AlmaLinux / Rocky:

sudo curl -L https://pkg.osquery.io/rpm/GPG -o /etc/pki/rpm-gpg/RPM-GPG-KEY-osquery
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-osquery
sudo dnf config-manager --add-repo https://pkg.osquery.io/rpm/osquery-s3-rpm.repo
sudo dnf install -y osquery
sudo systemctl enable --now osqueryd

Для интерактивной работы используется osqueryi, REPL, который читает те же таблицы, что и демон, но без записи в лог:

sudo osqueryi
osquery> SELECT hostname, cpu_brand, physical_memory FROM system_info;
osquery> .tables    -- показать все доступные таблицы (около 280 на Linux)
osquery> .schema processes   -- показать колонки таблицы

Конфигурация osqueryd и schedule-запросы

Демон конфигурируется через /etc/osquery/osquery.conf. Минимальный практичный конфиг для production-хоста:

{
  "options": {
    "config_plugin": "filesystem",
    "logger_plugin": "filesystem",
    "logger_path": "/var/log/osquery",
    "disable_logging": "false",
    "log_result_events": "true",
    "schedule_splay_percent": "10",
    "pidfile": "/var/osquery/osquery.pidfile",
    "events_expiry": "3600",
    "database_path": "/var/osquery/osquery.db",
    "verbose": "false",
    "worker_threads": "2",
    "enable_monitor": "true",
    "disable_audit": "false",
    "audit_allow_config": "true",
    "audit_allow_process_events": "true",
    "audit_allow_sockets": "true",
    "audit_allow_user_events": "true",
    "host_identifier": "hostname",
    "enable_syslog": "true",
    "utc": "true"
  },
  "schedule": {
    "listening_ports_hourly": {
      "query": "SELECT DISTINCT p.name, p.pid, l.port, l.address, l.protocol FROM listening_ports l JOIN processes p ON l.pid = p.pid WHERE l.address NOT IN ('127.0.0.1','::1','0.0.0.0');",
      "interval": 3600
    },
    "logged_in_users_15min": {
      "query": "SELECT user, tty, host, time FROM logged_in_users;",
      "interval": 900
    },
    "suid_binaries_daily": {
      "query": "SELECT path, uid, gid FROM suid_bin;",
      "interval": 86400,
      "snapshot": true
    },
    "kernel_modules_hourly": {
      "query": "SELECT name, size, used_by, status FROM kernel_modules;",
      "interval": 3600
    }
  }
}

Ключевые параметры. Опция schedule_splay_percent размывает время запуска на ±10%, чтобы 500 хостов не долбили диск одновременно. events_expiry держит буфер событий в оперативной памяти 3600 секунд, этого хватает для среднего интервала опроса. А disable_audit=false активирует линуксовую audit-подсистему, без которой не работают таблицы process_events, socket_events и user_events.

Полезные SQL-запросы для расследований

Ниже набор запросов, которые я запускаю в первую очередь при подозрении на компрометацию. Все они работают из коробки, без установки дополнительных extensions. Именно этот список пригодился мне в марте 2026-го, когда у клиента на кластере в Найроби появился «странный» PID из /dev/shm.

Persistence: закрепление в системе

-- Свежие systemd-юниты, добавленные за последние 7 дней
SELECT s.name, s.path, s.source_path, f.mtime, datetime(f.mtime,'unixepoch') AS modified
FROM systemd_units s
JOIN file f ON s.path = f.path
WHERE f.mtime > (strftime('%s','now') - 7*86400)
  AND s.source_path NOT LIKE '/lib/%'
  AND s.source_path NOT LIKE '/usr/lib/%';

-- Cron-задачи всех пользователей
SELECT c.command, c.path, c.event, u.username
FROM crontab c
LEFT JOIN users u ON c.path LIKE '%/'||u.username||'/%';

-- Модификации ~/.bashrc и ~/.profile
SELECT uid, path, mtime FROM file
WHERE path LIKE '/home/%/.bashrc' OR path LIKE '/home/%/.profile'
ORDER BY mtime DESC;

Аномальные процессы

-- Процессы, чей бинарник удалён с диска (rootkit / memfd_create)
SELECT pid, name, path, cmdline, on_disk
FROM processes WHERE on_disk = 0;

-- Процессы, запущенные из /tmp, /dev/shm, /var/tmp
SELECT pid, name, path, cmdline
FROM processes
WHERE path LIKE '/tmp/%' OR path LIKE '/dev/shm/%' OR path LIKE '/var/tmp/%';

-- Reverse shells: netcat, socat, bash -i с pipe
SELECT p.pid, p.name, p.cmdline, s.remote_address, s.remote_port
FROM processes p
JOIN process_open_sockets s ON p.pid = s.pid
WHERE (p.cmdline LIKE '%bash -i%' OR p.name IN ('nc','ncat','socat'))
  AND s.remote_address NOT IN ('127.0.0.1','::1','0.0.0.0');

Свежие учётные записи и группы

-- Пользователи с UID 0, кроме root
SELECT username, uid, gid, shell, description
FROM users WHERE uid = 0 AND username != 'root';

-- Пользователи с валидным shell, созданные недавно (проверяем shadow.password_last_changed_at)
SELECT u.username, u.uid, u.shell, s.password_last_changed_at,
       datetime(s.password_last_changed_at,'unixepoch') AS pwd_changed
FROM users u
JOIN shadow s ON u.username = s.username
WHERE u.shell NOT IN ('/usr/sbin/nologin','/bin/false','/sbin/nologin')
ORDER BY s.password_last_changed_at DESC LIMIT 20;

Сетевые аномалии

-- Все внешние listening-порты с процессом-владельцем
SELECT DISTINCT p.name, p.pid, p.path, l.port, l.address
FROM listening_ports l JOIN processes p ON l.pid = p.pid
WHERE l.address NOT IN ('127.0.0.1','::1');

-- DNS-запросы за последний час (требует включённого dns_lookup_events)
SELECT time, hostname, response_code FROM dns_resolvers
WHERE time > (strftime('%s','now') - 3600);

Packs и покрытие MITRE ATT&CK

Packs, это модульные наборы запросов, поставляемые вместе с osquery в /usr/share/osquery/packs/. Основные:

  • incident-response.conf: 40+ запросов для расследования (rootkits, backdoors, persistence).
  • osx-attacks.conf и windows-attacks.conf: специфика для не-Linux, пропускаем.
  • ossec-rootkit.conf: сигнатуры известных Linux-руткитов (Adore-NG, Diamorphine, Reptile).
  • vuln-management.conf: устаревшие пакеты, отсутствующие патчи ядра, версии SSH/OpenSSL.
  • hardware-monitoring.conf: USB-устройства, PCI-девайсы, изменения BIOS.

Подключение pack'а в osquery.conf:

{
  "packs": {
    "incident-response": "/usr/share/osquery/packs/incident-response.conf",
    "ossec-rootkit": "/usr/share/osquery/packs/ossec-rootkit.conf",
    "vuln-management": "/usr/share/osquery/packs/vuln-management.conf"
  }
}

Многие запросы можно замапить на MITRE ATT&CK. Ниже реальное соответствие, которое я использую в детект-инженерии (не идеально, но покрывает 70% сценариев):

Техника ATT&CKНазваниеТаблица osquery
T1053.003Cron persistencecrontab
T1136.001Создание локальной учёткиusers, shadow, user_events
T1543.002systemd persistencesystemd_units
T1547.006Загружаемые модули ядраkernel_modules, kernel_info
T1055.009Proc-injection / memfdprocesses (WHERE on_disk = 0)
T1071.001C2 через HTTP/Sprocess_open_sockets, socket_events
T1562.001Отключение защитыselinux_settings, iptables

Fleet: управление парком endpoint'ов

Голый osqueryd прекрасен на 5 хостах, но на 500 нужен менеджер. Fleet, это open-source платформа (MIT) от fleetdm.com для управления osquery. В 2026 году актуальная версия 4.51, с поддержкой gitops-конфигурации, live queries по 100 000 хостов и интеграцией с Jira/Slack.

Быстрый запуск через Docker Compose:

services:
  mysql:
    image: mysql:8.4
    environment:
      MYSQL_ROOT_PASSWORD: rootpw
      MYSQL_DATABASE: fleet
    volumes: ["mysql:/var/lib/mysql"]
  redis:
    image: redis:7-alpine
  fleet:
    image: fleetdm/fleet:v4.51.0
    depends_on: [mysql, redis]
    environment:
      FLEET_MYSQL_ADDRESS: mysql:3306
      FLEET_MYSQL_DATABASE: fleet
      FLEET_MYSQL_USERNAME: root
      FLEET_MYSQL_PASSWORD: rootpw
      FLEET_REDIS_ADDRESS: redis:6379
      FLEET_SERVER_TLS: "true"
      FLEET_SERVER_CERT: /etc/fleet/tls.crt
      FLEET_SERVER_KEY: /etc/fleet/tls.key
    ports: ["8080:8080"]
    volumes: ["./tls:/etc/fleet"]
volumes:
  mysql:

Регистрация agent'а через fleetctl:

# На сервере Fleet
fleetctl package --type=deb --fleet-url=https://fleet.example.com:8080 \
  --enroll-secret=$(fleetctl get enroll-secret | awk '{print $2}')

# Полученный deb-пакет ставим на endpoint
sudo dpkg -i fleet-osquery_1.35.0_amd64.deb
sudo systemctl enable --now orbit

Через Fleet UI или fleetctl вы можете запускать live-query на любой группе хостов, планировать recurring-запросы, версионировать packs в git и получать compliance-отчёты по CIS Benchmarks. Для команды с Kubernetes-компетенцией Fleet ставится через официальный Helm chart и хорошо соседствует с Falco для обнаружения угроз на eBPF.

Интеграция с Wazuh, Elastic и Splunk

osquery по умолчанию пишет результаты запросов в /var/log/osquery/osqueryd.results.log, построчный JSON, идеальный вход для любого лог-шиппера.

Filebeat → Elasticsearch

filebeat.inputs:
- type: filestream
  id: osquery-results
  paths:
    - /var/log/osquery/osqueryd.results.log
  parsers:
    - ndjson:
        keys_under_root: true
        add_error_key: true
output.elasticsearch:
  hosts: ["https://elastic.example.com:9200"]
  index: "osquery-%{+yyyy.MM.dd}"

Wazuh

Wazuh 4.9 включает штатный osquery-модуль. В ossec.conf:

<wodle name="osquery">
  <disabled>no</disabled>
  <run_daemon>yes</run_daemon>
  <log_path>/var/log/osquery/osqueryd.results.log</log_path>
  <config_path>/etc/osquery/osquery.conf</config_path>
</wodle>

После рестарта агента результаты появятся в Wazuh с тэгом osquery и попадут в правила 24000–24009. Дальше корреляция как обычно.

Splunk

Universal Forwarder читает тот же файл; source type osquery:results есть в Splunk Add-on for osquery (SPL-2). Ротацию логов делайте через /etc/logrotate.d/osquery, иначе файл на активном хосте вырастает до 500 МБ/сутки. Я как-то забыл про logrotate на dev-стенде, и через десять дней /var был на 100%. Классика.

osquery vs auditd vs Falco: что выбрать

Частый вопрос от команд, которые уже деплоят один из трёх инструментов. Короткий ответ: они не заменяют друг друга. У каждого своя ниша.

ХарактеристикаosqueryauditdFalco
МодельSQL по snapshot'уПоток событий ядраRuntime-правила eBPF
Latency детектаМинуты (schedule)СекундыМиллисекунды
Оверхед CPU1–3%3–8%2–5%
Порог входаНизкий (SQL)Высокий (audit-rules)Средний (YAML DSL)
KubernetesДа, через DaemonSetОграниченноОтлично, нативно
Compliance-отчётыОтлично (CIS, PCI)ХорошоСлабо
Response actionsНетНетЧерез plugins

В моей практике на Flatcar-кластере в Лагосе стек выглядит так. Falco ловит runtime-аномалии в контейнерах (spawned shell, mount /proc). osquery через Fleet отдаёт compliance-отчёты и глубокие расследования по инцидентам. auditd оставлен только на bare-metal хостах для PCI-DSS-совместимости (стандарт явно требует его). Wazuh собирает всё воедино и делает алертинг.

Типичные ошибки при внедрении

За три года операционализации osquery на 800+ хостах я собрал типичный список граблей:

  • Слишком частые schedule-запросы. Опрос всех processes раз в минуту на хосте с 500 процессами даёт 500 записей/мин × 800 хостов = 24 млн событий/час в SIEM. Ставьте интервалы 5–30 минут, для FIM используйте file_events (event-driven).
  • Забытая ротация логов. Файл osqueryd.results.log без logrotate заполняет /var за неделю. Пример конфигурации: rotate 14, daily, compress, postrotate: pkill -HUP osqueryd.
  • Конфликт с auditd. На одной машине активен только один слушатель netlink-audit. Проверяйте: ss -f netlink | grep AUDIT.
  • Игнорирование performance-мониторинга. Таблица osquery_schedule сама сообщает время выполнения каждого запроса. Запрос, который стабильно уходит за 1 секунду, кандидат на выкидывание или оптимизацию.
  • Отсутствие TLS для Fleet. Live-query по HTTP означает, что кто-то в сети может форсировать выполнение произвольных SQL-запросов на всех endpoint'ах. Только TLS + client-cert-mTLS или enroll-secret с ротацией.

Часто задаваемые вопросы

Для чего используется osquery?

osquery используется для инвентаризации endpoint'ов, поиска аномалий, расследования инцидентов и compliance-аудита (CIS, PCI-DSS, HIPAA). Он превращает состояние Linux/macOS/Windows в SQL-таблицы, к которым можно писать запросы вручную или по расписанию.

osquery, это бесплатно?

Да, osquery полностью бесплатен и распространяется под лицензией Apache 2.0. Fleet-менеджер также open-source (MIT); коммерческая версия Fleet Premium добавляет SSO, гранулярные роли и SLA-поддержку от fleetdm.com.

Может ли osquery заменить Wazuh или auditd?

Нет. osquery, это инструмент для SQL-запросов к состоянию системы, у него нет собственного алертинга, корреляции и response-действий. Wazuh делает SIEM/HIDS-функции, auditd отвечает за низкоуровневый audit ядра. На практике эти инструменты работают вместе: osquery отвечает за глубину, Wazuh за корреляцию, auditd за compliance.

Как установить osquery на Ubuntu 24.04?

Подключите официальный APT-репозиторий с ключом 1484120AC4E9F8A1A577AEEE97A80C63C9D8B80B, выполните apt install osquery и запустите systemctl enable --now osqueryd. Для интерактивных запросов используйте osqueryi.

Сколько ресурсов потребляет osquery на сервере?

По моим замерам на Flatcar-нодах: 40–120 МБ RSS и 1–3% CPU в среднем при schedule-интервалах 15+ минут. Пиковая нагрузка приходит на моменты выполнения тяжёлых запросов (например, полное сканирование file по /etc), но благодаря schedule_splay_percent нагрузка распределяется по времени.

Какой лог osquery отправлять в SIEM?

Основной файл: /var/log/osquery/osqueryd.results.log, построчный JSON с результатами schedule-запросов, готовый к парсингу Filebeat, Fluent Bit или Vector. Дополнительно можно шипить osqueryd.snapshots.log (для snapshot-запросов) и osqueryd.INFO для отладки.

Об авторе Adaeze Okonkwo

Adaeze runs platform security at a Series C fintech in Lagos, where she spent the last three years migrating a sprawling Debian estate to immutable Flatcar nodes on bare-metal Kubernetes. Before that she was a senior SRE at Andela for five years and did a two-year stint at Interswitch hardening PCI-DSS Linux hosts the old-fashioned way - Lynis scans, Bastille, and a lot of shell scripts that probably shouldn't have existed. She holds OSCP, CKS, and is one of the few people who has actually read the entire CIS Debian 12 benchmark cover to cover. She maintains a public set of OpenSCAP profiles tuned for African ISP environments where bandwidth assumptions matter. Adaeze writes about the operational side of Linux security: SSH key rotation that actually happens, log shipping that survives a reboot, and incident response runbooks people will read at 3am.