Аудит безопасности

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

YMatrix поддерживает два метода аудита: log_XXX и pgAudit.

log_XXX

Параметры серии log_xxx используются для настройки поведения ведения журналов, что помогает в мониторинге и отладке работы базы данных. Все операции с базой данных записываются в журналы операций СУБД, которые затем могут быть проанализированы для раннего обнаружения опасных действий.

Параметры конфигурации

logging_collector     -- Включать ли сборщик журналов; по умолчанию выключен, рекомендуется включить
log_destination       -- Тип вывода журнала; по умолчанию stderr (записываются только ошибки), рекомендуется csvlog; возможные значения: stderr, csvlog, syslog и eventlog,
log_directory          -- Каталог журналов; по умолчанию $PGDATA/pg_log, 
log_filename            -- Имя файла журнала; по умолчанию postgresql-%Y-%m-%d_%H%M%S.log
log_file_mode           -- Права доступа к файлу журнала; по умолчанию 0600
log_truncate_on_rotation  -- По умолчанию выключено; если включено, при ротации содержимое перезаписывается (off = добавление, on = очистка перед записью)
log_rotation_age      -- Максимальная продолжительность одного файла журнала; по умолчанию 1d, также поддерживаются 1h, 1min, 1s
log_rotation_size       -- Максимальный размер одного файла журнала; по умолчанию 10 МБ
log_error_verbosity    -- По умолчанию default; verbose означает более подробные сообщения
log_connections    -- Записывать ли событие входа пользовательской сессии; по умолчанию выключено, рекомендуется включить
log_disconnections -- Записывать ли событие выхода пользовательской сессии; по умолчанию выключено, рекомендуется включить
log_statement    -- Записывает различные операции после входа пользователя в базу данных:
    none — без записи
    ddl — запись create, drop и alter
    mod — запись ddl + insert, delete, update и truncate
    all — запись mod + select
log_min_duration_statement = 2s   -- Запись SQL-запросов, выполняющихся дольше 2 секунд
log_checkpoints = on
log_lock_waits = on
deadlock_timeout = 1s

Пример конфигурации

Ниже приведен пример конфигурации. Добавьте эти параметры в файл postgresql.conf:

Внимание!
После изменения файла postgresql.conf необходимо перезапустить службу YMatrix, чтобы конфигурация вступила в силу.

logging_collector = on
log_directory = 'stderr'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d
log_rotation_size = 10MB
log_truncate_on_rotation = off

log_statement = 'all'
log_min_duration_statement = 100

log_connections = on
log_disconnections = on
log_lock_waits = on

pgAudit

Используйте расширение pgAudit для более детального аудита.

Установка и включение

-- Измените параметры, добавив pgaudit
gpconfig -c shared_preload_libraries -v matrixts,matrixmgr,matrixgate,mxstream,telemetry,pgaudit
-- После изменения параметров перезапустите базу данных
mxstop -arf
mxstart -a
-- После перезапуска экземпляра базы данных
CREATE EXTENSION pgaudit;

Параметры конфигурации

pgAudit предоставляет два режима аудита: на уровне сессии и на уровне объекта. В базе данных доступны следующие настраиваемые параметры:

pgaudit.log     -- Указывает, какие классы операторов будут записываться в журналы аудита сессии; по умолчанию none. Допустимые значения:
    READ (select, copy from)
    WRITE (insert, update, delete, truncate, copy to)
    FUNCTION (вызовы функций и блоки DO)
    ROLE (grant, revoke, create/alter/drop role)
    DDL (все DDL, кроме ROLE)
    MISC (discard, fetch, checkpoint, vacuum)
    MISC_SET (различные команды SET, например SET ROLE)
    ALL (включает все вышеперечисленное)
pgaudit.log_catalog    -- Контролирует, аудируются ли изменения таблиц в схеме pg_catalog; по умолчанию включено.
pgaudit.log_client     -- Записывать ли тип клиентского приложения; по умолчанию выключено.
pgaudit.log_level      -- Уровень детализации записей аудита; по умолчанию log.
pgaudit.log_parameter  -- Контролирует, записываются ли действия по установке параметров на уровне сессии в журналы аудита; по умолчанию выключено.
pgaudit.log_parameter_max_size  -- Максимальный размер (в байтах) записываемых параметров; по умолчанию 0.
pgaudit.log_relation   -- Контролирует, создается ли одна запись журнала на каждую таблицу при аудите сессии; по умолчанию выключено.
pgaudit.log_rows       -- Контролирует, записывается ли количество затронутых строк; по умолчанию выключено.   
pgaudit.log_statement  -- Контролирует, записываются ли детали оператора; по умолчанию включено.
pgaudit.log_statement_once     -- Контролирует, записывается ли подробная информация для группы операторов только в первой записи аудита; по умолчанию выключено.
pgaudit.role           -- Указывает основную роль, используемую для аудита объектов; значение по умолчанию отсутствует.

Примеры конфигурации

Аудит на уровне сессии

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

-- 1. Установите область аудита
set pgaudit.log = 'read, ddl'; 

-- 2. Выполните операции 
-- 2.1 Создайте таблицу
create table account
(
    id int,
    name text,
    password text,
    description text
);

-- 2.2 Вставьте данные
insert into account (id, name, password, description)
             values (1, 'user1', 'HASH1', 'blah, blah');

-- 2.3 Выполните запрос
select *
    from account;

-- 3. Просмотрите журналы (так как область аудита не включает 'write', операция insert не записывается)
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>

Аудит объектов

Регистрирует доступ только к определенным объектам и требует наличия роли аудита.

В данном примере демонстрируется, как расширение pgAudit записывает операции роли аудита (auditor) над конкретными таблицами и столбцами.

--1. Создайте роль аудита
CREATE ROLE auditor;

--2. Включите аудит объектов
set pgaudit.role = 'auditor';    

--3. Предоставьте права на объект роли аудита
grant select (password) on public.account to auditor;

--4. Выполните операции
--4.1 Запросите указанный столбец password
postgres=# select password   
  from account;                                                                                                                                                                       
 password              
----------             
 HASH2                  
 HASH2              
 HASH2           
(3 rows)                  

--4.2 Запросите столбцы id и name     
postgres=# select id, name 
  from account;   
 id | name    
----+-------   
  1 | user1   
  1 | user1
  1 | user1 
(3 rows) 

--5. Просмотрите журналы — аудиту подвергается только доступ к столбцу password
"AUDIT: OBJECT,2,1,READ,SELECT,TABLE,public.account,""select password from account;"","
,,,,,,,0,,"pgaudit.c",767,  

--6. Предоставьте право UPDATE на объект
grant update (name, password) on public.account to audit;

--6.1 Выполните операцию обновления
update account set password = 'HASH2';

--7. Просмотрите журналы
"AUDIT: OBJECT,4,1,WRITE,UPDATE,TABLE,public.account,""update account                                 
   set password = 'HASH2';"",",,,,,,,0,,"pgaudit.c",767,

Комбинированный аудит объектов и сессий

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

--1. Создайте таблицу
create table account_role_map(account_id int,role_id int);

--2. Предоставьте право SELECT на таблицу объекта роли auditor
grant select on public.account_role_map to auditor; 

--3. Выполните операции
--3.1 При отключенном аудите сессий создается одна запись на таблицу
set pgaudit.log_relation to off; 

--3.2 Выполните запросы
select account.password,account_role_map.role_id \
from account inner join account_role_map \
on account.id = account_role_map.account_id;

select account_role_map.account_id \
from account inner join account_role_map
on account.id = account_role_map.account_id;

--4. Просмотрите журналы
--4.1 Первый запрос обращается и к password, и к account_role_map, поэтому аудиту подвергаются обе таблицы
"AUDIT: OBJECT,9,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       
;"",",,,,,,,0,,"pgaudit.c",767,  
"AUDIT: OBJECT,9,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    
;"",",,,,,,,0,,"pgaudit.c",767, 

--4.2 Второй запрос не обращается к password, поэтому создается только одна запись аудита
"AUDIT: OBJECT,10,1,READ,SELECT,TABLE,public.account_role_map,""select   
       account_role_map.account_id   
  from account                   
       inner join account_role_map                                  
            on account.id = account_role_map.account_id                                                                                                                                                                                                     
;"",",,,,,,,0,,"pgaudit.c",767, 

--4.3 Оба SQL-запроса обращались к account_role_map, поэтому оба вызвали аудит для account_role_map
"AUDIT: OBJECT,10,1,READ,SELECT,TABLE,public.account_role_map,""select                                
       account_role_map.account_id  
  from account                           
       inner join account_role_map      
            on account.id = account_role_map.account_id   
;"",",,,,,,,0,,"pgaudit.c",767, 
"AUDIT: OBJECT,11,1,READ,SELECT,TABLE,public.account_role_map,""select                                
       account_role_map.role_id    
  from account                   
       inner join account_role_map 
            on account.id = account_role_map.account_id  
;"",",,,,,,,0,,"pgaudit.c",767,