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

Git log для аудита КИИ 187-ФЗ: как история коммитов спасает на проверке ФСТЭК

Git log для аудита КИИ 187-ФЗ: как история коммитов спасает на проверке ФСТЭК
Время чтения: 11 мин.

По данным ФСТЭК (ссылается «Коммерсантъ»), из 700 проверенных значимых объектов критической информационной инфраструктуры обнаружено свыше 1200 нарушений, а минимальный уровень киберзащиты достигнут лишь у 36% организаций. Одна из системных причин — никто не фиксирует: кто, когда и зачем менял конфигурацию межсетевого экрана, правила IDS или параметры АСУ ТП. Всё держится на памяти инженера, который «вроде бы что-то менял в пятницу». На двух последних аудитах в промышленном секторе я показывал аудиторам вывод git log вместо папки с Word-документами — и проверка раздела «управление изменениями» заняла часы вместо дней. Разбираю на учебном проекте, как git log и сопутствующие команды формируют доказательную базу для аудита КИИ 187-ФЗ.

Пять вопросов аудитора и как git на них отвечает

187-ФЗ (Федеральный закон «О безопасности критической информационной инфраструктуры РФ» от 26.07.2017) обязывает субъектов КИИ — организации из сфер энергетики, транспорта, связи, здравоохранения, финансов и других, перечисленных в п. 8 ст. 2 — обеспечивать безопасность своих объектов. ФСТЭК (Федеральная служба по техническому и экспортному контролю — регулятор в области защиты информации) проводит плановые и внеплановые проверки (ст. 14). За нарушение правил эксплуатации значимых объектов КИИ (ЗОКИИ — объекты, которым присвоена категория значимости) предусмотрена уголовная ответственность по ст. 274.1 УК РФ — вплоть до 10 лет лишения свободы при тяжких последствиях. Это не абстрактная угроза: дела по этой статье уже возбуждаются.

Любая проверка управления изменениями на объекте КИИ сводится к пяти вопросам (такую модель описывает специалист по GitOps-аудиту Пим Виддерсховен):

  1. Что изменилось?
  2. Кто внёс изменение?
  3. Когда это произошло?
  4. Кто одобрил изменение?
  5. Совпадает ли то, что в продакшене, с тем, что было одобрено?

Тикет-система (Jira, Redmine) отвечает на первые четыре на уровне намерения. Пятый — только на доверии: инженер мог закрыть тикет, а сделать что-то другое. Git устраняет этот разрыв между записью и действием: изменение и запись об изменении — один объект (коммит). Коммит фиксирует diff (что изменилось), author (кто), timestamp (когда). Добавляем подписи и ревью через pull request — закрываются и вопросы об одобрении.

Вопрос аудитора Что показывает git Команда
Что изменилось? Diff между версиями — построчно git log --stat или git diff
Кто внёс? Поле Author (с GPG — криптографически) git log --author
Когда? Timestamp коммита git log --since --until
Кто одобрил? Merge-ревью в pull request git log --merges
Совпадает ли с одобренным? Diff = артефакт, не пересказ git log -p

Эта схема пересекается с требованиями NIST SP 800-53 Rev 5: семейство CM (Configuration Management) требует документирования процедур управления конфигурацией, семейство AU (Audit and Accountability) — ведения аудиторских записей. Git закрывает оба семейства одним инструментом, что помогает при соответствии 187-ФЗ.

Git log для аудита КИИ: команды и примеры вывода

Фильтрация по периоду и автору

Типичный запрос аудитора: «Покажите все изменения конфигурации межсетевого экрана за последний квартал». Команда git log --since="2025-07-01" --until="2025-10-01" --stat выводит коммиты за указанный период. Флаг --stat добавляет имена затронутых файлов и количество изменённых строк — аудитор видит не абстрактный лог, а конкретные артефакты.

Нужно проверить действия конкретного сотрудника (допустим, после увольнения администратора) — git log --author="ivanov" --oneline. Флаг --oneline сжимает вывод до одной строки на коммит: быстрый обзор за минуту.

Для формального отчёта к акту проверки пригодится форматированный вывод: git log --pretty=format:"%H | %an | %ai | %s" --since="2025-07-01". Здесь %H — полный хэш коммита (уникальный идентификатор, который меняется при любой правке истории), %an — имя автора, %ai — дата в ISO-формате, %s — сообщение коммита. Результат перенаправляется в файл для приложения к протоколу.

Ожидаемый вывод:

a1b2c3d4... | Петров А.В. | 2025-08-15 14:32:01 +0300 | fw: обновлены правила NAT для сегмента АСУ ТП
e5f6a7b8... | Сидорова Е.М. | 2025-09-02 09:15:44 +0300 | ids: добавлено правило детекции по инциденту #41
c9d0e1f2... | Петров А.В. | 2025-09-10 11:48:22 +0300 | acl: закрыт доступ с VLAN 42 после инцидента #187

Каждая строка — самостоятельное доказательство для журналирования изменений инфраструктуры: кто, когда, что и зачем. Обратите внимание на сообщения коммитов — они содержат номер инцидента и контекст действия. Это не случайность, а часть процесса: сообщение «fix» для аудитора бесполезно. А «acl: закрыт доступ с VLAN 42 после инцидента #187» — полноценная запись.

Git blame — кто менял конкретную строку конфигурации

git blame отвечает на вопрос: «Кто последним изменил эту конкретную строку?» Зачем: если при проверке в конфигурации межсетевого экрана обнаружена небезопасная настройка (открытый порт, слабый ACL), git blame configs/firewall.conf покажет автора и дату появления этой строки.

Это инструмент трассируемости изменений (audit trail — аудиторский след), а не поиск виноватых. Когда аудитор видит, что конкретное правило появилось 15 августа и его внёс конкретный инженер — вопрос закрыт документально. Без git blame начинается устный опрос сотрудников. Обычно никто ничего не помнит.

Полезный приём: git blame -L 10,20 configs/firewall.conf ограничивает вывод строками 10–20. Удобно при разборе конкретного инцидента, когда не нужно листать весь файл.

Комбинация git log и git blame закрывает два из пяти вопросов аудитора (что и кто) с построчной детализацией. Ни один Word-документ такой точности не даст.

Подписанные коммиты — доказательство авторства для подготовки к проверке ФСТЭК

Поле Author в git — обычный текст. Любой может выполнить git config user.name "Иванов" и коммитить от чужого имени. Для учебного проекта мелочь, для объекта КИИ — юридическая проблема. На проверке ФСТЭК такой журнал не выдержит вопроса: «Как вы подтверждаете, что изменение внёс именно этот сотрудник?»

Решение — подписанные коммиты с GPG (GNU Privacy Guard — инструмент асимметричного шифрования). У каждого сотрудника пара ключей: закрытый (хранится только у него, в идеале на аппаратном токене — Рутокен или YubiKey) и открытый (загружается в Git-хостинг). При коммите git создаёт цифровую подпись закрытым ключом. При проверке (git verify-commit <хэш>) подпись сверяется с открытым.

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

Настройка занимает три действия. Генерируем ключевую пару: gpg --full-generate-key (RSA 4096 бит, email должен совпадать с git config user.email). Указываем git использовать ключ: git config --global user.signingkey <ID_ключа>. Включаем автоматическую подпись: git config --global commit.gpgsign true. Теперь каждый коммит подписывается автоматически.

Проверка: git log --show-signature выводит Good signature from "Петров А.В. <petrov@company.ru>" — или BAD signature, если подпись не сходится. Для аудитора это разница между «мы верим, что это Петров» и «криптографически подтверждено, что это Петров».

Критический нюанс: generic-аккаунты (admin, operator, root) полностью разрушают аудиторский след. Каждый коммит должен быть привязан к реальному человеку с именным ключом. Это перекликается с OWASP A08:2021 (Software and Data Integrity Failures) — защита целостности данных и кода через верификацию авторства.

Версионирование конфигураций КИИ: что хранить в репозитории

На учебном проекте (и в реальной практике) в git кладутся текстовые конфигурации, а не бинарные дампы:

  • правила межсетевого экрана (iptables, nftables, экспорт политик Cisco ASA / Check Point)
  • настройки IDS/IPS (правила Suricata, Snort)
  • конфигурации коммутаторов и маршрутизаторов (текстовый экспорт)
  • параметры АСУ ТП (PLC-конфигурации в текстовом формате)
  • локальные нормативные акты ИБ (в Markdown — тоже версионируются)
  • шаблоны уведомлений ГосСОПКА (Государственная система обнаружения, предупреждения и ликвидации последствий компьютерных атак, ст. 5 187-ФЗ) — чтобы при инциденте не тратить время на оформление

Структура репозитория: каталог configs/ для сетевых конфигураций, policies/ для ОРД (организационно-распорядительная документация), ids-rules/ для правил детекции, incidents/ для журналов реагирования. Каждый каталог — зона ответственности конкретного специалиста.

Здесь полезен файл CODEOWNERS (поддерживается в GitLab, GitHub, Gitea): он задаёт, кто обязан подтвердить (approve) изменения в конкретном каталоге. Изменения в configs/firewall/ проходят ревью руководителя ИБ, ids-rules/ — аналитика SOC. Сам CODEOWNERS тоже под контролем версий: его изменение требует ревью, что исключает тихое удаление рецензента из цепочки. Я видел случай, когда инженер убрал себя из CODEOWNERS, чтобы пушить правила без согласования. Git зафиксировал и это.

Делай раз, делай два, делай три: документирование изменений для аудита на учебном проекте

Пошаговый сценарий для учебного стенда. Предпосылки: машина с Linux (Ubuntu/Debian), установленные git и gnupg (если нет — sudo apt install git gnupg), настроенный GPG-ключ (см. раздел выше).

Делай раз: инициализируем репозиторий и делаем первый подписанный коммит. Создаём каталог проекта: mkdir kii-audit-lab && cd kii-audit-lab && git init. Строим структуру: mkdir configs policies ids-rules incidents. Создаём начальный файл — configs/firewall.conf с базовыми правилами. Выполняем git add . и затем git commit -S -m "init: начальная конфигурация учебного ЗОКИИ". Флаг -S явно подписывает коммит. Как понять, что получилось: команда git log --show-signature -1 должна вывести «Good signature» и ваше имя. Если вместо этого «No signature» — проверьте, что commit.gpgsign выставлен в true.

Делай два: вносим изменение и проверяем трассируемость. Открываем configs/firewall.conf, добавляем строку с новым правилом (блокировка подсети). Коммитим: git commit -am "fw: заблокирована подсеть 10.0.42.0/24 по инциденту #12". Сообщение содержит контекст — номер инцидента. Аудитор видит не «что-то поменялось», а «поменялось в связи с конкретным событием». Проверяем: git log --oneline -3 показывает коммиты с читаемыми сообщениями. Затем git blame configs/firewall.conf — новая строка привязана к вашему имени и текущей дате.

Делай три: pre-commit хук для защиты от типичных ошибок. Pre-commit хук — скрипт, который git запускает автоматически перед каждым коммитом. Если скрипт завершается с ошибкой — коммит блокируется. Цель: не допустить случайного попадания пароля, API-ключа или пустого файла в историю.

#!/bin/sh
# .git/hooks/pre-commit — проверка перед коммитом
# Блокируем коммит, если в изменениях есть пароли или ключи
if git diff --cached | grep -qiE '(password|secret|api_key)\s*=\s*.+'; then
  echo "БЛОК: обнаружен пароль или ключ в коммите. Удалите секрет."
  exit 1
fi
# Блокируем пустые .conf файлы
for f in $(git diff --cached --name-only | grep '\.conf$'); do
  [ -f "$f" ] && [ ! -s "$f" ] && echo "БЛОК: пустой $f" && exit 1
done

Сохраняем в .git/hooks/pre-commit и делаем исполняемым: chmod +x .git/hooks/pre-commit. Как проверить: добавьте строку password = MySecret123 в любой файл и попробуйте закоммитить — хук заблокирует операцию с сообщением «БЛОК: обнаружен пароль или ключ в коммите». Уберите строку — коммит пройдёт. Это принцип «shift left» в DevSecOps: ошибка ловится до попадания в историю, а не после того, как секрет уже утёк в репозиторий.

Где git log перестаёт работать

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

Аварийные изменения. Во время активной атаки никто не ждёт ревью pull request. Решение: ветка emergency/ с правом прямого пуша для ограниченного круга лиц (break-glass role). Аварийное изменение фиксируется в истории с именем ответственного, а после стабилизации проходит обязательный пост-фактум ревью. Главное — изменение всё равно попадает в git, а не теряется в SSH-сессии.

Дрифт конфигурации. Кто-то зашёл на сервер по SSH и поменял настройку напрямую, минуя git. Репозиторий не знает об изменении, реальное состояние разъехалось с декларированным. Решение: GitOps-подход — автоматическая периодическая сверка живой конфигурации с репозиторием через Ansible, Salt или аналогичный инструмент. Расхождение = инцидент. Без такой сверки git превращается в «красивый журнал», который не отражает реальность.

Привязка к ГосСОПКА. При компьютерном инциденте на ЗОКИИ субъект КИИ обязан уведомить НКЦКИ (Национальный координационный центр по компьютерным инцидентам) в течение 3 часов (ст. 5 187-ФЗ). Git log не заменяет уведомление, но показывает хронологию изменений до, во время и после инцидента — именно те данные, которые нужны для отчёта о реагировании (срок подачи результатов — 48 часов для ЗОКИИ).

Штрафы и ответственность. По данным ICL Services, нарушение порядка информирования об инцидентах грозит штрафом до 500 000 рублей, несоблюдение требований к системам безопасности ЗОКИИ — до 100 000 рублей. Git log не избавит от штрафа за неотправленное уведомление. Но выстроенный процесс документирования изменений снижает количество замечаний при проверке, а каждое замечание может обернуться предписанием и повторной проверкой.

Срок хранения. 187-ФЗ не устанавливает явный срок хранения журналов изменений, но приказы ФСТЭК №235 и №239 подразумевают хранение на весь период эксплуатации ЗОКИИ. Git хранит полную историю по умолчанию — пока жив репозиторий. Регулярный bare clone на отдельный сервер решает вопрос резервирования.

Последние полтора года я настраиваю git-репозитории для хранения конфигураций на объектах КИИ в промышленном и энергетическом секторе. Технически всё работает. Самая частая проблема — не инструмент, а дисциплина. Инженеры коммитят с сообщением «fix» вместо описания, забывают номер инцидента, используют общий аккаунт. Я видел проверки, где история коммитов была идеальной — и аудитор зафиксировал это в протоколе как сильную сторону. И видел проверки, где репозиторий существовал для галочки, реальные изменения вносились по SSH мимо git — и всё посыпалось на первом вопросе «покажите, кто открыл этот порт».

Git log — это не compliance. Это инфраструктура доказательной базы, которая работает при одном условии: подписанные коммиты от именных аккаунтов, осмысленные сообщения с номером задачи, ревью через pull request и автоматическая сверка с живой конфигурацией. Без этого git — просто папка с файлами, у которой есть красивая команда log. На IB Basics показывают не теорию, а как джуны реально решают подобные рабочие задачи — от первых коммитов до выстраивания процессов, которые переживают аудит.

Эту тему и смежные навыки разбирают на практике в курсе «Git. Система контроля версий» Codeby Academy.