F.27. pgAudit — подробное журналирование аудита сессий и/или объектов#

F.27. pgAudit — подробное журналирование аудита сессий и/или объектов

F.27. pgAudit — подробное журналирование аудита сессий и/или объектов #

Версия: 18.0

F.27.1. Обзор #

pgAudit предоставляет детализированное журналирование аудита сессий и/или объектов через стандартное средство журналирования Tantor BE.

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

F.27.2. Почему pgAudit? #

Базовое ведение журнала операций может быть обеспечено стандартным механизмом ведения журнала с помощью параметра log_statement = all. Это приемлемо для мониторинга и других случаев использования, но не обеспечивает необходимого уровня детализации для аудита. Недостаточно иметь список всех операций, выполненных в отношении базы данных. Также необходимо иметь возможность найти конкретные операторы, которые представляют интерес для аудитора. Стандартный механизм ведения журнала показывает, что запросил пользователь, в то время как pgAudit фиксирует детали того, что произошло, пока база данных выполняла запрос.

Например, аудитор проверяет, была ли определенная таблица создана внутри задокументированного окна обслуживания. Это может показаться простой задачей для grep, но что, если вам представлено что-то вроде этого (мы выбрали специально усложненный вариант):

DO $$
BEGIN
    EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;

Стандартный механизм ведения журнала предоставит вам следующую информацию:

LOG:  statement: DO $$
BEGIN
    EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;

Похоже, что для поиска нужной таблицы, в случаях, когда таблицы создаются динамически, может потребоваться некоторое знание кода. Это не идеальный вариант, поскольку предпочтительнее просто искать по имени таблицы. Вот где приходит на помощь pgAudit. В примере выше, он выдаст следующие данные из журнала:

AUDIT: SESSION,33,1,FUNCTION,DO,,,"DO $$
BEGIN
    EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;"
AUDIT: SESSION,33,2,DDL,CREATE TABLE,TABLE,public.important_table,CREATE TABLE important_table (id INT)

В журнал записывается не только блок DO, также подзапрос 2 содержит полный текст CREATE TABLE с типом оператора, типом объекта и полным именем для упрощения поиска.

При ведении журнала для операций SELECT и DML , pgAudit можно настроить на регистрацию отдельной записи для каждой связанной с операцией таблицы. Для поиска всех операций, которые затрагивают определенную таблицу не нужен разбор. Фактически, цель состоит в том, чтобы текст операции предоставлялся в основном для глубокого анализа и не требовался для аудита.

F.27.3. Рекомендации по использованию #

В зависимости от настроек, pgAudit может генерировать огромный объем записей в журнал. Важно точно определить, что нужно регистрировать в журнале аудита в вашей среде, чтобы избежать раздутия журналов.

Например, при работе в среде OLAP, вероятно, не стоит регистрировать записи журнала аудита в большую таблицу фактов. Размер журнала вероятно будет в несколько раз больше фактического размера данных записей, потому что файл журнала представляет собой текст. Поскольку журналы обычно хранятся вместе с ОС, дисковое пространство может быстро закончится. В случаях, когда невозможно ограничить регистрацию определенными таблицами, обязательно оцените его влияние на производительность во время тестирования и выделите достаточно места под журнал. Это также может касаться среды OLTP. Даже если объем записей не так велик, ведение журнала аудита все равно может вызывать заметные задержки.

Чтобы ограничить количество отслеживаемых отношений для операторов SELECT и DML, рассмотрите возможность ведения журнала аудита объектов (см. ведение журнала объектов). Ведение журнала аудита объектов позволяет выбирать отслеживаемые отношения, что позволяет сократить общий объем журнала. Однако, при добавлении новых связей, их необходимо явно указать для ведение журнала аудита объектов. В этом случае хорошим вариантом может быть программное решение, при котором указанные таблицы исключаются из журналирования, а по всем остальным ведется журнал.

При использовании функции маркировки событий учитывайте, что правила маркировки оцениваются для каждого события, подлежащего аудиту, что может добавить некоторую нагрузку на производительность. Используйте конкретные правила, нацеленные только на интересующие события, чтобы минимизировать это влияние.

F.27.4. Tantor BE Совместимость версий #

pgAudit поддерживает PostgreSQL 12 или выше.

Для поддержки новой функциональности, вводимой в каждом выпуске Tantor BE, pgAudit поддерживает отдельную ветку для каждой основной версии Tantor BE, которая будет сопровождаться аналогично проекту PostgreSQL.

Помимо исправления ошибок, дальнейшая разработка для стабильных веток не допускается. Новая разработка, если таковая будет, будет строго для следующей не выпущенной основной версии PostgreSQL.

F.27.5. Настройки #

Настройки могут быть изменены только суперпользователем. Предоставление обычным пользователя возможности изменять свои настройки противоречит цели файла аудита.

Настройки можно указать глобально (в файле postgresql.conf или с помощью ALTER SYSTEM ... SET), на уровне базы данных (с помощью ALTER DATABASE ... SET) или на уровне роли (с помощью ALTER ROLE ... SET). Обратите внимание, что настройки не наследуются через обычное наследование ролей и команда SET ROLE не изменит пользовательские настройки pgAudit. Это ограничение системы ролей, а не расширения pgAudit.

Расширение pgAudit должно быть загружено в shared_preload_libraries. В противном случае при загрузке будет вызвана ошибка, и аудит не будет выполняться.

Кроме того, CREATE EXTENSION pgaudit должен быть вызван до установки pgaudit.log, чтобы обеспечить правильную функциональность pgaudit. Расширение устанавливает триггеры событий, которые добавляют дополнительный аудит для DDL. pgAudit будет работать без установленного расширения, но операторы DDL не будут иметь информации о типе и имени объекта.

Если расширение pgaudit удалено и его нужно воссоздать, то сначала необходимо отменить установку pgaudit.log, иначе будет вызвана ошибка.

F.27.5.1. pgaudit.log #

Определяет, какие классы операторов будут записываться в журнал аудита сессии. Возможные значения:

  • READ: SELECT и COPY, когда источник - это отношение или запрос.

  • WRITE: INSERT, UPDATE, DELETE, TRUNCATE, и COPY, когда назначение - это отношение.

  • FUNCTION: Вызовы функций и блоки DO.

  • ROLE: Операторы, связанные с ролями и привилегиями: GRANT, REVOKE, CREATE/ALTER/DROP ROLE.

  • DDL: Все DDL, которые не включены в ROLE класс.

  • MISC: Разные команды, например, DISCARD, FETCH, CHECKPOINT, VACUUM, SET.

  • MISC_SET: Разные команды SET, например, SET ROLE.

  • ALL: Включить все вышеупомянутое.

Несколько классов можно указать с помощью списка через запятую, и классы можно вычитать, написав перед классом знак - (см. ведение журнала аудита сессии).

По умолчанию используется none.

F.27.5.2. pgaudit.log_catalog #

Указывает, что регистрация сессии должна быть включена в случае, если все отношения в операторе находятся в pg_catalog. Отключение этой настройки снизит шум в журнале от таких инструментов, как psql и PgAdmin, которые интенсивно запрашивают каталог.

По умолчанию значение on.

F.27.5.3. pgaudit.log_client #

Определяет, будут ли сообщения журнала видны клиентскому процессу типа psql. Эта настройка обычно должна быть отключена, но может быть полезна для отладки или других целей.

Обратите внимание, что pgaudit.log_level включается только когда включен ( on) pgaudit.log_client.

По умолчанию - отключено ( off).

F.27.5.4. pgaudit.log_level #

Указывает уровень журнала, который будет использоваться для записей в журнал (см. Уровни серьезности сообщений для допустимых уровней), но обратите внимание, что ERROR, FATAL и PANIC не разрешены). Этот параметр используется для регрессионного тестирования и может также быть полезен конечным пользователям для тестирования или других целей.

Обратите внимание, что pgaudit.log_level включается только когда включен ( on) pgaudit.log_client; в противном случае будет использовано значение по умолчанию.

По умолчанию используется log.

F.27.5.5. pgaudit.log_parameter #

Указывает, что ведение журнала аудита должно включать параметры, которые были переданы вместе с оператором. Когда параметры присутствуют, они будут включены в формате CSV после текста оператора.

По умолчанию - отключено ( off).

F.27.5.6. pgaudit.log_parameter_max_size #

Указывает, что значения параметров, длина которых превышает это значение (в байтах), не должны записываться в журнал, а заменяться на <long param suppressed>. Это значение устанавливается в байтах, а не в символах, поэтому не учитывает многобайтовые символы в кодировке текстовых параметров. Эта настройка не работает, если log_parameter установлено в off. Если это значение равно 0 (по умолчанию), все параметры записываются в журнал независимо от длины.

По умолчанию 0.

F.27.5.7. pgaudit.log_relation #

Определяет, должно ли ведение журнала аудита сессии создавать отдельную запись журнала для каждого отношения (TABLE, VIEW и т. д.), на которое ссылается оператор SELECT или DML. Это полезный сокращенный вариант для исчерпывающей регистрации без ведение журнала аудита объектов.

По умолчанию - отключено ( off).

F.27.5.8. pgaudit.log_rows #

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

По умолчанию - отключено ( off).

F.27.5.9. pgaudit.log_statement #

Определяет, будут ли регистрироваться текст запроса и параметры в журнале (если включено). В зависимости от ситуаций, для журнала аудита эти данные могут не требоваться, что делает журналы менее детальными.

По умолчанию значение on.

F.27.5.10. pgaudit.log_statement_once #

Определяет, будет ли в журнале регистрироваться текст и параметры оператора вместе с первой записью журнала для связи запрос/подзапрос или вместе с каждой записью. Отключение этой настройки приведет к более сжатому ведению журнала, но может затруднить определение запроса, который сгенерировал запись в журнале, хотя пара запрос/подзапрос вместе с идентификатором процесса должны быть достаточными для идентификации текста запроса, зарегистрированного с предыдущей записью.

По умолчанию - отключено ( off).

F.27.5.11. pgaudit.role #

Указывает главную роль, которую следует использовать для ведения журнала аудита объектов. Можно определить несколько ролей аудита, предоставив их главной роли. Это позволяет нескольким группам отвечать за различные аспекты ведения журнала аудита.

Нет значения по умолчанию.

F.27.5.12. pgaudit.marking_rules_enabled #

Включает функцию маркировки событий. При включении события аудита будут сопоставляться с настроенными правилами маркировки и избирательно записываться в отдельный журнал маркировки в формате CSV.

Этот параметр требует настройки pgaudit.marking_log_directory и pgaudit.marking_log_filename.

По умолчанию - отключено ( off).

F.27.5.13. pgaudit.marking_rules_max #

Указывает максимальное количество правил маркировки, которые могут быть определены. Этот параметр определяет объем разделяемой памяти, выделяемой для системы правил маркировки при запуске сервера.

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

По умолчанию используется значение 1000.

F.27.5.14. pgaudit.marking_log_directory #

Указывает каталог, в котором будут создаваться файлы журнала маркировки. Этот каталог должен существовать и быть доступным для записи процессом сервера PostgreSQL. Путь может быть абсолютным или относительным по отношению к каталогу данных PostgreSQL.

Этот параметр обязателен, когда pgaudit.marking_rules_enabled установлен в on.

Нет значения по умолчанию.

F.27.5.15. pgaudit.marking_log_filename #

Указывает шаблон имени файла для маркировки файлов журнала. Шаблон может включать экранирования в стиле strftime, которые будут заменены на основе текущего времени, аналогично стандартным шаблонам имен файлов журнала PostgreSQL.

Например, pgaudit_marking_%Y%m%d.csv создаст ежедневные файлы журнала, такие как pgaudit_marking_20240101.csv.

Этот параметр обязателен, когда pgaudit.marking_rules_enabled установлен в on.

Нет значения по умолчанию.

F.27.6. Ведение журнала аудита сессии #

Ведение журнала аудита сессии обеспечивает детальную регистрацию всех операторов, выполненных пользователем в бэкенде.

F.27.6.1. Конфигурация #

Ведение журнала сессии включается через настройку pgaudit.log.

Включить ведение журнала сессии для всех операций DML и DDL и записывать все отношения в операторах DML:

set pgaudit.log = 'write, ddl';
set pgaudit.log_relation = on;

Включить ведение журнала сессии для всех команд, кроме MISC и выводить сообщения аудита в журнал с уровнем NOTICE:

set pgaudit.log = 'all, -misc';
set pgaudit.log_level = notice;

F.27.6.2. Пример #

В этом примере используется ведение журнала аудита сессии для регистрации операторов DDL и SELECT. Обратите внимание, что оператор insert не регистрируется, так как класс WRITE не включен.

SQL:

set pgaudit.log = 'read, ddl';

create table account
(
    id int,
    name text,
    password text,
    description text
);

insert into account (id, name, password, description)
             values (1, 'user1', 'HASH1', 'blah, blah');

select *
    from account;

Вывод журнала:

AUDIT: SESSION,1,1,DDL,CREATE TABLE,TABLE,public.account,create table account
(
    id int,
    name text,
    password text,
    description text
);,<not logged>
AUDIT: SESSION,2,1,READ,SELECT,,,select *
    from account,,<not logged>

F.27.7. Ведение журнала аудита объектов #

Журналы аудита объектов регистрируют операторы, которые влияют на конкретное отношение. Поддерживаются только SELECT, INSERT, UPDATE и DELETE . Команда TRUNCATE не включается в журнал аудита объектов.

Ведение журнала аудита объектов предназначено как более детальная альтернатива параметра pgaudit.log = 'read, write'. Поэтому, возможно, не имеет смысла использовать их совместно, но один из возможных сценариев - использовать регистрацию сессии для записи каждого оператора, а затем дополнить его регистрацией объектов для получения более подробной информации о конкретных отношениях.

F.27.7.1. Конфигурация #

Ведение журнала аудита объектов реализуется через систему ролей. Настройка pgaudit.role определяет роль, которая будет использоваться для аудита. Отношение (TABLE, VIEW, и т. д.) будет записано в журнал аудита, когда соответствующая роль аудитора имеет разрешения для выполненной команды или наследует разрешения от другой роли. Это позволяет эффективно совмещать несколько аудиторских ролей, даже если есть одна основная роль во всех контекстах.

Установите pgaudit.role в значение auditor и предоставьте привилегии SELECT и DELETE на таблицу account. Любые операторы SELECT или DELETE на таблице account теперь будут записываться в журнал:

set pgaudit.role = 'auditor';

grant select, delete
   on public.account
   to auditor;

F.27.7.2. Пример #

В этом примере используется ведение журнала аудита объектов чтобы продемонстрировать, как можно применить детализированный подход к регистрации операторов SELECT и DML. Обратите внимание, что ведение журнала на таблице account контролируется разрешениями на уровне столбцов, в то время как ведение журнала на таблице account_role_map происходит на уровне таблицы.

SQL:

create role auditor;

set pgaudit.role = 'auditor';

create table account
(
    id int,
    name text,
    password text,
    description text
);

grant select (password)
   on public.account
   to auditor;

select id, name
  from account;

select password
  from account;

grant update (name, password)
   on public.account
   to auditor;

update account
   set description = 'yada, yada';

update account
   set password = 'HASH2';

create table account_role_map
(
    account_id int,
    role_id int
);

grant select
   on public.account_role_map
   to auditor;

select account.password,
       account_role_map.role_id
  from account
       inner join account_role_map
            on account.id = account_role_map.account_id

Вывод журнала:

AUDIT: OBJECT,1,1,READ,SELECT,TABLE,public.account,select password
  from account,<not logged>
AUDIT: OBJECT,2,1,WRITE,UPDATE,TABLE,public.account,update account
   set password = 'HASH2',<not logged>
AUDIT: OBJECT,3,1,READ,SELECT,TABLE,public.account,select account.password,
       account_role_map.role_id
  from account
       inner join account_role_map
            on account.id = account_role_map.account_id,<not logged>
AUDIT: OBJECT,3,1,READ,SELECT,TABLE,public.account_role_map,select account.password,
       account_role_map.role_id
  from account
       inner join account_role_map
            on account.id = account_role_map.account_id,<not logged>

F.27.8. Маркировка событий #

Маркировка событий — это расширенная функция, которая обеспечивает детальный контроль над тем, какие аудируемые события отслеживаются и как они обрабатываются. В отличие от стандартного аудита, который фиксирует все события на основе конфигурации класса или роли, маркировка событий позволяет избирательно помечать определённые события на основе настраиваемых правил, соответствующих базе данных, типу события, типу объекта, имени объекта и ролям.

Когда маркировка событий включена, отмеченные события записываются в отдельный CSV-файл, указанный с помощью pgaudit.marking_log_directory и pgaudit.marking_log_filename. Такое разделение облегчает обработку и анализ событий, связанных с безопасностью.

F.27.8.1. Обзор #

Система маркировки событий состоит из трех основных компонентов:

  • Правила маркировки: настраиваемые правила, определяющие, какие события должны быть помечены на основе базы данных, типа события, типа объекта, имени объекта и ролей.

  • SQL-функции управления правилами: функции для добавления, удаления и просмотра правил маркировки во время выполнения. Все функции находятся в схеме pgaudit_marking.

  • Журнал маркировки: отдельный CSV-файл журнала, содержащий только отмеченные события с дополнительной контекстной информацией.

F.27.8.2. Поддерживаемые типы событий #

Система маркировки событий поддерживает следующие типы событий. Они представляют собой конкретные SQL-команды, которые могут быть сопоставлены с правилами маркировки:

События аутентификации и сессии: AUTHENTICATE, DISCONNECT

Операции DDL: ALTER AGGREGATE, ALTER COLLATION, ALTER CONVERSION, ALTER DATABASE, ALTER DEFAULT PRIVILEGES, ALTER DOMAIN, ALTER EVENT TRIGGER, ALTER EXTENSION, ALTER FOREIGN DATA WRAPPER, ALTER FOREIGN TABLE, ALTER FUNCTION, ALTER INDEX, ALTER LANGUAGE, ALTER LARGE OBJECT, ALTER MATERIALIZED VIEW, ALTER OPERATOR, ALTER OPERATOR CLASS, ALTER OPERATOR FAMILY, ALTER POLICY, ALTER PROFILE, ALTER ROLE, ALTER USER, ALTER GROUP, ALTER RULE, ALTER SCHEMA, ALTER SEQUENCE, ALTER SERVER, ALTER SYSTEM, ALTER TABLE, ALTER TABLESPACE, ALTER TEXT SEARCH CONFIGURATION, ALTER TEXT SEARCH DICTIONARY, ALTER TEXT SEARCH PARSER, ALTER TEXT SEARCH TEMPLATE, ALTER TRIGGER, ALTER TYPE, ALTER USER MAPPING, ALTER VIEW

Операции CREATE: CREATE ACCESS METHOD, CREATE AGGREGATE, CREATE CAST, CREATE COLLATION, CREATE CONVERSION, CREATE DATABASE, CREATE DOMAIN, CREATE EVENT TRIGGER, CREATE EXTENSION, CREATE FOREIGN DATA WRAPPER, CREATE FOREIGN TABLE, CREATE FUNCTION, CREATE INDEX, CREATE LANGUAGE, CREATE MATERIALIZED VIEW, CREATE OPERATOR, CREATE OPERATOR CLASS, CREATE OPERATOR FAMILY, CREATE POLICY, CREATE PROFILE, CREATE ROLE, CREATE USER, CREATE GROUP, CREATE RULE, CREATE SCHEMA, CREATE SEQUENCE, CREATE SERVER, CREATE TABLE, CREATE TABLE AS, SELECT INTO, CREATE TABLESPACE, CREATE TEXT SEARCH CONFIGURATION, CREATE TEXT SEARCH DICTIONARY, CREATE TEXT SEARCH PARSER, CREATE TEXT SEARCH TEMPLATE, CREATE TRANSFORM, CREATE TRIGGER, CREATE TYPE, CREATE USER MAPPING, CREATE VIEW

Операции DROP: DROP ACCESS METHOD, DROP AGGREGATE, DROP CAST, DROP COLLATION, DROP CONVERSION, DROP DATABASE, DROP DOMAIN, DROP EVENT TRIGGER, DROP EXTENSION, DROP FOREIGN DATA WRAPPER, DROP FOREIGN TABLE, DROP FUNCTION, DROP INDEX, DROP LANGUAGE, DROP MATERIALIZED VIEW, DROP OPERATOR, DROP OPERATOR CLASS, DROP OPERATOR FAMILY, DROP OWNED, DROP POLICY, DROP PROFILE, DROP ROLE, DROP USER, DROP GROUP, DROP RULE, DROP SCHEMA, DROP SEQUENCE, DROP SERVER, DROP TABLE, DROP TABLESPACE, DROP TEXT SEARCH CONFIGURATION, DROP TEXT SEARCH DICTIONARY, DROP TEXT SEARCH PARSER, DROP TEXT SEARCH TEMPLATE, DROP TRANSFORM, DROP TRIGGER, DROP TYPE, DROP USER MAPPING, DROP VIEW

Операции DML: SELECT, INSERT, UPDATE, DELETE, TRUNCATE TABLE, COPY

Другие операции: CLUSTER, COMMENT, DEALLOCATE, DO, EXECUTE, GRANT, PREPARE, REASSIGN OWNED, REFRESH MATERIALIZED VIEW, REINDEX, RESET, REVOKE, SECURITY LABEL, SET

Поддерживаются следующие классы событий безопасности:

ALL_DDL: CREATE, ALTER, DROP для любого объекта базы данных, за исключением хранимых процедур и функций.

ALL_DML: SELECT, INSERT, UPDATE, DELETE, TRUNCATE для любых типов таблиц; EXECUTE для функций и хранимых процедур.

ALL_MOD: INSERT, UPDATE, DELETE, TRUNCATE для любых типов таблиц.

ALL_PROC: CREATE, ALTER, DROP для любых функций и хранимых процедур.

ALL_ROLE: CREATE, ALTER, DROP в отношении USER, ROLE, GROUP, PROFILE.

F.27.8.3. Поддерживаемые типы объектов #

Следующие типы объектов могут быть указаны в правилах маркировки для фильтрации событий по типу задействованного объекта базы данных:

TABLE, VIEW, MATERIALIZED VIEW, INDEX, SEQUENCE, SCHEMA, DATABASE, TABLESPACE, ROLE, FUNCTION, AGGREGATE, PROCEDURE, OPERATOR, OPERATOR CLASS, OPERATOR FAMILY, CAST, TRANSFORM, COLLATION, CONVERSION, LANGUAGE, DOMAIN, COMPOSITE TYPE, EVENT TRIGGER, EXTENSION, FOREIGN DATA WRAPPER, FOREIGN TABLE, SERVER, USER MAPPING, POLICY, RULE, TRIGGER, TEXT SEARCH CONFIGURATION, TEXT SEARCH DICTIONARY, TEXT SEARCH PARSER, TEXT SEARCH TEMPLATE, ACCESS METHOD, STATISTICS, PROFILE, CATALOG RELATION, CATALOG FUNCTION

F.27.8.4. SQL-интерфейс #

Система маркировки событий предоставляет несколько SQL-функций для управления правилами маркировки во время выполнения. Все функции находятся в схеме pgaudit_marking и требуют прав суперпользователя.

pgaudit_marking.set_rule( db_name text, event_type text, object_type text, object_name text, role_name text, comment text DEFAULT '' ) #

Добавляет новое правило маркировки. Правило сопоставляет аудиторские события на основе указанного имени базы данных, типа SQL-команды, типа объекта базы данных, имени объекта и имени роли.

Каждый параметр принимает специальные строковые значения 'ALL' и 'NULL'. Эти значения эквивалентны и указывают, что параметр не используется для сопоставления.

Параметры:

  • db_name — имя базы данных для сопоставления.

  • event_type — тип SQL-команды для сопоставления (например, CREATE TABLE, INSERT).

  • object_type — тип объекта базы данных для сопоставления (например, TABLE, VIEW).

  • object_name — имя объекта, при необходимости с указанием схемы.

  • role_name — имя роли.

  • comment — необязательный описательный комментарий для правила.

Функция возвращает true, если правило успешно добавлено.

Примеры:

-- Mark all CREATE TABLE events in the current database
SELECT pgaudit_marking.set_rule(
    current_database(),
    'CREATE TABLE',
    'TABLE',
    'NULL',
    'ALL',
    'Track table creation'
);

-- Mark DROP TABLE operations in a specific database for a specific role
SELECT pgaudit_marking.set_rule(
    'mydb',
    'DROP TABLE',
    'TABLE',
    'NULL',
    'admin',
    'Admin drops in sensitive schema'
);

-- Mark all operations on a specific table for all roles
SELECT pgaudit_marking.set_rule(
    'mydb',
    'NULL',
    'TABLE',
    'public.audit_log',
    'ALL',
    'All operations on audit log'
);
pgaudit_marking.remove_rule( db_name text, event_type text, object_type text, object_name text, role_name text, comment text DEFAULT '' ) #

Удаляет правило маркировки по его спецификации. Все параметры должны точно соответствовать существующему правилу, чтобы оно было удалено. Возвращает true, если правило было найдено и удалено, и false в противном случае.

Примеры:

-- Remove specific rule
SELECT pgaudit_marking.remove_rule(
    'mydb',
    'CREATE TABLE',
    'TABLE',
    'ALL',
    'ALL',
    'Track table creation'
);

-- Remove rule without comment (use empty string)
SELECT pgaudit_marking.remove_rule(
    'mydb',
    'DROP TABLE',
    'TABLE',
    'test',
    'postgres',
    ''
);
pgaudit_marking.show_rules() #

Возвращает все текущие настроенные правила маркировки в виде таблицы. Результирующий набор включает следующие столбцы: db_name, event_type, object_type, object_name, role_name, comment.

Примеры:

-- List all marking rules
SELECT * FROM pgaudit_marking.show_rules();

-- Find rules for specific database
SELECT * FROM pgaudit_marking.show_rules() 
WHERE db_name = 'mydb';

-- Find rules for specific event type
SELECT * FROM pgaudit_marking.show_rules() 
WHERE event_type = 'DROP TABLE';

-- Find rules with comments
SELECT * FROM pgaudit_marking.show_rules() 
WHERE comment != '';
pgaudit_marking.rules_conf_save() #

Сохраняет текущие правила маркировки в файл конфигурации на диск. Это позволяет правилам сохраняться после перезапуска сервера. Файл записывается в каталог данных PostgreSQL.

Пример:

-- Save current rules to configuration file
SELECT pgaudit_marking.rules_conf_save();
pgaudit_marking.rules_conf_reload() #

Перезагружает правила маркировки из файла конфигурации. Это полезно после ручного редактирования файла правил или после перезапуска сервера для восстановления ранее сохранённых правил.

Пример:

-- Reload rules from configuration file
SELECT pgaudit_marking.rules_conf_reload();
pgaudit_marking.rules_conf_reset() #

Удаляет все правила маркировки только из таблицы базы данных. Удаление всех правил в конфигурационном файле выполняется вручную администратором базы данных.

Пример:

-- Remove all marking rules from the rules table only
SELECT pgaudit_marking.rules_conf_reset();

F.27.8.5. Формат журнала маркировки #

События, соответствующие правилам маркировки, записываются в файл журнала маркировки в формате CSV со следующими столбцами:

  • timestamp - Временная метка события

  • session_user - Имя пользователя сессии

  • current_user - Текущий эффективный пользователь

  • database - Имя базы данных

  • pid - идентификатор процесса

  • client_addr - IP-адрес клиента

  • client_port - Порт клиента

  • application_name - Имя приложения

  • statement_id - Идентификатор оператора

  • substatement_id - Идентификатор подоператора

  • event_type - Тип события (например, CREATE TABLE)

  • object_type - Тип объекта (например, TABLE)

  • object_name - Квалифицированное имя объекта

  • query_text - Полный текст запроса

  • status - Статус события (OK, ERROR)

  • error_message - Сообщение об ошибке, если статус — ERROR

  • параметры - Параметры запроса, если они записаны в журнал

  • marked_by_rule - Правило, которое пометило это событие

Формат CSV позволяет легко импортировать данные в аналитические инструменты, базы данных или системы SIEM для дальнейшей обработки и корреляции.

F.27.8.6. Примеры #

Пример 1: Базовая настройка маркировки событий

Настройте PostgreSQL для включения маркировки событий:

-- In postgresql.conf
shared_preload_libraries = 'pgaudit'
pgaudit.marking_rules_enabled = on
pgaudit.marking_log_directory = '/var/log/postgresql/audit'
pgaudit.marking_log_filename = 'pgaudit_marking_%Y%m%d.csv'
pgaudit.marking_rules_max = 1000

После перезапуска PostgreSQL создайте расширение и добавьте правила маркировки:

-- Create pgaudit extension
CREATE EXTENSION IF NOT EXISTS pgaudit;

-- Mark all DDL operations on tables in current database
SELECT pgaudit_marking.set_rule(
    current_database(),
    'CREATE TABLE',
    'TABLE',
    'ALL',
    'ALL',
    'Track CREATE TABLE'
);
SELECT pgaudit_marking.set_rule(
    current_database(),
    'ALTER TABLE',
    'TABLE',
    'ALL',
    'ALL',
    'Track ALTER TABLE'
);
SELECT pgaudit_marking.set_rule(
    current_database(),
    'DROP TABLE',
    'TABLE',
    'ALL',
    'ALL',
    'Track DROP TABLE'
);

-- Mark all operations on sensitive schema
SELECT pgaudit_marking.set_rule(
    current_database(),
    'ALL',
    'ALL',
    'sensitive_data.%',
    'ALL',
    'All ops on sensitive schema'
);

-- View configured rules
SELECT * FROM pgaudit_marking.show_rules();

Пример 2: Аудит определённых таблиц

-- Mark all DML operations on customer table for all roles
SELECT pgaudit_marking.set_rule(
    'mydb',
    'INSERT',
    'TABLE',
    'public.customers',
    'ALL',
    'Track inserts'
);
SELECT pgaudit_marking.set_rule(
    'mydb',
    'UPDATE',
    'TABLE',
    'public.customers',
    'ALL',
    'Track updates'
);
SELECT pgaudit_marking.set_rule(
    'mydb',
    'DELETE',
    'TABLE',
    'public.customers',
    'ALL',
    'Track deletes'
);
SELECT pgaudit_marking.set_rule(
    'mydb',
    'SELECT',
    'TABLE',
    'public.customers',
    'ALL',
    'Track reads'
);

-- Mark TRUNCATE separately
SELECT pgaudit_marking.set_rule(
    'mydb',
    'TRUNCATE TABLE',
    'TABLE',
    'public.customers',
    'ALL',
    'Track truncates'
);

-- Now perform operations - they will be marked in the log
INSERT INTO public.customers (name, email) VALUES ('John Doe', 'john@example.com');
UPDATE public.customers SET email = 'john.doe@example.com' WHERE name = 'John Doe';

Пример 3: Мониторинг операций с ролями

-- Mark all role-related operations for specific admin role
SELECT pgaudit_marking.set_rule(
    'ALL',
    'CREATE ROLE',
    'ROLE',
    'ALL',
    'admin',
    'Admin creates roles'
);
SELECT pgaudit_marking.set_rule(
    'ALL',
    'ALTER ROLE',
    'ROLE',
    'ALL',
    'admin',
    'Admin alters roles'
);
SELECT pgaudit_marking.set_rule(
    'ALL',
    'DROP ROLE',
    'ROLE',
    'ALL',
    'admin',
    'Admin drops roles'
);

-- Mark all GRANT/REVOKE for all roles
SELECT pgaudit_marking.set_rule(
    'ALL',
    'GRANT',
    'ROLE',
    'ALL',
    'ALL',
    'Track all grants'
);
SELECT pgaudit_marking.set_rule(
    'ALL',
    'REVOKE',
    'ROLE',
    'ALL',
    'ALL',
    'Track all revokes'
);

-- These operations will now be marked
CREATE ROLE analyst LOGIN PASSWORD 'secure_pass';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO analyst;
ALTER ROLE analyst VALID UNTIL '2025-12-31';

Пример 4: Сопоставление с образцом

-- Mark operations on all tables ending with _audit
SELECT pgaudit_marking.set_rule(
    current_database(),
    'ALL',
    'TABLE',
    '%_audit',
    'ALL',
    'Audit tables'
);

-- Mark operations on all tables in reporting schema
SELECT pgaudit_marking.set_rule(
    'mydb',
    'ALL',
    'TABLE',
    'reporting.%',
    'ALL',
    'Reporting schema'
);

-- Mark DROP operations in production database for specific role
SELECT pgaudit_marking.set_rule(
    'production',
    'DROP%',
    'ALL',
    'ALL',
    'dba',
    'DBA drops in production'
);

Пример 5: Конфигурация постоянных правил

-- Configure rules
SELECT pgaudit_marking.set_rule(
    'mydb',
    'CREATE TABLE',
    'TABLE',
    'ALL',
    'ALL',
    'Track creates'
);
SELECT pgaudit_marking.set_rule(
    'mydb',
    'DROP TABLE',
    'TABLE',
    'ALL',
    'ALL',
    'Track drops'
);

-- Save rules to file for persistence across restarts
SELECT pgaudit_marking.rules_conf_save();

-- After server restart, reload rules
SELECT pgaudit_marking.rules_conf_reload();

-- Verify rules are restored
SELECT * FROM pgaudit_marking.show_rules();

Пример 6: Анализ отмеченных событий

-- Create a table to load marking log for analysis
CREATE TABLE audit_analysis (
    timestamp timestamp,
    session_user text,
    current_user text,
    database text,
    pid integer,
    client_addr inet,
    client_port integer,
    application_name text,
    statement_id bigint,
    substatement_id bigint,
    event_type text,
    object_type text,
    object_name text,
    query_text text,
    status text,
    error_message text,
    parameters text,
    marked_by_rule text
);

-- Load marking log (adjust path as needed)
COPY audit_analysis 
FROM '/var/log/postgresql/audit/pgaudit_marking_20240101.csv' 
WITH (FORMAT csv, HEADER true);

-- Analyze: Count events by type
SELECT event_type, COUNT(*) 
FROM audit_analysis 
GROUP BY event_type 
ORDER BY COUNT(*) DESC;

-- Find all failed operations
SELECT timestamp, event_type, object_name, error_message
FROM audit_analysis
WHERE status = 'ERROR';

-- Track specific table modifications
SELECT timestamp, event_type, session_user, query_text
FROM audit_analysis
WHERE object_name = 'public.customers'
ORDER BY timestamp;

-- Analyze by database
SELECT database, event_type, COUNT(*)
FROM audit_analysis
GROUP BY database, event_type
ORDER BY database, COUNT(*) DESC;

Пример 7: Правила, специфичные для базы данных

-- The value of 'ALL' is equivalent to 'NULL'
-- Different rules for different databases
SELECT pgaudit_marking.set_rule(
    'production',
    'DROP TABLE',
    'NULL',
    'ALL',
    'ALL',
    'All drops in production'
);
SELECT pgaudit_marking.set_rule(
    'development',
    'CREATE TABLE',
    'ALL',
    'ALL',
    'ALL',
    'All creates in dev'
);
SELECT pgaudit_marking.set_rule(
    'ALL',
    'ALTER SYSTEM',
    'DATABASE',
    'ALL',
    'ALL',
    'ALTER SYSTEM in any DB'
);

-- View rules grouped by database
SELECT db_name, COUNT(*) as rule_count
FROM pgaudit_marking.show_rules()
GROUP BY db_name
ORDER BY db_name;

F.27.9. Формат #

Записи аудита регистрируются через стандартный механизм ведения журнала и содержат следующие столбцы с данными, разделенными запятой. Вывод соответствует формату CSV только в том случае, если префикс каждой записи журнала удален.

  • AUDIT_TYPE - SESSION или OBJECT.

  • STATEMENT_ID - Уникальный идентификатор оператора для этой сессии. Каждый идентификатор оператора представляет вызов бэкенда. Идентификаторы операторов последовательны, даже если некоторые операторы не регистрируются. Может быть несколько записей для идентификатора оператора, когда регистрируется более одной связи.

  • SUBSTATEMENT_ID - Последовательный идентификатор для каждого подзапроса в рамках основного запроса. Например, вызов функции из запроса. Идентификаторы подзапросов являются непрерывными, даже если некоторые подзапросы не записываются в журнал. Может быть несколько записей для идентификатора подзапроса, когда записывается более одной связи.

  • КЛАСС - например, READ, ROLE (см. pgaudit.log).

  • КОМАНДА - например, ALTER TABLE, SELECT.

  • OBJECT_TYPE - TABLE, INDEX, VIEW и т. д. Доступно для SELECT, DML и большинства DDL операторов.

  • OBJECT_NAME - Полностью квалифицированное имя объекта (например, public.account). Доступно для SELECT, DML и большинства операторов DDL.

  • STATEMENT - Команда, выполненная на сервере.

  • ПАРАМЕТР - Если pgaudit.log_parameter установлен, то это поле будет содержать параметры оператора в виде цитируемого CSV или <none>, если параметры отсутствуют. В противном случае поле будет <not logged>.

Используйте log_line_prefix для добавления любых других полей, необходимых для удовлетворения требований вашего аудита. Типичный префикс строки журнала может быть '%m %u %d [%p]: ', который будет предоставлять дату/время, имя пользователя, имя базы данных и идентификатор процесса для каждого журнала аудита.

F.27.10. Ограничения в использовании #

При переименовании объекты регистрируются по новым именем. Например, переименование таблицы приведет к следующему результату:

ALTER TABLE test RENAME TO test2;

AUDIT: SESSION,36,1,DDL,ALTER TABLE,TABLE,public.test2,ALTER TABLE test RENAME TO test2,<not logged>

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

Операции autovacuum и autoanalyze не регистрируются.

Операторы, выполняемые после того, как транзакция переходит в состояние "отменена", не будут зарегистрированы в журнале аудита. Однако, оператор, вызвавший ошибку, и все последующие операторы, выполненные в отмененной транзакции, будут зарегистрированы как ОШИБКИ стандартным механизмом ведения журнала.

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

При использовании маркировки событий имейте в виду, что правила маркировки оцениваются для каждого события, что может добавить некоторую нагрузку. Однако система сопоставления правил оптимизирована для производительности и должна оказывать минимальное влияние в большинстве сред.