Две машины и бумага между ними

от автора

Асимметричный асинхронный мост для ИИ-помощника на промышленном объекте

Дисклеймер. Это описание архитектурного паттерна, не анонс продукта. Все примеры реализации — иллюстрации того, как паттерн может быть собран; в реальных проектах его можно реализовать иначе. Регуляторные ссылки (IEC 61508, tool qualification) описывают доказательную базу — окончательное решение о соответствии всегда остаётся за независимым органом сертификации (TÜV/DNV/RISE и т.п.).

TL;DR

У инженера не одна машина, а две. Контур 1 — с интернетом, для работы со стандартами и LLM. Контур 2 — физически изолированный, для работы с реальным производственным кодом. Между ними асимметричный асинхронный мост:

  • Наружу — через программный фильтр и бумагу. Запрос печатается, инженер физически переносит лист, вводит текст в Контуре 1. Защита от утечки.

  • Внутрь — через Gate с GPG-подписью, SHA-256 и паспортом артефакта. Защита от внесения вредоносного кода.

  • Без real-time API между контурами. Никаких автосинхронизаций, каждый перенос — отдельный осознанный шаг человека.

Главное: air-gap — не «нет провода», а четыре проверяемых условия. Stuxnet нарушает условие 3, Norsk Hydro — условие 1, Triton/Trisis — условие 2. При выполнении всех четырёх архитектура формирует доказательную базу под IEC 61508 для инструментов разработки safety-критичного ПО, независимо от LLM в Контуре 1.

Новизна паттерна: не «ещё один air-gap», а явная асимметрия каналов (бумага наверх, подписанные хеши вниз) + формализация четырёх условий + привязка к реальным атакам.

Как читать

  • Инженер АСУ ТП / ИБ: разделы 1, 4–7 и чек-лист.

  • Архитектор / руководитель проекта: TL;DR, разделы 3–4, FAQ.

  • Просто понять идею: TL;DR, рисунок 1, раздел 6 («Один рабочий день»).

Мини-глоссарий

Термин

Что значит

Контур 1 / Контур 2

Машина с интернетом vs физически изолированная. В Контуре 1 — обобщения, в Контуре 2 — конкретика

Air-gap

Физическое отсутствие сети между контурами. Не «логическая сегментация»

IB-фильтр

Программный фильтр, проверяющий запрос наружу на запрещённые паттерны

Gate

Механизм допуска артефактов в Контур 2: подпись + хеш + паспорт + ревью

Content-addressable

Артефакт, идентифицируемый своим хешем (как коммит в Git); пересчёт при каждом использовании

1. Зачем два контура

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

Архитектура — не «концепция энтузиаста», а инженерный ответ на задокументированные атаки последних пятнадцати лет:

Инцидент

Год

Что показал

Какое решение это обосновывает

Stuxnet

2010

Air-gap пробивается через USB подрядчиков

Подписанные архивы + контроль хешей + ревью

Triton / Trisis

2017

Целью атаки была сама система безопасности (SIS)

Доп. валидация SIL-критичного кода, severity BLOCK для safety

Атаки на украинскую энергосистему

2015–16

APT-группы пишут вредоносный код под промышленные протоколы

Локальная LLM, локальная база, никаких облачных API

Norsk Hydro

2019

Шифровальщик прошёл «логическую сегментацию»

Полный air-gap, не VLAN-разделение «как бы»

Colonial Pipeline

2021

Превентивная остановка — нельзя было быстро доказать чистоту OT

Паспорт каждого артефакта, audit log

Каждая строка — это архитектурное требование, выведенное из конкретной атаки.

2. Два контура: обобщения и конкретика

Контур 1 — обычный корпоративный ноутбук с интернетом. Разрешена работа с LLM, но только с обобщениями: «PID-регулятор для центробежного насоса с ЧРП по SIL 2» — да. «PID-регулятор для насоса № 3 на установке № 47, давление 6.4 МПа» — нет.

Контур 2 — выделенный сервер в технологическом сегменте. Нет интернета, нет связи с офисом, нет «облачных» сервисов поставщиков оборудования. Здесь — конкретика, тут шаблоны от LLM превращаются в работающий код под реальный объект.

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

3. Мост — асимметричный

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

Рис. 1. Архитектура двух контуров и асимметричный мост.

Нет общей сети. Нет real-time API. Нет автосинхронизаций. Это главное свойство моста — без него ни асимметрия, ни четыре условия air-gap не работают.

Канал «вверх»

Канал «вниз»

Что передаётся

Запросы инженера наружу

Шаблоны, артефакты, обновления

Главный риск

Утечка проектных данных

Внесение вредоносного кода

Носитель

Бумага + IB-фильтр

USB + GPG + SHA-256 + Gate

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

4. Четыре условия настоящего air-gap

«Нет провода» — необходимое, но недостаточное условие. Norsk Hydro формально тоже имел «логическую сегментацию» — а зловред прошёл. Air-gap как архитектурное свойство — это четыре независимых условия:

Рис. 2. Четыре условия air-gap и привязка к инцидентам.

  1. Нет прямых вызовов — ни одного import contour2.*, ни одного HTTP-запроса между контурами. Проверка: тест в контейнере с --network=none.

  2. Нет общего изменяемого состояния — никаких общих папок с правом записи, БД, env-переменных. Read-only к константному артефакту — допустимо.

  3. Все артефакты «вниз» — через Gate с фиксацией хеша SHA-256 в audit log.

  4. Все запросы «вверх» — через IB-фильтр, удаляющий sensitive данные.

Главное следствие: Norsk Hydro нарушает условие 1, Stuxnet — условие 3, Triton/Trisis — условие 2. Каждая знаменитая атака — нарушение одного из четырёх условий, а не «провал air-gap вообще».

Формальная запись Π₁–Π₄ и связь с tool qualification — в Приложении А отдельной статьи серии (по запросу можно прислать).

5. Канал «вверх»: бумага и двойной барьер

Рис. 3. Канал «вверх» — двойной барьер защиты от утечки.

Главный риск — утечка. Принципа «не выноси конкретику» недостаточно: на практике он превращается в десяток неочевидных вопросов. Поэтому два независимых барьера:

Барьер 1 — IB-фильтр. Запрос проверяется на запрещённые паттерны: IP-адреса, имена тегов SCADA, номера установок, ФИО, договоры, ключи, конкретные численные параметры. Найдено — печать блокируется, инженер видит, что переформулировать.

Минимальная реализация:

import re# Паттерны, которые НЕ должны уходить во внешний контурFORBIDDEN = {    "ip":       r"\b(?:\d{1,3}\.){3}\d{1,3}\b",    "scada":    r"\b[A-Z]{2,}_[A-Z0-9_]{3,}\b",    "object":   r"(?:насос|установка|агрегат)\s*№?\s*\d+",    "pressure": r"\b\d+[.,]\d+\s*(?:МПа|бар)\b",    "name":     r"\b[А-ЯЁ][а-яё]+\s+[А-ЯЁ]\.\s*[А-ЯЁ]\.",    "creds":    r"(?:password|token|api_key)\s*[:=]\s*\S+",}def screen(text: str) -> list[tuple[str, str]]:    """Возвращает список найденных нарушений; пустой список — печать разрешена."""    return [(category, m.group())            for category, pattern in FORBIDDEN.items()            for m in re.finditer(pattern, text, re.IGNORECASE)]

Барьер 2 — материализация на бумаге. Прошедший фильтр запрос печатается, физически переносится в Контур 1 и там считывается визуально. Три причины именно бумаги:

  • Не несёт метаданных — нет ОС, шрифтов, путей, имени учётной записи (всё это есть в любом электронном файле).

  • Неэксплуатируема — на бумаге нельзя спрятать вредоносный код. Это исключает класс атак уровня Stuxnet.

  • Принуждает к чтению — инженер обязательно прочитает то, что вводит руками с листа.

«Не глядя скопировал и вставил» здесь невозможен по построению.

Почему бумага, а не data diode? — частый вопрос

Data diode

DLP-gateway

Бумага + IB-фильтр

Стоимость

от $15 000

от $20 000/год

~ноль

Метаданные

передаются

частично фильтруются

физически отсутствуют

Скрытые каналы

timing/length

DLP-обход

физически невозможны

Принудительное чтение

нет

нет

да, по построению

Когда что: для АЭС, ОПК, КИИ I категории — данные диоды (часто требование регулятора). Для большинства промышленных объектов — бумага закрывает 90% угроз и обходится в нулевую стоимость. Никто не мешает комбинировать: канал «вниз» через диод, «вверх» через бумагу.

6. Один рабочий день в этой архитектуре

Рис. 4. Хронология одного цикла «вопрос → ответ → артефакт в Контуре 2».

Инженеру нужно улучшить шаблон PID-регулятора. День проходит так:

  • Утром в Контуре 2: пишет запрос — «как настроить anti-windup для PID при ЧРП с ёмкостной нагрузкой?». IB-фильтр пропускает (конкретики нет). Запрос печатается.

  • Перенос: берёт лист, идёт к ноутбуку Контура 1, вводит текст с листа в LLM.

  • Работа с LLM: получает ответ, упаковывает обновление шаблона regulators_pid_v2.4.zip, пишет passport.yaml (стандарты, ревью), подписывает GPG-ключом, считает SHA-256.

  • После обеда: записывает архив на USB, идёт обратно к Контуру 2.

  • Gate: проверяет подпись, паспорт, хеш. Запись в audit log: <regulators_pid_v2.4.zip, sha256:9a7b…, 14:32 UTC>.

  • Запуск: валидатор Контура 2 принимает шаблон. Каждое последующее использование предваряется пересчётом хеша и сверкой с audit log.

Один цикл занял рабочий день. Если бы LLM выдал странный совет — инженер увидел при упаковке. Если бы кто-то подменил флешку — Gate не пропустил. Если бы файл подменили уже в Контуре 2 — пересчёт хеша при запуске поймал. Три независимых проверки между «инженер написал в LLM» и «код запустился на контроллере».

7. Канал «вниз»: Gate с фиксацией хеша

Рис. 5. Gate с фиксацией хеша при допуске и проверкой целостности при каждом использовании.

Главный риск — внесение. Пять механизмов:

  • Носитель — USB или однонаправленный диод.

  • GPG-подпись конкретного автора.

  • Content-addressable фиксация — хеш записывается в audit log один раз, проверяется при каждом использовании.

  • Паспорт артефакта (passport.yaml) — автор, дата, стандарты, ревью.

  • Ручное ревью перед запуском.

Пример паспорта:

artifact: regulators_pid_v2.4.ziphash_sha256: 9a7b3f1c8d2e4a5b6c0f3e2a1b8d7c6f5e4d3c2b1a0987...author: { name: А.К. Иванов, gpg_key_id: "0x4F2A9B1C" }signed_at: 2026-04-12T14:32:07Zstandards: [IEC 61508-2 §7.4.4.3, IEC 61131-3 ST, NAMUR NE43]review: { reviewer: М.С. Петров, date: 2026-04-11, decision: APPROVED }

Скелет Gate:

def admit(artifact, signature, passport, trusted_keys) -> GateResult:    if not verify_gpg(artifact, signature):              return reject("bad signature")    meta = yaml.safe_load(passport.read_text())    if meta["author"]["gpg_key_id"] not in trusted_keys: return reject("untrusted key")    if sha256_of(artifact) != meta["hash_sha256"]:       return reject("hash mismatch")    if meta["review"]["decision"] != "APPROVED":         return reject("no approved review")    audit_log.append((artifact.name, sha256_of(artifact), now()))    return GateResult.ACCEPTEDdef verify_before_use(artifact) -> bool:    """Каждое использование артефакта в Контуре 2 предваряется этой проверкой."""    return sha256_of(artifact) == audit_log.get(artifact.name)

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

У Gate нет автоматических триггеров. Никакой «фоновой синхронизации». Каждый перенос — осознанное действие инженера, фиксируемое в audit log.

8. Асинхронность как свойство, а не баг

Если посмотреть на сценарий из раздела про «один рабочий день», бросается в глаза одна вещь: цикл «запрос → ответ → артефакт в Контуре 2» занимает не миллисекунды и даже не минуты, а весь рабочий день. На первый взгляд это выглядит как чистый неудобный тормоз.

На практике именно эта «медлительность» и даёт те свойства, ради которых всё и затевалось:

  • Не получается сделать каскадную атаку. Между LLM-сервисом и контроллером нет провода, а между каждым шагом есть человек с руками. Даже если кто-то сломает облачную модель, результат всё равно упрётся в инженера, который тащит распечатку и собирает архив.

  • Появляется время на тормоз. Между «LLM что-то сгенерила» и «код ушёл в ПЛК» много отдельных шагов. На любом из них можно остановиться и сказать: «секундочку, а вот это я точно хочу видеть в контроллере?».

  • Работа идёт пакетами, а не хаотично. Инженер не сидит в режиме «спросил у ИИ каждую мелочь». Он готовит серию вопросов, раз за разом переносит ответы и потом спокойно разбирает их в Контуре 2.

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

9. Прецедент: Simplex и IEC 61508

Этот раздел можно пролистать, если вам не нужны формальные аргументы для аудиторов и регуляторов.

Рис. 6. Двухконтурная архитектура — Simplex-паттерн (Sha, 2001), перенесённый из runtime в момент разработки.

В runtime известна Simplex-архитектура: рядом с «умным, но непроверенным» контроллером (Advanced Controller) ставится «простой и формально верифицируемый» (Basic Controller), а Decision Module решает, чьё решение применить. Двухконтурная архитектура — тот же паттерн в development-time: Контур 1 = AC, Контур 2 = BC, Gate = DM.

Главное практическое следствие для IEC 61508-3 Annex D (tool qualification):

При выполнении четырёх условий air-gap + трёх дополнительных условий (детерминизм компонентов Контура 2; валидатор внутри; документированный путь вывода) валидатор формирует доказательную базу под требования T2-tool, независимо от LLM в Контуре 1.

Это не автоматическая сертификация и не замена оценке независимого органа — это набор архитектурных решений, упрощающий прохождение tool qualification.

10. Что архитектура НЕ решает

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

Во-первых, социальная инженерия внутри Контура 2. Если у вас есть инсайдер с легальным доступом, который сознательно подписывает вредоносный артефакт и сам же его ревьюит, никакой Gate не спасёт. Здесь защита не про архитектуру, а про организацию: разделение обязанностей (минимум два человека на критичные артефакты), ротация ролей, независимый аудит ревью.

Во-вторых, компрометация самой локальной LLM. Модель с закладкой будет честно выдавать вам «слегка неправильный» код, а вы будете его честно переносить. На этом уровне архитектура говорит только: «между LLM и контроллером стоит валидатор». Дальше всё упирается в качество этого валидатора, наличие SBOM на модель и в то, насколько у вас отлажены регрессионные тесты.

В-третьих, атаки на инструменты разработки в Контуре 2. Если скомпрометирован компилятор, среда разработки, GPG-клиент или сам валидатор, никакой air-gap не поможет. Это уже классическая тема tool qualification и цепочек поставки ПО: доверенные репозитории, контроль обновлений, проверки на уровне ОС.

Отдельно стоит история с железом и принтерами. Современный цветной принтер может вставлять в распечатку невидимые точки с серийником устройства (printer steganography), а сервер может приехать с уже «интересной» прошивкой BMC. Для особо параноидальных сценариев это отдельный слой: чёрно-белый лазерный принтер без «водяных знаков», проверенные поставщики железа, аудит цепочки поставок.

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

11. FAQ

В. Почему не OCR вместо ручного ввода с бумаги? О. Допустим, но только локальный, оффлайновый, внутри Контура 1. Никаких облачных OCR API. И главное: OCR ускоряет ввод, но не отменяет асинхронность — лист всё равно физически переносится и читается перед сканированием.

В. Почему не DLP-система вместо «бумажного барьера»? О. DLP — барьер на сетевом канале. Закрывает условие 4, но не помогает с условиями 1, 2, 3. Сам факт сетевого канала между контурами уже нарушает условие 1. DLP отлично дополняет паттерн на уровне офисных сетей и Контура 1, но не заменяет физический разрыв между контурами.

В. Сколько это стоит внедрить? О. Минимальный вариант: один сервер для Контура 2 (несколько сотен тысяч рублей), GPG-ключи (бесплатно), реализация фильтра и Gate (несколько человеко-недель). Сравните с data diode (от $15 000) и DLP (от $20 000/год). Это оценка порядка величины; в конкретных проектах цифры зависят от инфраструктуры и требований регулятора.

12. Чек-лист внедрения

MVP «День 1» — минимум, который можно собрать за смену из подручных средств:

  • ☐ Завести вторую машину без сети (можно ноутбук).

  • ☐ Поставить regex-фильтр на 5–6 паттернов (см. раздел 5).

  • ☐ Печатать запросы. Хеши вручную через sha256sum, журнал в простом текстовом файле.

  • ☐ Договориться с командой: артефакты только через USB и подписанный архив.

Это не закрывает все четыре условия air-gap, но даёт быстрый старт и вынуждает дисциплину переноса. Этого хватает, чтобы начать.

Полный паттерн — соответствует четырём условиям air-gap из раздела 4:

  • ☐ 1. Две физически разные машины, нет общих сетевых маршрутов.

  • ☐ 2. Контур 2 в контейнере с --network=none (проверка условия 1).

  • ☐ 3. Audit точек I/O (проверка условия 2).

  • ☐ 4. IB-фильтр на 8 категорий паттернов (условие 4).

  • ☐ 5. Gate на 5 проверок: подпись, паспорт, ключ, хеш, ревью (условие 3).

  • ☐ 6. GPG-ключи на инженеров, локальная база доверенных ключей.

  • ☐ 7. Формат passport.yaml. Роли: автор vs ревьюер — разные люди.

  • ☐ 8. verify_before_use перед каждым запуском артефакта.

  • ☐ 9. Audit log Gate в иммутабельном хранилище.

  • ☐ 10. Тренинг инженеров на сценарии «один день».

После — поддержка: пополнение базы фильтра новыми паттернами, расширение правил валидатора.

Финальная мысль

Если упростить всю статью до одного вопроса, он звучит так: не «насколько умная у нас модель», а «по какому маршруту её результат попадает на реальное оборудование».

Двухконтурная схема даёт на этот вопрос вполне буквальный ответ: есть две разные машины, между ними два разных канала, никакого общего провода и никакого real-time. Наверх — через IB-фильтр и бумагу. Вниз — через Gate с подписью, хешем и паспортом артефакта. Каждый перенос — отдельное действие конкретного инженера, которое можно показать в audit log.

Почти каждый громкий кейс из OT-безопасности последних лет можно разложить как нарушение одного из четырёх условий настоящего air-gap. В этом смысле архитектура здесь — не «красивая концепция», а список вполне приземлённых требований, которые либо выполняются, либо нет. Провода нет — хорошо. Общей папки нет — ещё лучше. Gate и IB-фильтр работают и логируются — отлично.

Если из всего текста оставить в голове одну картинку, то это не диаграмма, а инженер с распечаткой, который идёт к другому компьютеру. На фоне историй про Stuxnet, Triton/Trisis и Norsk Hydro такой лист уже не выглядит анахронизмом. Это вполне осознанное проектное решение: за счёт пары лишних шагов руками вы отрезаете целый класс атак и при этом не тратите миллионы на экзотические железки.

Вопросы к читателям

  • Как у вас организован перенос артефактов между офисным и технологическим сегментом? Используете ли что-то похожее на passport.yaml?

  • Сталкивались ли с обходом air-gap через USB, общие папки или «временные синхронизации»?

  • Применяете ли LLM в проектной работе на safety-критичных системах? Если да — как разделяете «обобщения» и «конкретику»?

  • Какие паттерны вы добавили бы в FORBIDDEN для IB-фильтра под специфику своих объектов? Это самая полезная вещь, которой можно поделиться — соберём в комментариях расширенный список.

Особенно интересно мнение safety-инженеров про привязку к T2-tool IEC 61508-3 Annex D — какие аргументы работают при разговорах с TÜV/DNV. Жду ваши истории в комментариях.

Серия статей. Это первая статья. Следующая — про реализацию IB-фильтра с расширенным набором паттернов, регламент подписи и тестирование Gate. Дальше — про валидатор внутри Контура 2 и как туда попадают новые правила.

ссылка на оригинал статьи https://habr.com/ru/articles/1042610/