Меня зовут Семён Ремезов, я Senior QA в компании «Гринатом» (мы пишем софт для «Росатома»).

Про такие вещи обычно говорят шёпотом в курилках либо громко обсуждают, только когда уже «прилетело».

Можно, конечно, наклепать синтетических моков, но в сложных системах это мало что даст. У нас в «Гринатоме» крутятся огромные системы. Это не просто «магазин с корзиной». Это продукты с чудовищным уровнем вложенности, тоннами информации и зависимостями, которые переплетаются между собой, как корни столетнего дуба. Данные пересекаются везде и всюду.

Синтетика — это стерильная лаборатория. Моковые данные — это то, как разработчик представляет себе данные. А их реальный массив — это то, как пользователи на самом деле кошмарят систему.

Мы внедрили у себя security-лейблы в Postgres Pro Enterprise для анонимизации, и этот путь был, мягко говоря, тернистым. Если вы думаете, что анонимизация — это просто скрипт UPDATE users SET name = 'Ivan', то у меня для вас плохие новости.

Давайте разберём, как мы построили процесс, почему отказались от дорогих «коробочных» решений и как заставили Postgres 15-й версии работать нормально.

Как додумались до Postgres Pro

Когда поняли, что нам нужны обезличенные копии, начали перебирать варианты. Первая мысль любого инженера — написать скрипт. Берём базу, пишем простыню апдейтов, заменяем фамилии на «Тестов».

Но в сложной реляционной базе данных, где связи держатся на честном слове и внешних ключах, грубое обновление может превратить эти данные в фарш. Если при обновлении таблицы пользователей забыть про лог операций — привет, мёртвые души! Плюс обычный самописный скрипт «update» не сертифицирован и провалит первый же аудит безопасности в госкорпорации.

Тогда мы пошли смотреть, что есть на рынке. Там много красивых «коробок», например, «Гарда Маскирование». Продукт достойный, есть сертификаты (для нашей СБ это обязательно), принцип «нажал кнопку — и готово».

Мы почти подписали договор, но нас остановила экономика. Возник вопрос: оправдает ли цель средства? 

Пока мы всё обдумывали, случилось неожиданное, но в то же время занимательное событие — вышла 15-я версия Postgres Pro Enterprise. Оказалось, что все нужные для маскирования инструменты уже лежат внутри лицензии, которую мы и так покупаем: не надо тащить в контур левый софт.

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

Бюрократия нужна

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

Вместе с безопасниками составили огромную портянку, где чётко разложили все данные по полочкам. Общедоступное (адреса офисов, названия департаментов) оставляем. СНИЛСы, телефоны, зарплаты скрываем железобетонно, а что-то и вовсе дропаем без задней мысли.

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

Ещё составили техническую карту (таблицу анонимизации). Это наш мануал, без которого в работу лезть не стоит. Там прописано всё: какая таблица, какая колонка и какой метод (random_in_range, shuffling и т. д.) применяются.

Как работают Security Labels

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

А Provider — это загружаемый модуль (скомпилированный C-код, а не SQL-функция), который регистрирует себя через register_label_provider, видит метки и исполняет их.

Модуль проверяет, совместима ли метка с типом данных, чтобы на выходе не получился мусор.

Для безопасности мы работаем только на изолированной копии — никакого живого прода. Снимаем дамп, переносим его на отдельный инстанс с жёстким сетевым периметром и антивирусом, куда есть доступ только у ограниченного списка лиц.

Все правила анонимизации собираем в один большой SQL-скрипт, а затем вызываем функцию pg_anon.anonymize_database. Она берёт массив данных, сопоставляет его с установленными правилами и проводит все нужные трансформации — от удаления до замены. На выходе мы получаем базу, которая структурно идентична оригиналу, но при этом полностью очищена от чувствительной информации. Кроме того, сохраняется консистентность данных: фарш нам не нужен, нам, пожалуйста, правильные «котлетки».

Как мы прячем данные

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

А вот всё, что позволяет вычислить человека — СНИЛСы, личные телефоны, почты, — удаляем под корень. Это самый эффективный способ.

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

Для создания такого «контролируемого хаоса» хорошо подходит перестановка. Мы берём реальные фамилии и имена, просто перетасовывая их. В итоге Иван Петров с улицы Ленина превращается в Сергея Сидорова с улицы Гагарина. Данные реальные, и связи не разорваны, просто теперь ваш id в системе будет являться кем-то другим и с другим набором данных. 

Если же речь идёт о статусах вроде «Active», то тут используем статическую замену, чтобы не сломать логику.

Для ИНН мы используем генераторы. Они создают номера, которые проходят все проверки по контрольным суммам, но на самом деле не существуют. Зарплаты (если они нужны для тестов) рисуем рандомом в заданном адекватном диапазоне.

Финальные штрихи, чтобы база поехала

Маскирование — это полдела. После того как скрипт прошёлся по базе, она находится в состоянии «грогги»: индексы побиты, статистика устарела. Поэтому нам нужно привести её в чувство.

Сначала мы обновляем схемы и связи между микросервисами, чтобы всё снова начало «биться» друг с другом. Затем обязательно делаем REINDEX, иначе всё будет тормозить или сыпать ошибками. И в самом конце запускаем ANALYZE, чтобы планировщик запросов понимал, с чем он теперь имеет дело.

Стоило ли оно того

В итоге мы получили спокойный сон наших безопасников, т. к. Postgres Pro Enterprise сертифицирован, что для нас критично.

Мы контролируем каждый байт и можем моментально внести любое изменение в скрипты, не полагаясь на «чёрный ящик» от стороннего вендора. Плюс мы всегда можем настроить правила под любое экзотическое поле. Да, это была колоссальная ручная работа, и кнопки «Сделать хорошо» у нас нет, но зато мы сэкономили бюджет и набрались опыта.

Почему не сторонние сканеры? Они берут деньги за «умный поиск» персданных, но работают по паттернам. Они найдут поле passport, но пропустят user_comment, где оператор записал данные паспорта текстом. Вам всё равно придётся перепроверять всё руками.

На чём мы спотыкались

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

1. Консистентность в микросервисах при шаффлинге. В базе А Иван стал Петром, а в реплицируемой базе Б тот же Иван стал Сидором (рандом сработал иначе). Мы решаем это через «Базовый модуль». Маскируем данные в одной мастер-базе (справочник пользователей), а потом разносим эти уже изменённые, но согласованные данные по остальным базам.

2. В живую базу не лезем. Мы анонимизируем только в дампе. Переливаем дамп на отдельный сервер и там запускаем скрипты. Есть вариант инжектиться в пайплайн переливки и маскировать на лету, что сложнее и рискованнее, но и до этого руки дотянутся.

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

Зачем вообще платить за энтерпрайз-версию, если на ГитХабе полно бесплатных библиотек с похожим функционалом? В крупной госкорпорации вы просто не сможете объяснить СБ, почему используете софт без сертификата и поддержки. Мы платим не столько за функции, сколько за сертификат ФСТЭК и гарантию того, что в инструменте нет «закладок».

Если вы всё ещё пишете UPDATE-скрипты руками — остановитесь. Посмотрите в сторону Security Labels. Это долго на старте, больно в процессе разметки, но в итоге вы получаете инструмент, который позволяет спокойно работать и вам, и безопасникам.