Пишем свой immutable‑логгер на Python: как защитить данные на edge‑устройствах без облаков и SIEM
Я занимаюсь разработкой архитектуры для автономных робототехнических систем, которые должны работать в экстремальных условиях: без интернета, без облаков и без возможности оперативного вмешательства человека.
Одна из ключевых проблем таких систем — обеспечение целостности логов. Если устройство попало в аварию или было скомпрометировано, традиционный текстовый файл system.log не является доказательством: его можно незаметно отредактировать, удалить строки или изменить порядок событий.
Корпоративные SIEM‑системы (вроде ELK) слишком тяжелы для edge‑устройств с ограниченной памятью и вычислительной мощностью. Облачные решения неприменимы из‑за отсутствия связи.
В этой статье я расскажу, как я реализовал легковесный, не требующий внешних зависимостей модуль на чистом Python, который создает криптографически неизменяемую цепочку записей (по аналогии с блокчейном), и покажу, как он обнаруживает любые попытки подделки.
Как это работает (математика процесса)
Идея проста, но эффективна. Каждая новая запись в журнале вычисляет свой хеш не только на основе своего содержимого, но и на основе хеша предыдущей записи.
Формат записи выглядит так:
[2023-10-27 14:32:01] [CRITICAL] [SAFETY] Emergency shutdown triggered | PREV: a1b2c3d4... | SIG: e5f6g7h8...Алгоритм генерации подписи (SIG) для текущей записи:
hash_input = f"[{timestamp}] [{level}] [{module}] {message}{prev_hash}"
current_hash = hashlib.sha256(hash_input.encode('utf-8')).hexdigest()[:16]Это создает жесткую цепочку:
Запись 1:
SIG: hash1(гдеPREV= «GENESIS»)Запись 2:
SIG: hash2(гдеPREV=hash1)Запись 3:
SIG: hash3(гдеPREV=hash2)
Если злоумышленник (или сбойный сектор диска) изменит текст во 2-й записи, её хеш изменится. Это мгновенно приведет к несовпадению PREV в 3-й записи, и вся цепочка после точки вмешательства будет признана невалидной при проверке.
Реализация на Python
Я назвал этот модуль KERN Witness. Он написан на чистом Python (без pip install сторонних библиотек), что делает его идеальным для микрокомпьютеров вроде Raspberry Pi или ESP32 (через MicroPython).
Вот ключевой метод добавления записи:
def log(self, level: str, module: str, message: str) -> str:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
raw_string = f"[{timestamp}] [{level}] [{module}] {message}"
# Хеш текущей записи включает хеш предыдущей
hash_input = f"{raw_string}{self.last_hash}"
current_hash = hashlib.sha256(hash_input.encode('utf-8')).hexdigest()[:16]
final_entry = f"{raw_string} | PREV: {self.last_hash} | SIG: {current_hash}\n"
with open(self.filepath, "a", encoding="utf-8") as f:
f.write(final_entry)
self.last_hash = current_hash
return current_hashИнженерный нюанс: При парсинге файла для проверки я использую line.rsplit(" | ", 2). Это критически важно, так как само сообщение (message) может содержать символы |. Метод rsplit гарантирует, что мы разделим строку ровно два раза справа, корректно извлекая PREV и SIG, не ломая текст сообщения.»
Доказательство работы (Тесты)
Модуль включает в себя тесты, которые наглядно демонстрируют его устойчивость.
Тест на удаление записи:
Если мы программно удалим вторую строку из файла с тремя записями, метод verify() моментально обнаружит разрыв цепочки:
# Удаляем вторую строку из файла
del lines[1]
is_valid, issues = witness.verify()
# is_valid будет False
# issues будет содержать: "Строка 2: разрыв цепочки! Ожидался PREV: hash1, найдено: hash3"Честно об ограничениях
Как инженер, я должен четко обозначить границы применимости этого инструмента. KERN Witness обеспечивает криптографическую целостность, но не решает всех проблем безопасности:
Это не шифрование. Записи хранятся в открытом виде. Для конфиденциальности необходимо использовать шифрование диска (например, LUKS).
Это не защита от добавления. Злоумышленник с правами root может дописать новые строки в конец файла. Цепочка останется целой, но появятся ложные события. Решение: строгие права доступа к файлу (
chmod 400или600) и запись на append‑only файловые системы, где это возможно.Это не защита от полного уничтожения. Если файл удалят целиком, цепочку не проверить. Решение: регулярная выгрузка хешей на внешний, доверенный узел.
Заключение и Open Source
Этот модуль стал частью моей большой открытой инициативы по созданию этичной, офлайн‑первой робототехники (KERN SYSTEMS), где прозрачность и доверие к данным являются базовыми принципами.
Я выложил проект на GitHub под лицензией AGPL-3.0 и буду рад любой конструктивной критике, code review или идеям по оптимизации от сообщества.
🔗 Репозиторий: https://github.com/0ntwee/kern‑witness
Спасибо, что дочитали! Готов ответить на вопросы в комментариях.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.