Протоколирование, аудит

~ 35 минут
Представьте туриста, который использует мобильное приложение для подачи заявки на возмещение ущерба. В этом случае протоколирование всех действий пользователя может сыграть решающую роль в разрешении возможных проблем. Если у туриста возникнут вопросы о статусе его заявки, система сможет предоставить полную информацию о каждой операции, включая время входа, загрузку документов и любые возникающие ошибки. Это не только ускоряет процесс решения проблем, но и повышает доверие клиентов, показывая, что их действия фиксируются и могут быть проверены.
В этом уроке поговорим о том, как проектировать такие подсистемы, которые будут эффективно работать в различных приложениях. Вы узнаете, какие процессы стоит протоколировать и как лучше всего организовать хранение и передачу данных в системе аудита. Изучите, какие события фиксировать, чтобы при возникновении ошибки или запроса пользователя можно было легко проследить всю цепочку его действий.
Урок охватывает важные аспекты проектирования подсистемы протоколирования и аудита, включая определение состава процессов.

Кейс урока: взаимодействие со страховой системой

Некий турист использует мобильное приложение для страхования путешествий. Во время путешествия рейс отменили из-за плохих погодных условий. В приложении турист подаёт заявку на возмещение ущерба: загружает подтверждающие документы и ждёт поддержку через чат.
Весь процесс успешно завершился выплатой компенсации на электронный кошелёк туриста.
Разберём этот кейс в контексте проектирования системы протоколирования и аудита.

1. Полнота данных

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

JSON

{
  "event_id": "abc123",
  "timestamp": "2024-07-12T14:30:00Z",
  "event_type": "login_attempt",
  "user_id": "anna456",
  "result": "success",
  "details": {
    "ip_address": "203.0.113.5",
    "location": "Paris, France",
    "device": "iPhone 12",
    "os": "iOS 17"
  }
},
{
  "event_id": "def456",
  "timestamp": "2024-07-12T14:35:00Z",
  "event_type": "claim_submission",
  "user_id": "anna456",
  "result": "success",
  "details": {
    "claim_id": "claim789",
    "reason": "Flight Cancellation",
    "document_uploaded": "flight_cancellation.pdf",
    "claim_amount": 500.00,
    "status": "submitted"
  }
},
{
  "event_id": "ghi789",
  "timestamp": "2024-07-12T14:45:00Z",
  "event_type": "claim_approval",
  "user_id": "anna456",
  "result": "approved",
  "details": {
    "claim_id": "claim789",
    "approval_amount": 500.00,
    "payout_method": "Digital Wallet",
    "payout_status": "completed"
  }
}
 
На что стоит обратить внимание?
  • Избыточность логов Если система будет фиксировать каждое мелкое действие (например, каждую смену экрана приложения), это приведёт к огромным объёмам данных и усложнит анализ. Важно находить баланс между детализацией и минимализмом.
  • Пропуск критических событий Недостаточное логирование (например, отсутствие записи изменений в заявке) может заблокировать последующий анализ инцидентов. В этом кейсе важно логировать все этапы: от подачи заявки до выплаты.

2. Сегментация данных

Для упрощения анализа логи должны быть разделены на категории: действия пользователя, изменения статуса заявки, взаимодействие с поддержкой.
Пример сегментации логов:
  • Аутентификация и авторизация Вход в систему, проверка прав доступа.
  • Финансовые операции Подтверждение заявки на возмещение, передача средств.
  • Взаимодействие с поддержкой Чат с поддержкой, получение медицинских консультаций.
На что стоит обратить внимание:
  • Сложность сегментации Иногда одно событие может относиться к нескольким категориям (например, финансовая операция и обращение в поддержку). Система должна быть способна правильно и однозначно распределять события по категориям.
  • Избыточная детализация Слишком мелкое разделение логов по категориям может привести к путанице и усложнению анализа.

3. Централизация и автоматизация анализа

Логи из разных частей системы (мобильное приложение, серверы, платёжные системы) должны передаваться в центральную систему для их анализа и хранения. Система должна автоматически анализировать логи на предмет выявления аномалий. Например, если турист подаёт несколько заявок подряд за короткий период, это должно быть зафиксировано и система должна уведомить службу безопасности.
На что стоит обратить внимание?
  • Ложные срабатывания Автоматизация может иногда ошибочно интерпретировать нормальные действия как аномалии. Например, если турист случайно подаст заявку дважды, это может вызвать ложное срабатывание.
  • Обработка больших данных Система должна быть способна эффективно анализировать большие объёмы данных без снижения производительности.

4. Безопасность

Логи могут содержать чувствительные данные — финансовую информацию или персональные данные. Важно защищать эти данные от несанкционированного доступа.
На что стоит обратить внимание?
  • Открытые данные в логах Логи не должны содержать пароли или финансовые данные в открытом виде. Например, при логировании финансовой транзакции запрещено записывать полный номер карты или CVV-код.
  • Защита логов Логи должны быть зашифрованы как при хранении, так и при передаче по сети.

Принципы построения подсистемы аудита

Сначала введём необходимые понятия.
Аудируемость — это способность системы или процесса подвергаться аудиту. Это означает, что система спроектирована так, чтобы фиксировать все необходимые данные и события, что позволяет потом провести анализ и оценку её состояния.
Аудит — это процесс анализа и проверки данных и событий в системе для определения их соответствия требованиям безопасности, стандартам и политике организации.
Логирование — это процесс записи информации о событиях и действиях, происходящих в системе. Логи служат основой для аудируемости, поскольку фиксируют все значимые действия, которые могут быть впоследствии проанализированы в ходе аудита.
Если коротко и в обратном порядке:
✏️ Логирование — сохранение данных. Аудит — анализ данных логирования. Аудируемость — оценка возможности аудита.

Когда нужен аудит?

  1. После инцидентов безопасности В случае попытки взлома или утечки данных аудит помогает определить, как произошёл инцидент, какие данные были скомпрометированы и какие меры необходимо предпринять для предотвращения повторения ситуации.
  2. Для регулярных проверок соответствия Для обеспечения соблюдения нормативных требований и внутренних политик безопасности регулярные аудиты помогают выявить несоответствия и разработать планы по их устранению.
  3. При изменениях в инфраструктуре При добавлении новых систем или обновлении существующих компонентов аудит позволяет удостовериться, что все изменения соответствуют стандартам безопасности.
  4. Перед внедрением новых функций Перед запуском новых функций или услуг, особенно если они связаны с обработкой конфиденциальных данных, аудит помогает оценить потенциальные риски и разработать меры для их минимизации.
  5. Для периодической оценки эффективности мер безопасности Аудиты помогают определить, насколько эффективны действующие меры безопасности и где можно внести улучшения.
Цель аудита — обеспечить прозрачность и контроль над действиями внутри информационной системы.
Кейс
Турист подаёт заявку на возмещение ущерба через мобильное приложение. Логирование может фиксировать каждое действие, начиная с попытки входа в приложение и заканчивая подтверждением выплаты.
Включение всех событий (каждая смена экрана, нажатие кнопок и загрузка документов) обеспечит полное покрытие действий пользователя. Однако это создаст огромные объёмы логов, что усложнит их анализ и может замедлить работу системы.
Логирование ключевых действий (успешные и неуспешные попытки входа, подача заявки и статус выплаты) сделает систему более управляемой и упростит анализ. Это позволит быстро выявлять инциденты и реагировать на них, однако в этом случае могут быть упущены менее значимые, но потенциально важные события.
Ключевой вызов заключается в нахождении оптимального баланса между полнотой данных и их эффективностью: необходимо логировать достаточно информации, чтобы обеспечить полное понимание действий и событий в системе, но без избыточности, которая усложняет анализ и управление.

Основные принципы аудита

Турист, использующий мобильное приложение для страхования путешествий, столкнулся с неожиданной отменой рейса. В панике он подал заявку на возмещение ущерба через приложение, несколько раз загружая необходимые документы в попытке добиться внимания службы поддержки. В этом случае протоколирование и аудит становятся ключевыми элементами, позволяющими обеспечить безопасность его личных данных и эффективность обработки заявки.
Если система не сможет зафиксировать все эти действия, включая попытки подачи нескольких заявок, последствия могут быть серьёзными. Потеря информации о предыдущих действиях может привести к путанице и задержкам в выплатах, к увеличению нагрузки на службу поддержки. Чётко выстроенный процесс аудита помогает избежать подобных инцидентов.
Перечислим основные принципы аудита:
  1. Полнота данных Логирование должно фиксировать все значимые действия, включая операции аутентификации, авторизации, доступ к данным и изменения конфигурации. Однако избыточное протоколирование может перегрузить систему и усложнить анализ данных, поэтому важно найти баланс.
  2. Сегментация данных Разделение событий по категориям (например, аутентификация, доступ к данным, административные действия) улучшает читаемость логов и повышает эффективность последующего анализа.
  3. Централизация и анализ Предусмотрите механизм передачи данных в централизованное хранилище для их анализа. Инструменты вроде ELK Stack или Splunk позволяют эффективно анализировать информацию, помогая выявлять потенциальные угрозы в режиме реального времени.
  4. Безопасность Данные аудита могут содержать чувствительную информацию, поэтому они должны быть защищены.
  5. Масштабируемость Подсистема аудита должна быть спроектирована с учётом будущего роста системы.
  6. Автоматизация анализа Интегрируйте в подсистему автоматизированные инструменты анализа и корреляции данных. Добавьте оповещение об инцидентах в реальном времени (алертинг).
Пример применения принципов аудита системы страхования путешествий
После того как турист подал несколько заявок на возмещение ущерба из-за отмены рейса, страховая компания решила провести аудит своей системы протоколирования и аудита.
  1. Полнота данных В ходе аудита выяснилось, что не все попытки входа в систему записывались. Это означало, что сотрудники службы безопасности не могли определить, были ли несанкционированные попытки доступа к личной информации клиентов. Вывод Страховая компания приняла решение фиксировать все попытки входа и выхода, при этом установив фильтры для записи только неудачных попыток, чтобы избежать избыточности логов.
  2. Сегментация данных Аудит показал, что логи хранились в одной базе данных без чёткой сегментации. Это усложняло анализ данных. Вывод Компания внедрила категоризацию логов на уровнях (аутентификация, доступ к заявкам, операции с финансовыми данными), что позволило облегчить анализ и повысить скорость реагирования на инциденты.
  3. Централизация и анализ Все данные из различных систем (мобильное приложение, серверы, платёжные системы) собирались в едином централизованном хранилище. Вывод Внедрение инструмента ELK Stack позволило автоматизировать анализ логов и быстро выявлять аномалии, например, случаи, когда один пользователь подаёт несколько заявок на возмещение в короткий срок.
  4. Безопасность Аудит показал, что некоторые логи содержали конфиденциальную информацию (номера счетов). Вывод Компания приняла решение о маскировании таких данных при записи в логи, чтобы предотвратить утечки в случае доступа к логам несанкционированными лицами.
  5. Масштабируемость Страховая компания планировала расширение, поэтому важно было спроектировать систему логирования с учётом роста числа пользователей и данных. Вывод Разработана архитектура, позволяющая легко масштабировать систему хранения и анализа логов по мере роста компании.
  6. Автоматизация анализа В ходе аудита было установлено, что многие инциденты оставались незамеченными из-за недостаточной автоматизации. Вывод Интеграция автоматических инструментов анализа и корреляции данных позволила быстро реагировать на аномальные действия вроде повторных попыток подачи заявок.

Определение состава процессов, подлежащих аудиту

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

1. Аутентификация и управление доступом

  • Попытки входа: Протоколируйте все успешные и неуспешные попытки входа в систему. Неудачные попытки аутентификации (например, неверный пароль) часто являются признаком попытки взлома или подбора пароля.
  • Изменение учетных записей: Записывайте все действия, связанные с созданием, изменением или удалением учетных записей, включая изменения прав доступа. Любое аномальное изменение учетных записей не должно остаться без внимания.
  • Смена паролей: Фиксируйте запросы на изменение и восстановление паролей, чтобы отслеживать подозрительную активность.
  • Запросы на авторизацию: Протоколируйте все попытки доступа к ресурсам, особенно если доступ был отклонен. Это позволяет отследить потенциально вредоносные действия.

2. Доступ к данным и ресурсам

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

3. Административные действия

  • Изменение политик безопасности: Логи должны отражать действия, связанные с настройкой политик аутентификации, авторизации, аудита, резервного копирования и восстановления.
  • Доступ к системным журналам: Контролируйте доступ к логам аудита. Несанкционированный доступ к журналам может указывать на попытку злоумышленника скрыть свои следы.
  • Управление привилегиями: Фиксируйте все операции по выдаче или отзыву привилегий пользователей. Действия, связанные с повышением привилегий - частый элемент атаки.

4. События безопасности и инциденты

  • Попытки сканирования уязвимостей: Записывайте все попытки сканирования сети, портов и приложений.
  • Перегрузка системы: Фиксируйте случаи перегрузки ресурсов (например, CPU, память, сеть).
  • Обнаружение вредоносной активности: Интегрируйте с системой мониторинга антивирусы.

5. Бизнес-транзакции и операции

  • Финансовые операции: В системах, связанных с финансовыми транзакциями, протоколируйте все операции, которые влияют на активы организации.
  • Изменение данных клиентов: Записывайте все изменения в конфиденциальной информации клиентов для последующего анализа на предмет аномалий или подозрительных действий.

Проектирование структуры данных для аудита

Когда логи плохие:
  1. Логи неструктурированны или неинформативны, что затрудняет аудит.
  2. Логи содержат недостаточно информации о событиях, и понять истинные причины проблемы становится затруднительно. Это может привести к неверным выводам в процессе аудита.
  3. Качество логов неудовлетворительно в целом, и это может привести к большим проблемам. Специалисты службы ИБ не смогут качественно выполнить свои задачи по своевременному выявлению уязвимостей.
Как из плохих логов сделать хорошие:
  1. Структурируйте данные
    • Создайте единый формат для всех логов (например, JSON-схема).
    • Убедитесь, что каждая запись содержит ключевые поля, например: timestamp, event_id, event_type, user_id, result.
  2. Добавьте информативность
    • Включите дополнительные поля — IP-адрес, местоположение и детали действия.
    • Проверьте, что важные события фиксируются с достаточным уровнем детализации.
  3. Классифицируйте события
    • Разделите логи на категории (например, аутентификация, доступ к данным, ошибки).
    • Убедитесь, что система позволяет легко фильтровать логи по категориям.
  4. Учитывайте специфические требования
    • Определите особенности логирования в зависимости от типа приложения (например, для финансовых данных). В целом список ключевых полей в конкретной системе может быть другим. Например, в списке может присутствовать route — маршрут, в котором отражены задействованные микросервисы.
    • Обеспечьте соответствие нормативным требованиям вроде ФЗ-152.
  5. Автоматизируйте анализ
    • Настройте системы мониторинга для автоматического анализа логов (например, ELK Stack или Splunk).
    • Установите правила для выявления аномалий и уведомлений.
  6. Установите политику хранения и ротации
    • Определите политику хранения логов (например, на 1 год для аутентификации, 5 лет для транзакций).
    • Настройте автоматическую ротацию и архивирование логов для предотвращения переполнения диска.
  7. Проведите обучение и подготовьте документацию
    • Организуйте обучение для разработчиков и администраторов по стандартам логирования.
    • Обеспечьте наличие документации, описывающей правила ведения логов.
  8. Проверяйте логи периодически
    • Установите график для регулярной проверки качества логов.
    • Анализируйте логи на предмет полноты, корректности и соответствия установленным стандартам.

Записи в логах

Записи в логах должны быть структурированными, информативными и стандартизированными.
  1. Структурированные Записи должны иметь предопределённый формат (например, JSON), чтобы каждая запись содержала одинаковые поля с чёткими значениями. Это облегчает автоматизированный анализ, позволяет использовать инструменты для обработки данных и делает логи более читаемыми для администраторов и разработчиков. Пример структуры может включать поля timestamp, event_id, user_id, event_type, которые предоставляют всю необходимую информацию в удобном формате.
  2. Информативные Каждая запись должна содержать достаточно информации, чтобы её можно было понять без необходимости обращения к другим источникам. Это включает в себя ключевые данные о событии: тип события, результат выполнения действия, детали о пользователе и контексте (например, IP-адрес, местоположение, устройство). Информативные записи позволяют быстро идентифицировать и проанализировать инциденты без необходимости дополнительного исследования.
  3. Стандартизированные Все записи в логах должны следовать единой схеме. Стандартизация позволяет установить чёткие требования к записи данных, включая обязательные и опциональные поля, типы данных и форматы. Это гарантирует, что все записи будут созданы в соответствии с установленными правилами, что облегчает их обработку и анализ.
Разберём пример. Для начала нужно определиться с форматом лог-сообщений. Будем использовать json-схему.
Формат логов на примере JSON Schema
JSON Schema позволяет описывать структуру JSON-данных, определяя, какие поля могут присутствовать, какие типы данных они могут содержать и какие значения являются допустимыми. Использование JSON Schema для логов помогает поддерживать стандартизированный формат, который облегчает анализ и обработку данных.
Пример схемы JSON Schema для записей логов:

JSON

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "timestamp": {
      "type": "string",
      "format": "date-time"
    },
    "event_id": {
      "type": "string"
    },
    "user_id": {
      "type": "string"
    },
    "event_type": {
      "type": "string",
      "enum": ["registration", "login", "data_access", "payment", "admin_action"]
    },
    "result": {
      "type": "string",
      "enum": ["success", "failed", "rejection"]
    },
    "details": {
      "type": "object",
      "additionalProperties": true
    }
  },
  "required": ["timestamp", "event_id", "user_id", "event_type", "result", "details"]
} 
Плюсы:
  1. Валидация данных При записи логов, особенно на этапе тестирования, можно использовать JSON Schema для проверки, что данные соответствуют заданной структуре.
  2. Документация JSON Schema служит документацией для команды, описывая, какие поля должны присутствовать в записях логов и как они должны быть структурированы.
  3. Упрощение анализа Стандартизированные логи облегчают процесс анализа, позволяя быстро определять ключевые поля и значения, важные для аудита и мониторинга.

Ключевые элементы структуры данных для аудита

Микросервис 1: сервис управления пользователями

GO

package main

import (
    "encoding/json"
    "log"
    "time"
)

type LogEntry struct {
    Timestamp string `json:"timestamp"`
    EventID   string `json:"event_id"`
    UserID    string `json:"user_id"`
    EventType string `json:"event_type"`
    Result    string `json:"result"`
    Details   struct {
        IPAddress string `json:"ip_address"`
        Location  string `json:"location"`
        Device    string `json:"device"`
        OS        string `json:"os"`
    } `json:"details"`
}

// logUserRegistration пример кода для записи лога
func logUserRegistration(userID string, result string) {
    entry := LogEntry{
        Timestamp: time.Now().Format(time.RFC3339),
        EventID:   "evt_001",
        UserID:    userID,
        EventType: "registration",
        Result:    result,
        Details: struct {
            IPAddress string `json:"ip_address"`
            Location  string `json:"location"`
            Device    string `json:"device"`
            OS        string `json:"os"`
        }{
            IPAddress: "127.0.0.1",
            Location:  "Moscow, Russia",
            Device:    "Some-Phone",
            OS:        "iOS XX",
        },
    }

    logJSON, err := json.Marshal(entry)
    if err != nil {
        log.Printf("Error marshaling log entry: %v", err)
        return
    }
    log.Println(string(logJSON))
}

func main() {
    logUserRegistration("user123", "success")
} 
Микросервис 2: сервис обработки платежей

GO

package main

import (
    "encoding/json"
    "log"
    "time"
)

type PaymentLogEntry struct {
    Timestamp     string `json:"timestamp"`
    EventID       string `json:"event_id"`
    TransactionID string `json:"transaction_id"`
    UserID        string `json:"user_id"`
    EventType     string `json:"event_type"`
    Result        string `json:"result"`
    Details       struct {
        Amount        int    `json:"amount"`
        Currency      string `json:"currency"`
        Reason        string `json:"reason"`
        PaymentMethod string `json:"payment_method"`
    } `json:"details"`
}

type PaymentFailureDTO struct {
    TransactionID string
    UserID        string
    Reason        string
    Amount        int
    Currency      string
    PaymentMethod string
    EventID       string
}

func logPaymentFailure(dto PaymentFailureDTO) {
    entry := PaymentLogEntry{
        Timestamp:     time.Now().Format(time.RFC3339),
        EventID:       dto.EventID,
        TransactionID: dto.TransactionID,
        UserID:        dto.UserID,
        EventType:     "payment",
        Result:        "failed",
    }
    entry.Details.Amount = dto.Amount
    entry.Details.Currency = dto.Currency
    entry.Details.Reason = dto.Reason
    entry.Details.PaymentMethod = dto.PaymentMethod

    logJSON, err := json.Marshal(entry)
    if err != nil {
        log.Printf("Error marshaling JSON: %v", err)
        return
    }

    log.Println(string(logJSON))
}

func main() {
    dto := PaymentFailureDTO{
        TransactionID: "trans_12345",
        UserID:        "user_67890",
        Reason:        "Insufficient funds",
        Amount:        5000,
        Currency:      "RUB",
        PaymentMethod: "credit_card",
        EventID:       "evt_002",
    }

    logPaymentFailure(dto)
} 
Пример анализа логов на аудите:

GO

package main

import (
    "bufio"
    "encoding/json"
    "fmt"
    "log"
    "os"
    "sync"
)

// LogEntry представляет общую структуру записи лога.
type LogEntry struct {
    EventID   string                 `json:"event_id"`
    Timestamp string                 `json:"timestamp"`
    EventType string                 `json:"event_type"`
    UserID    string                 `json:"user_id"`
    Result    string                 `json:"result"`
    Details   map[string]interface{} `json:"details"`
}

// ErrorHandler — это интерфейс для обработки ошибок.
type ErrorHandler interface {
    HandleError(entry LogEntry)
}

// LogErrorHandler записывает ошибку в лог.
type LogErrorHandler struct{}

func (h *LogErrorHandler) HandleError(entry LogEntry) {
    log.Printf("Обнаружена ошибка: %s, Пользователь: %s, Время: %s\n",
        entry.EventType, entry.UserID, entry.Timestamp)
}

// NotifyUserHandler отправляет уведомление пользователю.
type NotifyUserHandler struct{}

func (h *NotifyUserHandler) HandleError(entry LogEntry) {
    // Реализация отправки уведомления пользователю
}

// BlockUserHandler временно блокирует пользователя.
type BlockUserHandler struct{}

func (h *BlockUserHandler) HandleError(entry LogEntry) {
    // Реализация блокировки пользователя
}

// CreateIncidentHandler создаёт инцидент для службы ИБ.
type CreateIncidentHandler struct{}

func (h *CreateIncidentHandler) HandleError(entry LogEntry) {
    // Реализация создания инцидента для службы ИБ
}

func analyzeLogs(handlers []ErrorHandler) error {
    scanner := bufio.NewScanner(os.Stdin)

    for scanner.Scan() {
        var entry LogEntry
        line := scanner.Text()

        err := json.Unmarshal([]byte(line), &entry)
        if err != nil {
            return fmt.Errorf("ошибка декодирования: %w", err)
        }

        if entry.Result != "success" {
            var wg sync.WaitGroup
            for _, handler := range handlers {
                wg.Add(1)
                go func(h ErrorHandler, e LogEntry) {
                    defer wg.Done()
                    h.HandleError(e)
                }(handler, entry)
            }
            wg.Wait()
        }
    }

    if err := scanner.Err(); err != nil {
        return fmt.Errorf("ошибка чтения данных: %w", err)
    }

    return nil
}

func main() {
    handlers := []ErrorHandler{
        &LogErrorHandler{},
        &NotifyUserHandler{},
        &BlockUserHandler{},
        &CreateIncidentHandler{},
    }

    if err := analyzeLogs(handlers); err != nil {
        log.Fatalf("Произошла ошибка: %v", err)
    }
} 
Мы можем использовать json-схему для проверки создаваемых лог-сообщений на этапе разработки автотестов. В целом схема играет роль соглашения или контракта между разными командами. Но в промышленной эксплуатации лог-сообщения обычно не валидируют по схемам в целях оптимизации быстродействия и экономии ресурсов.
Пример показывает, как структурировать записи логов для двух различных микросервисов и проводить анализ логов в рамках аудита.

Ключевые элементы структуры данных для аудита

Рекомендации

Часто в структуру данных попадают ценные сведения из-за неопытности и невнимательности разработчиков. Чтобы избежать распространённых ошибок и улучшить безопасность системы, учитывайте следующие рекомендации:
  1. Минимизация чувствительных данных в логах Никогда не храните в логах пароли, платёжные данные и другие конфиденциальные сведения в открытом виде! Используйте хеширование и маскирование для защиты чувствительных данных. В крайнем случае используйте очистку логов от чувствительных данных перед сохранением. Эта мера защищает данные от несанкционированного доступа и минимизирует риски в случае утечки логов.
  2. Сохранение логов Определите политику хранения логов в зависимости от нормативных требований и внутренних политик безопасности. Например, храните логи об аутентификации в течение 1 года, а логи транзакций — 5 лет. Такой подход помогает соответствовать юридическим и регуляторным стандартам, обеспечивает возможность анализа данных за необходимый период.
  3. Интеграция с системой управления инцидентами Свяжите систему аудита с процессом управления инцидентами, чтобы при выявлении угрозы автоматически инициировались меры реагирования. Это позволяет оперативно реагировать на инциденты и минимизировать потенциальный ущерб для системы и пользователей.
Эти рекомендации помогут создать более безопасную и эффективную систему протоколирования и аудита, которая не только защитит данные, но и облегчит их анализ в случае возникновения инцидентов.

Типичные ошибки логирования

Логирование — ключевой компонент системы безопасности, однако ошибки в его реализации могут стать серьёзной угрозой для информационной безопасности и стабильности архитектуры ПО.
Рассмотрим распространённые ошибки и реальные примеры последствий для информационной безопасности.

1. Избыточное логирование

Одна из самых распространённых ошибок — логирование избыточной информации. Разработчики часто стремятся записать максимальное количество данных о каждом событии, включая даже внутренние процессы и малозначимые детали. Это приводит к излишней нагрузке на хранилища логов и делает систему уязвимой к атакам, нацеленным на переполнение диска или перегрузку службы логирования (так называемые DoS-атаки на логирование).
Пример В 2019 году облачный провайдер DigitalOcean столкнулся с проблемой, вызванной избыточным логированием. Из-за неправильной конфигурации логов вся диагностическая информация о запросах к API записывалась в журнал событий. Это привело к резкому росту объёма логов и перегрузке системы хранения данных, в результате чего возникли сбои в работе сервиса и замедление производительности. Компания была вынуждена временно отключить ряд функций и провести переработку системы логирования.
Решение:
  • Заранее определите набор ключевых событий и атрибутов, которые должны быть залогированы. Используйте минимальный уровень детализации для рутинных событий и повышайте его для критических инцидентов.
  • Используйте политики ротации и архивирования логов для поддержания их оптимального объёма.
  • Помните: «Effective logging is about capturing the right data, not all data».

2. Логирование конфиденциальной информации

Грубой ошибкой является запись конфиденциальных данных (например, паролей, токенов доступа, платёжной информации) в логи. Такие данные могут быть случайно утрачены или украдены, что приведёт к серьёзным нарушениям безопасности и нарушениям законодательства о защите данных (ФЗ-152).
Пример В 2017 году Uber сообщила об утечке данных 57 миллионов пользователей и водителей, произошедшей в результате доступа злоумышленников к приватным репозиториям, содержащим логи. Эти логи включали ключи доступа к хранилищу данных в облаке (AWS S3), которые были использованы для получения несанкционированного доступа к конфиденциальной информации. Инцидент привёл к крупному репутационному ущербу и штрафу в размере 148 миллионов долларов.
Решение:
  • Никогда не логируйте конфиденциальные данные вроде паролей или персональных данных! Если логирование таких данных необходимо для отладки, используйте маскирование или хеширование.
  • Реализуйте строгие политики доступа к логам и применяйте шифрование для защиты конфиденциальной информации.

3. Недостаточное логирование критически важных событий

Обратная сторона избыточного логирования — недостаточное логирование критически важных событий. Иногда разработчики ограничиваются минимальным набором логов, игнорируя ключевые операции — изменение прав доступа, создание новых учётных записей или удаление конфиденциальных данных. В результате, когда происходит инцидент, расследование затрудняется из-за отсутствия необходимой информации.
Пример В 2014 году JPMorgan Chase подверглась крупной кибератаке, в ходе которой были скомпрометированы данные 76 миллионов домашних хозяйств и 7 миллионов малых предприятий. Атака была обнаружена слишком поздно из-за недостаточного логирования ключевых событий. Логи не содержали информацию об изменении привилегий учётных записей и операциях, связанных с доступом к конфиденциальным данным, что затруднило расследование и принятие мер.
Решение:
  • Определите заранее набор критически важных событий, которые необходимо протоколировать. Это могут быть попытки входа, создание и изменение учётных записей, доступ к конфиденциальным ресурсам, изменение политик безопасности и так далее.
  • Настройте уведомления в реальном времени для выявления аномальной активности, связанной с этими событиями.

4. Использование неструктурированных логов

Неструктурированные логи (например, текстовые файлы, содержащие только сообщения об ошибках без контекста) затрудняют анализ и корреляцию событий. Это также делает практически невозможным использование современных инструментов для автоматического анализа и обработки логов. Как следствие, компания может упустить важные инциденты и не выявить аномалии в работе системы.
Пример В 2021 году облачный провайдер Azure (Microsoft) столкнулся с проблемой в одной из своих облачных служб. Из-за использования неструктурированных логов, записанных в виде свободного текста, и недостаточной детализации событий службе безопасности потребовалось значительно больше времени для анализа и устранения неполадок. Это привело к длительной недоступности ряда облачных сервисов для клиентов.
Решение:
  • Используйте структурированные логи, поддерживающие включение метаданных и контекста. Это позволит применять инструменты автоматизации анализа — ELK Stack, Splunk или Datadog.
  • Определите стандарты протоколирования и внедрите единый формат логов для всей системы.

5. Отсутствие ротации и архивирования логов

Если не реализовать политику ротации и архивирования логов, они могут быстро заполнить дисковое пространство и вызвать отказ в обслуживании (DoS) из-за перегруженности хранилища. Это особенно критично для систем с высокой частотой событий и большим количеством пользователей.
Пример В 2018 году GitLab столкнулась с серьёзным инцидентом. Из-за неправильной политики ротации и резервного копирования логов один из серверов логов заполнил дисковое пространство, что привело к недоступности ряда функций и данных. Компания вынуждена была провести восстановительные работы и пересмотреть политику логирования для предотвращения подобных инцидентов в будущем.
Решение:
  • Настройте ротацию логов по времени (например, ежедневно) или по объёму (например, при достижении определённого размера файла).
  • Архивируйте и сжимайте устаревшие логи для долгосрочного хранения, используя внешние хранилища (допустим, Amazon S3, Google Cloud Storage).

6. Пренебрежение безопасностью хранения и передачи логов

Логи часто хранятся и передаются без шифрования, что делает их уязвимыми для несанкционированного доступа и перехвата. Злоумышленник, получив доступ к логам, может обнаружить конфиденциальную информацию или узнать о внутренней структуре системы.
Пример В 2019 году компания ElasticSearch допустила утечку данных в связи с отсутствием шифрования при передаче логов. Доступ к открытой базе данных логов, которая содержала подробные сведения о запросах к серверу, включая данные об авторизации, позволил злоумышленникам использовать эту информацию для последующих атак. Этот инцидент привёл к массовой утечке данных и репутационному ущербу компании.
Решение:
  • Всегда используйте шифрование (SSL/TLS) для передачи логов на внешние системы и хранилища.
  • Реализуйте шифрование логов на стороне сервера перед сохранением их на диск, чтобы предотвратить доступ к конфиденциальным данным.
Кейс
Компания, предоставляющая облачные услуги, столкнулась с проблемой утечки конфиденциальной информации. В ходе внутреннего аудита выяснилось, что часть логов содержала открытые данные пользователей (номера кредитных карт и токены доступа), что создало уязвимость для утечек данных. Более того, логирование всех операций, включая внутренние системные процессы, создавало чрезмерную нагрузку на хранилища и привело к снижению производительности системы.
Компания решила оптимизировать свою подсистему аудита, чтобы уменьшить избыточное логирование, улучшить безопасность хранения данных и сосредоточиться на логировании ключевых событий.
Техническая команда предложила внести следующие изменения:
  1. Логировать только критически важные события, такие как аутентификация и изменения конфигураций.
  2. Шифровать все логи и удалять конфиденциальные данные из них.
  3. Внедрить политику ротации логов для предотвращения переполнения хранилищ.

Задание 1

Какое из предложенных решений компании наиболее важно для успешного функционирования подсистемы аудита? Выберите один правильный ответ.
Логирование всех событий, включая внутренние системные процессы, приводит к избыточному объёму данных и перегружает систему. Оптимизация заключается в логировании только ключевых событий.
Хотя детализация логов важна, она должна быть применена к ключевым событиям, а не ко всем действиям в системе. Избыточная детализация затрудняет анализ данных и увеличивает нагрузку на хранилища.
Это решение помогает как минимизировать избыточное логирование, так и защитить чувствительную информацию. Шифрование логов и удаление конфиденциальных данных повышают безопасность системы.
Использование единой категории логов для всех процессов затрудняет анализ и не позволяет эффективно сегментировать события, что снижает качество мониторинга безопасности.

Задание 2

Какие события следует приоритизировать при логировании для улучшения безопасности компании XYZ? Выберите все правильные ответы.
Логирование всех попыток доступа к системе, как успешных, так и неудачных, помогает отслеживать подозрительные активности и предотвращать взломы.
Логирование изменений конфигураций безопасности необходимо для контроля за действиями, которые могут повлиять на целостность системы и её защищённость.
Логирование попыток несанкционированного доступа позволяет вовремя реагировать на инциденты и выявлять возможные угрозы.

Задание 3

Какое действие технической команды наиболее эффективно для предотвращения переполнения хранилищ логов? Выберите один правильный ответ.
Увеличение объёма хранилища не решает проблему переполнения логов. Важно внедрять механизмы ротации и архивирования данных для управления их объёмом.
Логирование всех событий без механизма ротации приведёт к быстрому переполнению хранилищ и создаст проблемы с производительностью системы.
Политика ротации и архивирования логов помогает поддерживать оптимальный объём данных, предотвращает переполнение хранилищ и позволяет системе эффективно функционировать.
Логирование только успешных операций оставляет без внимания возможные попытки несанкционированного доступа или другие инциденты, которые могут представлять угрозу безопасности системы.

Дополнительные материалы

  • А кто это сделал? Автоматизируем аудит информационной безопасности
  • От логов к аудиту
  • Синхронизация в распределённых системах

Итоги

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