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

15 Занятие 15: Безопасность / Аудит

Исходная страница в нативном Markdown: Безопасность / Аудит
Примечание

Эта страница извлечена из официального PDF в нативный Markdown. Текст слайдов, код и комментарии сохранены в порядке чтения; исходные PDF и HTML остаются эталоном макета. HTML source: pgpro_15_audit.html Archive: PGPRO-handouts-16.zip Страниц PDF: 21

Page 1: Безопасность / Аудит

Авторские права

© Postgres Professional, 2023–2026 Авторы: Алексей Береснев, Илья Баштанов, Павел Толмачев, Игорь Гнатюк Фото: Олег Бартунов (монастырь Пху и пик Бхрикути, Непал)

Использование материалов курса

Некоммерческое использование материалов курса (презентации, демонстрации) разрешается без ограничений. Коммерческое использование возможно только с письменного разрешения компании Postgres Professional. Запрещается внесение изменений в материалы курса.

Обратная связь

Отзывы, замечания и предложения направляйте по адресу: edu@postgrespro.ru

Отказ от ответственности

Компания Postgres Professional не несет никакой ответственности за любые повреждения и убытки, включая потерю дохода, нанесенные прямым или непрямым, специальным или случайным использованием материалов курса. Компания Postgres Professional не предоставляет каких-либо гарантий на материалы курса. Материалы курса предоставляются на основе принципа «как есть» и компания Postgres Professional не обязана предоставлять сопровождение, поддержку, обновления, расширения и изменения.

Page 2: Темы

  • Расширение pg_proaudit
  • Возможности pg_proaudit
  • Аудит ролей и объектов
  • Сохранение настроек
  • Запись событий аудита

Page 3: Расширение pg_proaudit

Аудит — средство сбора событий безопасности

  • не отладка (поиск ошибок и неисправностей)
  • не мониторинг (выявление аномалий и проблем)
  • Не зависит от обычного журнала сообщений
    • отдельный фоновый процесс
    • отдельный журнал событий безопасности
  • Доступ к расширению и журналу событий безопасности должен быть предоставлен только уполномоченным ролям

Комментарии преподавателя

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

Расширение pg_proaudit разработано в Postgres Professional для регистрации событий, связанных с безопасностью. Оно реализует концепцию независимости подсистемы аудита. Для этого запускается отдельный фоновый процесс pg_proaudit logging worker, который регистрирует события безопасности независимо от записи в обычный журнал сообщений сервера.

Место размещения журнала событий безопасности (журнал аудита) в файловой системе и настройки для передачи сообщений в syslog или во внешнюю систему определяются параметрами конфигурации расширения pg_proaudit. Каждое событие описывается фиксированным набором полей, для него формируется отдельная строка журнала или отдельное сообщение.

Доступ к расширению pg_proaudit и журналам аудита следует предоставлять только пользователям, исполняющим роль администратора информационной безопасности (например, администратору безопасности; см. тему «Защищенная схема»).

https://postgrespro.ru/docs/enterprise/16/pg-proaudit#PG-PROAUDIT

Page 4: Установка расширения pg_proaudit

Создадим базу данных.

=> CREATE DATABASE pgpro_audit;
CREATE DATABASE

Расширение pg_proaudit требует загрузки одноименной разделяемой библиотеки:

=> ALTER SYSTEM SET shared_preload_libraries = 'pg_proaudit';
ALTER SYSTEM

Необходимо рестартовать СУБД.

student$ sudo systemctl restart postgrespro-ent-16.service
student$ psql -d pgpro_audit

Создадим расширение pg_proaudit:

=> CREATE EXTENSION pg_proaudit;
CREATE EXTENSION

В результате в списке процессов экземпляра должен быть виден процесс pg_proaudit logging worker.

student$ ps -o pid,command --ppid 828958
    PID COMMAND
 828960 postgres: logger
 828961 postgres: checkpointer
 828962 postgres: background writer
 828964 postgres: walwriter
 828965 postgres: autovacuum launcher
 828966 postgres: cfs-worker-0
 828967 postgres: pg_proaudit logging worker
 828968 postgres: logical replication launcher
 829006 postgres: student pgpro_audit [local] idle

Page 5: Возможности pg_proaudit

Source slide page 5: Возможности pg_proaudit{#source-figure-005 caption=“Source slide page 5: Возможности pg_proaudit”}

Классы фиксируемых событий

  • команды DDL — создание, изменение и удаление объектов баз данных
  • команды DCL — управление доступом к объектам баз данных
  • команды DML — обращение к объектам баз данных
  • подключения и отключения
  • действия, выполняемые заданной ролью

Комментарии преподавателя

Расширение pg_proaudit позволяет отслеживать действия заданных ролей, а также следить за операциями с заданными объектами (например, конкретными таблицами) или с определенными классами объектов и событий:

● команды создания, изменения и удаления объектов СУБД;

● команды управления доступом к объектам баз данных;

● команды обращения к объектам баз данных;

● события аутентификации или отключения от баз данных;

● любые команды, выполняемые заданным пользователем.

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

Полный список регистрируемых событий и классов событий: https://postgrespro.ru/docs/enterprise/16/pg-proaudit#PG-PROAUDIT-EVEN T-TYPES

Page 6: Аудит ролей и объектов

Управление аудитом ролей, объектов или типов объектов

  • pg_proaudit_set_rule()
  • pg_proaudit_remove_rule()
  • Отключение аудита всех событий
    • pg_proaudit_reset()
  • Текущие настройки
    • представление pg_proaudit_settings

Комментарии преподавателя

Для отслеживания событий или классов событий, выполняемых ролями (в том числе групповыми), а также событий, связанных с определенным объектом или типом объектов базы данных, создаются соответствующие правила. Для работы с правилами используются функции:

● pg_proaudit_set_rule — создание правила регистрации;

● pg_proaudit_remove_rule — удаление правила регистрации.

Функция pg_proaudit_reset отключает регистрацию всех событий.

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

Текущие настройки аудита (список правил) можно получить с помощью представления pg_proaudit_settings.

Page 7: Аудит ролей и объектов

Включим аудит всех событий, связанных с управлением ролями — для текущей базы, для всех объектов и всех ролей:

=> SELECT pg_proaudit_set_rule(
  db_name => current_database(),
  event_type => 'ALL',
  object_type => 'ROLE',
  object_name => NULL,
  role_name => NULL
);
 pg_proaudit_set_rule
----------------------
 t
(1 row)

Аудит включается немедленно. Для проверки настроек аудита используется представление:

=> SELECT * FROM pg_proaudit_settings;
   db_name   | event_type | object_type | object_name | role_name | comment
-------------+------------+-------------+-------------+-----------+---------
 pgpro_audit | ALL        | role        |             |           |
(1 row)

Зарегистрируем нового пользователя и отдельной командой дадим право начинать сеанс.

=> CREATE ROLE alice;
CREATE ROLE
=> ALTER ROLE alice LOGIN;
ALTER ROLE

Теперь назначим пользователю пароль:

=> ALTER ROLE alice PASSWORD 'alice';
ALTER ROLE

Ожидаем, что в журнал аудита попали три записи, по числу выполненных команд. Выведем последние строки из журнала аудита, имеющего самую свежую дату модификации:

student$ sudo tail -10 /var/lib/pgpro/ent-16/pg_proaudit/postgresql-2026-07-27_234348.log
2026-07-27 23:43:49.533 MSK,"student","pgpro_audit",829006,INFO,1,1,"CREATE
ROLE","ROLE","alice",SUCCESS,"","CREATE ROLE
alice;",,"student",019FA551-CD9D-7F02-B259-AD66B00330DB,964,4/9,,[local]
2026-07-27 23:43:49.583 MSK,"student","pgpro_audit",829006,INFO,2,1,"ALTER
ROLE","ROLE","alice",SUCCESS,"","ALTER ROLE alice
LOGIN;",,"student",019FA551-CDCF-7465-91E4-C9A68E5391D5,965,4/10,,[local]
2026-07-27 23:43:49.728 MSK,"student","pgpro_audit",829006,INFO,3,1,"ALTER
ROLE","ROLE","alice",SUCCESS,"","ALTER ROLE alice password
<REDACTED>",,"student",019FA551-CE60-734F-A2B0-C02883666153,966,4/11,,[local]

Обратите внимание, что конфиденциальная информация (в данном случае — пароли) скрыта за пометкой . Текстовый CSV-файл удобен для автоматизированной обработки, но для ручного анализа может быть удобнее обращаться к журналу с помощью SQL, используя обертку сторонних данных. Установим расширение file_fdw и определим сторонний сервер.

=> CREATE EXTENSION file_fdw;
CREATE EXTENSION
=> CREATE SERVER pg_proaudit_server FOREIGN DATA WRAPPER file_fdw;
CREATE SERVER

Создадим стороннюю таблицу:

Page 8: Page 8

=> CREATE FOREIGN TABLE pg_proaudit_log(
  log_time timestamp(3) with time zone,
  current_usr_name text,
  database_name text,
  session_pid text,
  error_severity text,
  session_line_num bigint,
  session_line_subcommand_num bigint,
  event_type text,
  object_type text,
  object_name text,
  status text,
  error_message text,
  query_text text,
  query_args text,
  session_usr_name text,
  uuid text,
  xid text,
  vxid text,
  rows text,
  host text
)
SERVER pg_proaudit_server
OPTIONS (filename '/var/lib/pgpro/ent-16/pg_proaudit/postgresql-2026-07-27_234348.log',
         format 'csv' );
CREATE FOREIGN TABLE

И прочитаем из нее записи, касающиеся изменений в данных таблицы tab1:

=> SELECT log_time, current_usr_name, event_type, status, query_text
FROM pg_proaudit_log
LIMIT 3 \gx
-[ RECORD 1 ]----+-------------------------------------
log_time         | 2026-07-27 23:43:49.533+03
current_usr_name | student
event_type       | CREATE ROLE
status           | SUCCESS
query_text       | CREATE ROLE alice;
-[ RECORD 2 ]----+-------------------------------------
log_time         | 2026-07-27 23:43:49.583+03
current_usr_name | student
event_type       | ALTER ROLE
status           | SUCCESS
query_text       | ALTER ROLE alice LOGIN;
-[ RECORD 3 ]----+-------------------------------------
log_time         | 2026-07-27 23:43:49.728+03
current_usr_name | student
event_type       | ALTER ROLE
status           | SUCCESS
query_text       | ALTER ROLE alice password <REDACTED>

Включим аудит всех событий подключения. Здесь функции pg_proaudit_set_rule вместо типа объекта передаем NULL.

=> SELECT pg_proaudit_set_rule(
  db_name => current_database(),
  event_type => 'AUTHENTICATE',
  object_type => NULL,
  object_name => NULL,
  role_name => NULL
);
 pg_proaudit_set_rule
----------------------
 t
(1 row)

Что теперь покажет представление pg_proaudit_settings?

=> SELECT * FROM pg_proaudit_settings;
   db_name   |  event_type  | object_type | object_name | role_name | comment
-------------+--------------+-------------+-------------+-----------+---------
 pgpro_audit | ALL          | role        |             |           |
 pgpro_audit | authenticate | ALL         |             |           |
(2 rows)

Page 9: Page 9

Начнем другой сеанс от имени Алисы:

student$ psql 'host=localhost dbname=pgpro_audit user=alice password=alice'

И снова проверим журнал аудита:

=> SELECT log_time, current_usr_name, event_type, status
FROM pg_proaudit_log
ORDER BY log_time DESC
LIMIT 1 \gx
-[ RECORD 1 ]----+---------------------------
log_time         | 2026-07-27 23:43:51.497+03
current_usr_name | alice
event_type       | AUTHENTICATE
status           | SUCCESS

Следующая задача — включить регистрацию всех действий Алисы. Для этого укажем имя роли в соответствующем параметре функции pg_proaudit_set_rule:

=> SELECT pg_proaudit_set_rule(
  db_name => current_database(),
  event_type => 'ALL',
  object_type => NULL,
  object_name => NULL,
  role_name => 'alice'
);
 pg_proaudit_set_rule
----------------------
 t
(1 row)

Как это отобразилось в представлении pg_proaudit_settings?

=> SELECT * FROM pg_proaudit_settings;
   db_name   |  event_type  | object_type | object_name | role_name | comment
-------------+--------------+-------------+-------------+-----------+---------
 pgpro_audit | ALL          | role        |             |           |
 pgpro_audit | authenticate | ALL         |             |           |
 pgpro_audit | ALL          | ALL         |             | alice     |
(3 rows)

Алиса собирается создать таблицу в схеме public, предоставим ей такие полномочия:

=> GRANT CREATE ON SCHEMA public TO alice;
GRANT

Алиса создает таблицу в своем сеансе:

=> CREATE TABLE tab1(
  id integer,
  msg text
);
CREATE TABLE

…и сведения об этом сразу появляются в журнале аудита:

=> SELECT log_time, current_usr_name, event_type, object_type, object_name, status, query_text
FROM pg_proaudit_log
ORDER BY log_time DESC
LIMIT 1 \gx
-[ RECORD 1 ]----+---------------------------
log_time         | 2026-07-27 23:43:51.946+03
current_usr_name | alice
event_type       | CREATE TABLE
object_type      | TABLE
object_name      | public.tab1
status           | SUCCESS
query_text       | CREATE TABLE tab1(        +
                 |   id integer,             +
                 |   msg text                +
                 | );

Сосредоточимся теперь на отслеживании изменений данных в таблице tab1. Отменим аудит всех действий Алисы и

Page 10: Page 10

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

=> SELECT pg_proaudit_remove_rule(
  db_name => current_database(),
  event_type => 'ALL',
  object_type => NULL,
  object_name => NULL,
  role_name => 'alice'
);
 pg_proaudit_remove_rule
-------------------------
 t
(1 row)
=> SELECT pg_proaudit_set_rule(
  db_name => current_database(),
  event_type => 'ALL_MOD',
  object_type => 'TABLE',
  object_name => 'public.tab1',
  role_name => NULL
);
 pg_proaudit_set_rule
----------------------
 t
(1 row)
=> SELECT * FROM pg_proaudit_settings;
   db_name   |  event_type  | object_type | object_name | role_name | comment
-------------+--------------+-------------+-------------+-----------+---------
 pgpro_audit | ALL          | role        |             |           |
 pgpro_audit | authenticate | ALL         |             |           |
 pgpro_audit | ALL_MOD      | table       | public.tab1 |           |
(3 rows)

В сеансе Алисы выполним вставку в таблицу tab1 и проверим журнал аудита.

=> INSERT INTO tab1 VALUES (1984, 'Big brother is watching you...');
INSERT 0 1
=> SELECT * FROM tab1;
  id  |              msg
------+--------------------------------
 1984 | Big brother is watching you...
(1 row)
=> SELECT log_time, current_usr_name, event_type, status, query_text
FROM pg_proaudit_log
ORDER BY log_time DESC
LIMIT 1 \gx
-[ RECORD 1 ]----+------------------------------------------------------------------
log_time         | 2026-07-27 23:43:53.391+03
current_usr_name | alice
event_type       | INSERT
status           | SUCCESS
query_text       | INSERT INTO tab1 VALUES (1984, 'Big brother is watching you...');

Обратите внимание на отсутствие записи о выполнении SELECT. Создадим второго пользователя:

=> CREATE USER bob PASSWORD 'bob';
CREATE ROLE

Откроем от его имени еще один сеанс, в котором Боб попытается опустошить таблицу tab1:

student$ psql 'host=localhost dbname=pgpro_audit user=bob password=bob'
=> TRUNCATE TABLE tab1;
ERROR:  permission denied for table tab1

Page 11: Page 11

Поскольку у Боба нет доступа к таблице, в журнале аудита увидим ошибку:

=> SELECT log_time, current_usr_name, event_type, status, query_text
FROM pg_proaudit_log
ORDER BY log_time DESC
LIMIT 3 \gx
-[ RECORD 1 ]----+------------------------------------
log_time         | 2026-07-27 23:43:53.802+03
current_usr_name | bob
event_type       | TRUNCATE TABLE
status           | FAILURE
query_text       | TRUNCATE TABLE tab1;
-[ RECORD 2 ]----+------------------------------------
log_time         | 2026-07-27 23:43:53.753+03
current_usr_name | bob
event_type       | AUTHENTICATE
status           | SUCCESS
query_text       |
-[ RECORD 3 ]----+------------------------------------
log_time         | 2026-07-27 23:43:53.65+03
current_usr_name | student
event_type       | CREATE ROLE
status           | SUCCESS
query_text       | CREATE USER bob password <REDACTED>

Page 12: Настройки

Настройки, сделанные функциями, необходимо сохранить в файле PGDATA/pg\_proaudit.conf

  • pg_proaudit_save()
  • Файл настроек аудита можно отредактировать напрямую, но после этого надо перечитать
    • pg_proaudit_reload()

Комментарии преподавателя

Настройки аудита, произведенные вызовами функций расширения pg_proaudit, будут потеряны после перезагрузки сервера, если не сохранить их в файле настроек pg_proaudit.conf.

Файл pg_proaudit.conf размещается в каталоге кластера данных (PGDATA), изменить его расположение нельзя.

Для сохранения текущих настроек в этот файл предназначена функция pg_proaudit_save. Аудит можно настраивать и непосредственным редактированием файла pg_proaudit.conf, но это не так удобно, как вызов функций расширения.

Если изменить настройки непосредственно в файле pg_proaudit.conf, их нужно прочитать и применить функцией pg_proaudit_reload.

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

Page 13: Настройки

Функция pg_proaudit_save записывает настройки аудита в файл pg_proaudit.conf. Если не сохранить настройки, они будут потеряны при остановке сервера.

=> SELECT pg_proaudit_save();
 pg_proaudit_save
------------------
(1 row)

Заглянем в файл pg_proaudit.conf:

/var/lib/pgpro/ent-16/pg_proaudit.conf
"pgpro_audit",ALL,role,"","",""
"pgpro_audit",authenticate,,"","",""
"pgpro_audit",ALL_MOD,table,"public.tab1","",""

А теперь сбросим все настройки аудита:

=> SELECT pg_proaudit_reset();
 pg_proaudit_reset
-------------------
(1 row)

Никакие настройки не действуют:

=> SELECT * FROM pg_proaudit_settings;
 db_name | event_type | object_type | object_name | role_name | comment
---------+------------+-------------+-------------+-----------+---------
(0 rows)

Можно (хотя это не очень удобно) изменять файл pg_proaudit.conf любыми средствами редактирования текста. Например, удалим строку конфигурации аудита событий подключения:

/var/lib/pgpro/ent-16/pg_proaudit.conf
"pgpro_audit",ALL,role,"","",""
"pgpro_audit",ALL_MOD,table,"public.tab1","",""

А теперь считаем настройки из файла:

=> SELECT pg_proaudit_reload();
 pg_proaudit_reload
--------------------
(1 row)
=> SELECT * FROM pg_proaudit_settings;
   db_name   | event_type | object_type | object_name | role_name | comment
-------------+------------+-------------+-------------+-----------+---------
 pgpro_audit | ALL        | role        |             |           |
 pgpro_audit | ALL_MOD    | table       | public.tab1 |           |
(2 rows)

Настройки аудита восстановлены, за исключением регистрации подключений.

Page 14: Запись событий аудита

Source slide page 14: Запись событий аудита{#source-figure-014 caption=“Source slide page 14: Запись событий аудита”}

Комментарии преподавателя

Параметр расширения pg_proaudit.log_destination определяет способ регистрации (один или несколько) событий безопасности:

● csvlog — записывать события в файл CSV.

Параметр pg_proaudit.log_filename задает шаблон имен файлов CSV, а параметр pg_proaudit.log_rotation_size — максимальный размер файла в килобайтах. Другой способ настройки ротации файлов журнала — по времени — устанавливается параметром pg_proaudit.log_rotation_age.

● ceflog — передавать события в SIEM-систему в формате CEF.

Поддержка открытого формата событий CEF (Common Event Format) позволяет отправлять собранные данные различным системам управления информацией и событиями безопасности (SIEM, Security Information and Event Management).

● syslog и cefsyslog — передавать события в службу syslog в формате syslog или CEF.

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

Полный список параметров конфигурации записи событий аудита в журнал содержится в документации: https://postgrespro.ru/docs/enterprise/16/pg-proaudit#PG-PROAUDIT-SECU RITY-EVENT-LOG-CONFIGURATION-PARAMETERS

Page 15: Настройка записи событий аудита

Посмотрим значения параметров регистрации событий по умолчанию:

=> SELECT name, setting
FROM pg_settings
WHERE name LIKE 'pg_proaudit.log_%';
                 name                 |            setting
--------------------------------------+--------------------------------
 pg_proaudit.log_catalog_access       | off
 pg_proaudit.log_command_text         | on
 pg_proaudit.log_destination          | csvlog
 pg_proaudit.log_directory            | pg_proaudit
 pg_proaudit.log_file_mode            | 0600
 pg_proaudit.log_filename             | postgresql-%Y-%m-%d_%H%M%S.log
 pg_proaudit.log_rotation_age         | 1440
 pg_proaudit.log_rotation_size        | 10240
 pg_proaudit.log_rows                 | off
 pg_proaudit.log_truncate_on_rotation | off
(10 rows)

Добавим запись в журнал аудита количества строк, затронутых SQL-командой:

=> ALTER SYSTEM SET pg_proaudit.log_rows = on;
ALTER SYSTEM

Перечитаем конфигурацию.

=> SELECT pg_reload_conf();
 pg_reload_conf
----------------
 t
(1 row)

Удалим строки в таблице tab1 в сеансе Алисы:

=> DELETE FROM tab1;
DELETE 1

Теперь в конце записи о событии появилось еще одно поле. Сравните последнюю запись с записью вставки: удалена одна строка.

=> SELECT log_time, current_usr_name, event_type, status, query_text, rows
FROM pg_proaudit_log
WHERE event_type IN ('INSERT', 'DELETE') \gx
-[ RECORD 1 ]----+------------------------------------------------------------------
log_time         | 2026-07-27 23:43:53.391+03
current_usr_name | alice
event_type       | INSERT
status           | SUCCESS
query_text       | INSERT INTO tab1 VALUES (1984, 'Big brother is watching you...');
rows             |
-[ RECORD 2 ]----+------------------------------------------------------------------
log_time         | 2026-07-27 23:43:54.98+03
current_usr_name | alice
event_type       | DELETE
status           | SUCCESS
query_text       | DELETE FROM tab1;
rows             | 1

Page 16: Итоги

Расширение pg\_proaudit регистрирует события аудита независимо от обычного журнала сообщений

  • Аудиту подлежат подключения и отключения, операции с объектами баз данных и действия ролей
  • Журнал аудита может сохраняться как в формате CSV, так и передаваться службам SIEM или syslog

Page 17: Практика

  1. Настройте аудит для записи в CSV и syslog одновременно. Включите аудит регистрации ролей и создания таблиц. В следующих заданиях сравните сообщения, попадающие в CVS и в syslog. 2. Зарегистрируйте новую роль observed1 и настройте аудит подключений и отключений для этой роли. 3. Создайте таблицу tab1 так, чтобы роль observed1 могла выполнять команды DML с этой таблицей; владельцем таблицы должен быть другой пользователь. 4. Настройте регистрацию команд DML, выполненных любым пользователем, для таблицы tab1.

Комментарии преподавателя

  1. После подключения аудита используйте команду
ALTER SYSTEM SET pg_proaudit.log_destination = 'csvlog,syslog';

для записи сообщений аудита и в файл, и в syslog.

Для настройки аудита используйте функцию pg_proaudit_set_rule.

В заданиях с 2 по 4 просматривать сообщения аудита в файле CSV нужно в каталоге /var/lib/pgpro/ent-16/pg_proaudit.

Идентификатор, заранее записанный в параметр сервера syslog_ident, поможет отфильтровать необходимые строки журнала сообщений syslog, который находится в файле /var/log/syslog. Воспользуйтесь следующей командой:

sudo grep -a идентификатор /var/log/syslog | tail

Page 18: 1. Настройка аудита

Создадим базу данных:

=> CREATE DATABASE pgpro_audit;
CREATE DATABASE

Загрузим библиотеку:

=> ALTER SYSTEM SET shared_preload_libraries = 'pg_proaudit';
ALTER SYSTEM

Подключение библиотеки требует перезагрузки СУБД.

student$ sudo systemctl restart postgrespro-ent-16.service
student$ psql -d pgpro_audit

Создадим расширение pg_proaudit:

=> CREATE EXTENSION pg_proaudit;
CREATE EXTENSION

Настроим запись сообщений аудита одновременно в CSV-файл и syslog:

=> ALTER SYSTEM SET pg_proaudit.log_destination = 'csvlog,syslog';
ALTER SYSTEM

Установим имя программы — идентификатор в записях syslog:

=> ALTER SYSTEM SET syslog_ident = 'MY_audit';
ALTER SYSTEM
=> SELECT pg_reload_conf();
 pg_reload_conf
----------------
 t
(1 row)

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

=> SELECT pg_proaudit_set_rule(current_database(), 'ALL', 'ROLE', NULL, NULL);
 pg_proaudit_set_rule
----------------------
 t
(1 row)

Аудит событий создания таблиц:

=> SELECT pg_proaudit_set_rule(current_database(), 'CREATE TABLE', 'TABLE', NULL, NULL);
 pg_proaudit_set_rule
----------------------
 t
(1 row)

Получившиеся настройки аудита:

=> SELECT * FROM pg_proaudit_settings;
   db_name   |  event_type  | object_type | object_name | role_name | comment
-------------+--------------+-------------+-------------+-----------+---------
 pgpro_audit | ALL          | role        |             |           |
 pgpro_audit | create table | table       |             |           |
(2 rows)

Page 19: 2. Регистрация событий создания и управления пользователями

Регистрация нового пользователя:

=> CREATE ROLE observed1 LOGIN PASSWORD 'obs123';
CREATE ROLE

Второй сеанс от имени observed1:

student$ psql 'dbname=pgpro_audit user=observed1 password=obs123'

Командой ls -ltr $PGDATA/pg_proaudit можно получить список файлов аудита, отсортированный по времени модификации:

student$ sudo ls -ltr /var/lib/pgpro/ent-16/pg_proaudit
total 4
-rw------- 1 postgres postgres 228 июл 28 00:16 postgresql-2026-07-28_001605.log

Проверяем CSV-файл аудита, который был изменен последним:

student$ sudo tail -1 /var/lib/pgpro/ent-16/pg_proaudit/postgresql-2026-07-28_001605.log
2026-07-28 00:16:06.494 MSK,"student","pgpro_audit",887175,INFO,1,1,"CREATE
ROLE","ROLE","observed1",SUCCESS,"","CREATE ROLE observed1 LOGIN password
<REDACTED>",,"student",019FA56F-5BDE-7215-80D8-E869B0DBA039,964,4/13,,[local]

Получим последние две записи в журнале /var/log/syslog по установленному идентификатору MY_audit:

student$ sudo grep -a MY_audit /var/log/syslog | tail -2
2026-07-28T00:16:06.494916+03:00 course MY_audit[887175]: AUDIT [1-1] INFO: USER:
student, DB: pgpro_audit, PID: 887175, EVENT TYPE: CREATE ROLE, OBJECT TYPE: ROLE, OBJECT
NAME: observed1, SUCCESS, SESSION USER: student, UUID:
019FA56F-5BDE-7215-80D8-E869B0DBA039, XID: 964, VXID: 4/13, SRC: [local]
2026-07-28T00:16:06.495262+03:00 course MY_audit[887175]: AUDIT [1-1] STATEMENT: CREATE
ROLE observed1 LOGIN password <REDACTED>

3. Создание таблицы и предоставление прав на нее

Суперпользователь student создает таблицу и выдает на нее права observed1.

=> CREATE TABLE tab1(n integer, txt text);
CREATE TABLE
=> GRANT SELECT,INSERT,UPDATE,DELETE ON tab1 TO observed1;
GRANT

Проверяем CSV-файл аудита: должно быть видно CREATE TABLE, но не GRANT.

student$ sudo tail -1 /var/lib/pgpro/ent-16/pg_proaudit/postgresql-2026-07-28_001605.log
2026-07-28 00:16:07.975 MSK,"student","pgpro_audit",887175,INFO,2,1,"CREATE
TABLE","TABLE","public.tab1",SUCCESS,"","CREATE TABLE tab1(n integer, txt
text);",,"student",019FA56F-61A7-716F-ABB1-ABA3E461C9D9,965,4/14,,[local]

Поиск записей в журнале /var/log/syslog по установленному идентификатору MY_audit:

student$ sudo grep -a MY_audit /var/log/syslog | tail -2
2026-07-28T00:16:07.975974+03:00 course MY_audit[887175]: AUDIT [2-1] INFO: USER:
student, DB: pgpro_audit, PID: 887175, EVENT TYPE: CREATE TABLE, OBJECT TYPE: TABLE,
OBJECT NAME: public.tab1, SUCCESS, SESSION USER: student, UUID:
019FA56F-61A7-716F-ABB1-ABA3E461C9D9, XID: 965, VXID: 4/14, SRC: [local]
2026-07-28T00:16:07.976100+03:00 course MY_audit[887175]: AUDIT [2-1] STATEMENT: CREATE
TABLE tab1(n integer, txt text);

4. Регистрация команд DML с таблицей tab1

Установка регистрации команд DML для tab1.

=> SELECT pg_proaudit_set_rule(current_database(), 'ALL_DML', 'TABLE', 'public.tab1', NULL);
 pg_proaudit_set_rule
----------------------
 t
(1 row)

Page 20: Page 20

Получившиеся настройки аудита:

=> SELECT * FROM pg_proaudit_settings;
   db_name   |  event_type  | object_type | object_name | role_name | comment
-------------+--------------+-------------+-------------+-----------+---------
 pgpro_audit | ALL          | role        |             |           |
 pgpro_audit | create table | table       |             |           |
 pgpro_audit | ALL_DML      | table       | public.tab1 |           |
(3 rows)

Выполним несколько команд в сеансе observed1, сразу проверяя CSV-файл и журнал событий:

=> INSERT INTO tab1 VALUES (1, 'Один');
INSERT 0 1
student$ sudo tail -1 /var/lib/pgpro/ent-16/pg_proaudit/postgresql-2026-07-28_001605.log
2026-07-28 00:16:09.474
MSK,"observed1","pgpro_audit",887533,INFO,1,1,"INSERT","TABLE","public.tab1",SUCCESS,"","I
NSERT INTO tab1 VALUES (1,
'Один');",,"observed1",019FA56F-6782-7868-B88C-EEF51B601E9C,,5/4,,[local]
student$ sudo grep -a MY_audit /var/log/syslog | tail -2
2026-07-28T00:16:09.475221+03:00 course MY_audit[887533]: AUDIT [1-1] INFO: USER:
observed1, DB: pgpro_audit, PID: 887533, EVENT TYPE: INSERT, OBJECT TYPE: TABLE, OBJECT
NAME: public.tab1, SUCCESS, SESSION USER: observed1, UUID:
019FA56F-6782-7868-B88C-EEF51B601E9C, XID: 0, VXID: 5/4, SRC: [local]
2026-07-28T00:16:09.475452+03:00 course MY_audit[887533]: AUDIT [1-1] STATEMENT: INSERT
INTO tab1 VALUES (1, 'Один');
=> SELECT * FROM tab1;
 n | txt
---+------
 1 | Один
(1 row)
student$ sudo tail -1 /var/lib/pgpro/ent-16/pg_proaudit/postgresql-2026-07-28_001605.log
2026-07-28 00:16:10.719
MSK,"observed1","pgpro_audit",887533,INFO,2,1,"SELECT","TABLE","public.tab1",SUCCESS,"","S
ELECT * FROM tab1;",,"observed1",019FA56F-6C5F-7365-AE2B-B6716031846C,,5/5,,[local]
student$ sudo grep -a MY_audit /var/log/syslog | tail -2
2026-07-28T00:16:10.719912+03:00 course MY_audit[887533]: AUDIT [2-1] INFO: USER:
observed1, DB: pgpro_audit, PID: 887533, EVENT TYPE: SELECT, OBJECT TYPE: TABLE, OBJECT
NAME: public.tab1, SUCCESS, SESSION USER: observed1, UUID:
019FA56F-6C5F-7365-AE2B-B6716031846C, XID: 0, VXID: 5/5, SRC: [local]
2026-07-28T00:16:10.719996+03:00 course MY_audit[887533]: AUDIT [2-1] STATEMENT: SELECT *
FROM tab1;
=> UPDATE tab1 SET n=2;
UPDATE 1
student$ sudo tail -1 /var/lib/pgpro/ent-16/pg_proaudit/postgresql-2026-07-28_001605.log
2026-07-28 00:16:11.970
MSK,"observed1","pgpro_audit",887533,INFO,3,1,"UPDATE","TABLE","public.tab1",SUCCESS,"","U
PDATE tab1 SET n=2;",,"observed1",019FA56F-7142-743C-9EF1-92E5AA3AED8A,,5/6,,[local]
student$ sudo grep -a MY_audit /var/log/syslog | tail -2
2026-07-28T00:16:11.971276+03:00 course MY_audit[887533]: AUDIT [3-1] INFO: USER:
observed1, DB: pgpro_audit, PID: 887533, EVENT TYPE: UPDATE, OBJECT TYPE: TABLE, OBJECT
NAME: public.tab1, SUCCESS, SESSION USER: observed1, UUID:
019FA56F-7142-743C-9EF1-92E5AA3AED8A, XID: 0, VXID: 5/6, SRC: [local]
2026-07-28T00:16:11.971413+03:00 course MY_audit[887533]: AUDIT [3-1] STATEMENT: UPDATE
tab1 SET n=2;
=> DELETE FROM tab1;
DELETE 1
student$ sudo tail -1 /var/lib/pgpro/ent-16/pg_proaudit/postgresql-2026-07-28_001605.log
2026-07-28 00:16:13.201

Page 21: Page 21

MSK,"observed1","pgpro_audit",887533,INFO,4,1,"DELETE","TABLE","public.tab1",SUCCESS,"","D
ELETE FROM tab1;",,"observed1",019FA56F-7611-7DC3-BBA7-6D315A10132C,,5/7,,[local]
student$ sudo grep -a MY_audit /var/log/syslog | tail -2
2026-07-28T00:16:13.202695+03:00 course MY_audit[887533]: AUDIT [4-1] INFO: USER:
observed1, DB: pgpro_audit, PID: 887533, EVENT TYPE: DELETE, OBJECT TYPE: TABLE, OBJECT
NAME: public.tab1, SUCCESS, SESSION USER: observed1, UUID:
019FA56F-7611-7DC3-BBA7-6D315A10132C, XID: 0, VXID: 5/7, SRC: [local]
2026-07-28T00:16:13.203005+03:00 course MY_audit[887533]: AUDIT [4-1] STATEMENT: DELETE
FROM tab1;

Уборка

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

=> \c student
You are now connected to database "student" as user "student".
=> DROP DATABASE pgpro_audit WITH (FORCE);
DROP DATABASE
=> DROP ROLE observed1;
DROP ROLE
student$ sudo rm -rf /var/lib/pgpro/ent-16/pg_proaudit
=> ALTER SYSTEM RESET ALL;
ALTER SYSTEM
student$ sudo systemctl restart postgrespro-ent-16.service