🚨 Пятница, вечер. Мониторинг замечает скачок чтения в таблице платежей. У ИБ три вопроса:
1. Кто обращался к данным?
2. С какого адреса?
3. Сколько строк прочитал?
Обычный журнал PostgreSQL редко дает такой ответ.
log_statement = all смешивает запросы с сообщениями сервера и приложений, а
log_line_prefix лишь добавляет к текстовым строкам роль или IP.
pgAudit улучшает аудит команд и объектов, но нужные поля остаются в общем серверном логе. Триггер тоже не спасет: он не увидит
SELECT — основной канал утечки.
Нужен заранее подготовленный структурированный аудит. В Postgres Pro Enterprise его обеспечивает
pg_proaudit: записывает в отдельный CSV-журнал роль, IP клиента, тип операции, объект, статус, текст запроса и число затронутых строк.
Чтобы не утонуть в событиях, правила задают выборочно: DML для
public.payments, операции с ролями, невременный DDL, входы и отключения. Доступ к системному каталогу включают через
pg_proaudit.log_catalog_access = on и DML-правило для интересующей роли — здесь это
insider.
Две детали решают исход расследования.
object_name указывают вместе со схемой: правило для
payments сохранится, но не сработает, нужно
public.payments, а
pg_proaudit.log_rows = on фиксирует объем чтения.
Затем
pgpro-otel-collector разбирает CSV на 20 полей и отправляет события по OTLP HTTP в VictoriaLogs. LogsQL дает быстрый поиск, Grafana — обзор аномалий.
🔍 Вернемся к платежам. Запрос по
object_name:payments находит событие:
role_name=insideruser_ip=172.24.0.5event_type=SELECTstatus=SUCCESSquery_text=SELECT * FROM paymentsrows=5000Пять тысяч строк еще не доказывают утечку. Нужен baseline. Приложение и аналитик читали таблицу небольшими порциями — с
LIMIT 50 или через
count(*). Инсайдер выполнил полный скан без
LIMIT. Аномалия здесь — не просто большой
SELECT, а отклонение от привычного объема для этой роли и адреса.
Дальше проверяют смежные события:
ALL_ROLE — выдачу прав и попытки эскалации,
ALL_DDL_NONTEMP — изменения схемы,
AUTHENTICATE и
DISCONNECT — входы и отключения. Чтения
pg_class,
pg_attribute,
pg_roles выдают разведку. Даже запрещенное обращение к
pg_authid остается в журнале со
status=FAILURE.
Фильтр по роли и IP сшивает цепочку: разведка по каталогу, неудачные входы, затем успешное чтение 5000 платежей. Теперь известно, кто, откуда, сколько данных прочитал и что делал до этого.
📊 На дашборде полезно следить за долей отказов, максимумом строк за запрос, новыми ролями, адресами и пиками чтения. Grafana помогает заметить, LogsQL — разобраться.
🔗 Пошаговая настройка
pg_proaudit, конфиг коллектора, запросы для пяти сценариев и устройство дашборда — в
подробном разборе на Хабре.
🔔
Читайте нас в MAX