Правила аудита

Правила делятся на следующие блоки:

  • Настройка фреймворка системы аудита (см. Конфигурация фреймворка);

  • Правила-исключения;

  • Правила для слежения за системными вызовами;

  • Правила для слежения за доступом к файлам и каталогам (на самом деле это тоже слежение за системными вызовами, только их подстановка выполняется фреймворком, подробности описаны далее).

Правила передаются на вход auditctl, в том же виде их можно записывать в каталоге /etc/audit/rules.d/*.rules.

При создании правил желательно размещать их в следующем порядке, хоть auditctl и выполнит минимальную сортировку самостоятельно:

[1-ая часть настроек системы аудита]
## CONTROL
-D
-b 8192
[...]

[исключения для списков TASK,EXIT,USER,FILESYSTEM идут первыми]
## EXCEPTIONS
-a never,exit -F arch=b64 -S execve,execveat -F exe=/usr/bin/hindsight
[...]

[слежение за системными вызовами - списки TASK,EXIT]
## SYSCALL
-a always,exit -F arch=b64 -S execve,execveat -F auid=0 -F key=execroot
[...]

[слежение за обращениями к файлам и каталогам - список EXIT]
## WATCH
-a always,exit -F path=/etc/passwd -F perm=wa
-a always,exit -F path=/etc/shadow -F perm=wa
[...]

[2-ая часть настроек системы аудита]
## CONTROL
-e 1

Слежение за системными вызовами

Синтаксис:
-a action,list [-F arch=b64|b32] -S syscall -F field=value -C field=field -F key=key_name

-a: добавить правило в конец списка;
action: действие, выполняемое при выполнении всех условий правила:

  • always - после выхода из сис. вызова записать событие аудита;

  • never - не записывать событие аудита.

list: наименование списка, в который заносится правило аудита:

  • task - доступен после создания процесса родителем с помощью вызова clone() или fork();

  • user - для исключения событий, поступающих из пространства пользователя (userspace);

  • filesystem - список, применяемый глобально для типа файловой системы;

  • exit - список, применяемый после выхода из системного вызова;

  • exclude - для исключения по типам записи.

-F arch: ставить перед -S syscall. Возможные значения:

  • b64, x86_64;

  • b32, i386.

В дистрибутивах с поддержкой запуска 64-х и 32-битных приложений номер одного и того же системного вызова может различаться. На примере сис. вызова execve в CentOS 7.7 x86_64:

# ausyscall x86_64 --exact execve
59

# ausyscall i386 --exact execve
11

# ausyscall i386 59
oldolduname

Без указания поля arch в правиле, номер сис. вызова execve будет взят из таблицы системных вызовов для текущей архитектуры x86_64, и этот же номер (59) будет отслеживаться для другой архитектуры, то есть для i386 отслеживаться будет вообще другой сисколл oldolduname. auditctl выдаст предупреждение WARNING - 32/64 bit syscall mismatch, you should specify an arch и тем не менее применит правило. Перед указанием сис. вызова нужно указывать архитектуру в поле arch; для отслеживания сискола для двух архитектур использовать "двойное правило": одно для b64, другое для b32, например:

# Executables
-a always,exit -F arch=b64 -S execve -F key=sc_execve
-a always,exit -F arch=b32 -S execve -F key-sc_execve

-S syscall: имя или номер системного вызова, который необходимо отслеживать.

Удобнее использовать имя сисколла, чтобы утилита auditctl сама отрезолвила его номер при загрузке правила. Список всех системных вызовов для архитектур x86_64 и i386 можно посмотреть командой ausyscall [ x86_64 || i386 ] --dump.

Можно указать несколько сис. вызовов в одном правиле через запятую или с помощью нескольких опций -S:

-a always,exit -F arch=b64 -S execve,execveat

равнозначно

-a always,exit -F arch=b64 -S execve -S execveat

Если требуется соблюдать совместимость правил аудита со старыми версиями auditctl, то применимо использовать синтаксис -S syscall1 -S syscall2

Правило, содержащее несколько отслеживаемых сисколлов, отработает быстрее чем несколько правил по отдельности:

-a always,exit -F arch=b64 -S execve,execveat

быстрее чем

-a always,exit -F arch=b64 -S execve
-a always,exit -F arch=b64 -S execveat

Для каждого системного вызова система аудита записывает первые переданные ему 4 аргумента - значение соответствующего аргумента доступно в полях a0..a3 в виде hex-значения, над которым, помимо стандартных операций сравнения, могут также выполняться операции bit-mask или bit-test.

Для примера - необходимо  отследить операцию монтирования с опцией bind. За монтирование отвечает системный вызов mount, которому в 4-ом аргументе (a3=) вместе с прочими флагами передаётся флаг MS_BIND равный 4096 (hex=0x1000). Для того чтобы проверить, имеется ли данный флаг в переданном аргументе, используем bit mask:

-a always,exit -F arch=b64 -S mount -F a3&0x1000 -k sc_mountbind

-F [f=v | f!=v | f<v | f>v | f⇐v | f>=v | f&v | f&=v]: создать условие правила, сравнив содержимое поля f и значение v.

Отдельно стоит отметить поле auid, это поле часто используется в правилах для фильтрации процессов пользователя, интерактивно вошедшего в систему. loginuid, audit uid, auid - это всё один и тот же идентификатор.

Для фильтрации неинтерактивных процессов (демонов) можно встретить разные по записи, но одинаковые по значению условия: -F auid=unset == -F auid=-1 == -F auid=4294967295.

Примеры:

-F auid=0 используется для фильтрации процессов, запущенных вошедшим в систему root’ом;
-F auid>=1000 -F auid!=unset используется для фильтрации процессов непривилегированных пользователей. В RHEL 6 пользовательские UID’ы начинаются с 500 (UID_MIN): -F auid>=500 -F auid!=unset

-C [f=f | f!=f]: создать условие правила, сравнив два поля.

-F key=key_name: навесить метку key_name на правило аудита, а также на сгенерированное событие в случае успешной отработки правила. Для правил-исключений метку не ставят.

Действие по правилу выполнится только в том случае, если все условия типа -F и -C истинны - для них применяется логический оператор И.

Для условий, требующих оператора ИЛИ, необходимо написать несколько правил с одинаковой меткой в поле key=.

Исключения

Примеры исключений для каждого списка:

Не следить за системными вызовами всех процессов, запущенных от UID couchbase.

-a never,task -F uid=couchbase

Не журналировать тип записи USYS_CONFIG на этапе принятие сообщения аудита от userspace-приложения:

-a never,user -F msgtype=USYS_CONFIG

Не журналировать события для файловых систем типа tracefs и debugfs так как иначе система аудита получает события от ФС данных типов при загрузке или выгрузке модулей ядра:

-a never,filesystem -F fstype=tracefs
-a never,filesystem -F fstype=debugfs

Не журналировать определённые системные вызовы при их запросе указанной в поле exe= программой:

-a never,exit -F arch=b64 -S execve,execveat -F exe=/usr/bin/hindsight
-a never,exit -F arch=b32 -S execve,execveat -F exe=/usr/bin/hindsight

Слежение за файловой системой

Cинтаксис:

-a always,exit -F (path|dir)=/path/to/file/or/dir -F perm=rwxa -k key

При наличии в правиле поля path= или dir= система аудита активирует слежение за доступом к inode указанного файла/каталога:

path=/path/to/file следит за inode файла.

Tip
Символическая ссылка является отдельным файлом с собственным inode поэтому нужно следить за файлом/каталогом, на который указывает ссылка.

path=/path/to/dir следит за указанным каталогом и его дочерними объектами, без рекурсии.
dir=/path/to/dir рекурсивно следит за указанным каталогом.

Tip
Если дочерний объект отслеживаемого правилом каталога является точкой монтирования и правило аудита -q <точка монтирования> отсутствует - слежение за примонтированным каталогом не производится. Например, рекурсивное слежение за записью в каталог /mnt, в котором примонтирован раздел /mnt/backup, будет генерировать события по всем вложенным объектам, кроме /mnt/backup, пока в правилах не указать -q /mnt/backup.

perm= определяет так называемые "модификаторы", каждому из которых соответствует отслеживаемое действие с inode: r - чтение; w - запись; a - изменение атрибутов; x - исполнение.

Каждый модификатор отражает группу системных вызовов, во время выполнения которых система аудита собирает список inode с которыми сисколлы взаимодействуют, и затем сравнивает со списком отслеживаемых inode в правиле.

В таблице приведено соответствие модификаторов и подставляемых ядром системных вызовов для архитектуры x86_64.

Таблица 1. Соответствие модификаторов системным вызовам
perm= Системные вызовы

r

open с флагом O_RDONLY
getxattr, lgetxattr, fgetxattr
listxattr, llistxattr, flistxattr
readlink, readlinkat
quotactl

w

open с флагом O_WRONLY
creat
link, linkat
mkdir, mkdirat, rmdir
mknod, mknodat
rename, renameat, renameat2
symlink, symlinkat
unlink, unlinkat

a

chmod, fchmod, fchmodat
chown, fchown, lchown, fchownat
link, linkat
removexattr, lremovexattr, fremovexattr
setxattr, lsetxattr, fsetxattr

x

execve, execveat

При слежении за доступом к файлам и каталогам система аудита также использует API подсистемы fsnotify, которая сообщает фреймворку аудита об изменениях, связанных с отслеживаемыми объектами. Так, при создании каталога в уже рекурсивно отслеживаемой директории, система аудита перестроит список наблюдаемых inode, включив в него созданный каталог.
В текущей реализации есть и обратная сторона - при удалении каталога, который отслеживается в правиле аудита, система аудита также удалит правило из текущих правил фреймворка. Повторное создание каталога не приведёт к возвращению правила, поможет только самостоятельное добавление правила или рестарт демона auditd, чтобы он перечитал правила с диска.