Как не дать ИИ-агенту уронить прод
Идея этой заметки родилась после комментариев в соцсетях к моему предыдущему гайду. В нём я описал, как поставил автономного ИИ-агента на pet-сервер и настроил управление через ТГ-бота. Базовый механизм ограничения прав на уровне ОС там был, но в комментариях вместо советов или критики прилетело много мемов и иронии. Пришлось разбираться самому.
Сразу оговорюсь: это не эталон безопасности и не production-ready гайд. Просто заметка о том, на что обратить внимание, если ты дал агенту доступ к серверу и не хочешь однажды утром обнаружить, что он «починил» что-то слишком радикально.
Тема свежая, лучших практик пока никто толком не нащупал — каждый собирает свой стек защиты под свой кейс. Если у тебя есть свои наработки или просто опыт из серии «как агент опрокинул мою БД в проде» - пиши в комментариях.
Уровень 0: базовый
- Отдельный пользователь без sudo group. Чтобы при компрометации агент не получил root.
- В sudoers - allowlist конкретных команд, не blacklist. Запрещать `rm -rf /` бесполезно: обходится через `find / -delete`.
- chattr +i на критичные конфиги. Агент не сможет туда записать, даже если получит права.
- Лимиты в docker compose - защита от fork bomb и утечек памяти
Другие полезные параметры для docker compose:
user: "1000:1000" - процессы внутри контейнера запускаются от непривилегированного юзера, а не root.
read_only: true -корневая ФС контейнера становится read-only.
cap_drop: [ALL] -сбрасывает все Linux capabilities.
security_opt: [no-new-privileges:true] - процесс никогда не сможет получить больше прав, чем имеет на старте.
tmpfs: [/tmp:size=100M] - /tmp в RAM, с лимитом 100 MB.
Уровень 1: настройки агента
Сначала почитать документацию по безопасности самого агента. У OpenClaw этому посвящён целый раздел. Начни с простой команды - она проведёт аудит и подскажет проблемы:
С флагом `--fix` можно сразу их исправить.
Сделать агент недоступным извне и потребовать аутентификацию по токену:
Остальное — в документации.
Уровень 2: изоляция по сценарию
Агент и сервис на одном хосте через systemd
Если агент работает напрямую через systemd, без контейнера - пригодятся первые три пункта Уровня 0 (отдельный юзер, sudoers-allowlist, chattr +i) плюс несколько директив в systemd-юните::
По итогу примерно та же изоляция, что и docker-compose опции, только нативно.
Агент в Docker → systemd-сервис на хосте
- Точечные volume-mount'ы. Не пробрасывай агенту весь хост - давай ровно то, что нужно. Логи nginx - окей, весь /var/log - уже перебор.
- Логи и journal - только `:ro`. Читать может, испортить - нет.
- Для активных действий (restart, reload) можно можно пробросить D-Bus сокет. Например:
В образе агента нужны клиентские утилиты systemd: apt-get install -y systemd dbus - только CLI, без daemon'а. UID юзера в контейнере должен совпадать с UID на хосте, иначе polkit не применит правило (!).
Как альтернатива — триггер-механизмы вроде systemd path activation или Falco. Но это уже тема для отдельного поста.
Агент в Docker → сервис в другом Docker-контейнере
- Никогда не пробрасывай сырой docker.sock. Это фактически даёт root на хосте через `docker run --privileged`
- Используй docker-socket-proxy с allowlist API-вызовов:
Сервис в Kubernetes
- Никаких volume-пробросов, всё через RBAC и API
- resourceNames в Role - точечный allowlist по имени. Агент видит только нужный deployment:
- Никогда не давать cluster-admin. Для диагностики хватит отдельной read-only ClusterRole с verbs: [get, list, watch].
- pods/exec - красная зона: это root в чужом контейнере. Лучше sidecar с HTTP-эндпоинтом /debug/restart.
- SecurityContext пода - то же, что cap_drop: ALL в Docker, только декларативно:
Уровень 3: сеть
- UFW egress-allowlist. Без сети агент почти безвреден
- Заблокировать IP metadata облака. Оттуда улетают IAM-ключи. Всегда. На любой VPS. (Link)
- Для Docker - фильтр по IP контейнера в /etc/ufw/before.rules. UFW не умеет фильтровать по `--uid-owner` нативно:
Альтернатива - ufw-docker. После установки появляются нормальные команды, и это проще, чем править before.rules руками:
- В K8s - NetworkPolicy (или Cilium toFQDNs для DNS-фильтрации). В flannel NetworkPolicy не работает, понадобится другая CNI.
Уровень 4: поведение и аудит
- В промпте - заставляем агента спрашивать перед опасным:
- Append-only лог. Нельзя стереть даже с правами:
- Снапшоты и бэкапы. Периодически, на случай отката,
- Rate limit в systemd - защита от bug-loop'ов и DoS через инъекцию. (Хорошая статья на тему).
Чек-лист
- ✅ Завести отдельного юзера для агента, без sudo
- ✅ Разрешить только нужные команды через sudoers. Блеклистить бесполезно - обойдут
- ✅ Залочить критичные конфиги через `chattr +i`
- ✅ Проверить настройки самого агента: наверняка из коробки уже есть что покрутить
- ✅ Агент на хосте без Docker — изоляция через systemd-директивы (`ProtectSystem`, `PrivateTmp`, `CapabilityBoundingSet`)
- ✅ Docker - минимум привилегий: не от root, read-only, без capabilities, с лимитами ресурсов
- ✅ Если агент рулит другими контейнерами - доступ к `docker.sock` через прокси, не напрямую
- ✅ В Kubernetes - точечная Role, никаких cluster-admin'ов
- ✅ Закрыть сеть наружу. Оставить только нужное (LLM-провайдер, Telegram API и прочее). Metadata облака - заблокировать
- ✅ В промпте - запрет на опасные команды без подтверждения
- ✅ Логи append-only, регулярные снапшоты, ресурсы - с лимитами в systemd
Заключение
Идея этой заметки - не закрыть тему, а наоборот, открыть. Безопасность AI-агентов сейчас выглядит как security в Web2 в 2005-м: понятно, что нужно, непонятно как. Будем пробовать, ломать, делиться.
Главное помнить: агент = стажёр с правами админа. Минимум доступов, максимум проверок.
Если статья зашла и у тебя есть свой опыт, которым хочешь поделиться — пиши в комментариях или заходи к нам в Art of Chain. Там разбираем blockchain-инфраструктуру, DevOps и AI-инструменты для инженеров. Без хайпа и трейдинга.