SYNAPSE
EN
Гайды

Как ограничить автономного ИИ-агента: гайд по Hard Stop

Практическое руководство по настройке системы Hard Stop для контроля автономных ИИ-агентов. Узнайте, как предотвратить выход агента за пределы песочницы и защитить систему от нежелательных действий.

Как ограничить автономного ИИ-агента: гайд по Hard Stop

Что понадобится

  • Linux-машина (тестировалось на Ubuntu 22.04).
  • Python 3.9+.
  • Установленный Docker (для изоляции агента).
  • Права sudo.
  • Базовое понимание работы cgroups и namespaces.

Шаг 1. Создайте изолированное окружение для агента

Агент должен работать в контейнере без доступа к сети. Используйте Docker с отключённой сетью.

docker run -it --rm --network none --name agent-sandbox ubuntu:22.04 bash

Внутри контейнера установите только необходимые пакеты. Например, Python и curl (для локальных тестов).

apt update && apt install -y python3 curl

Проверьте, что сеть недоступна:

curl -s http://example.com || echo "Сеть недоступна"

Шаг 2. Настройте cgroups для ограничения ресурсов

Создайте cgroup v2 и задайте лимиты по CPU и памяти. Это предотвратит исчерпание ресурсов агентом.

sudo mkdir /sys/fs/cgroup/agent
sudo sh -c 'echo "max 50000" > /sys/fs/cgroup/agent/cpu.max'
sudo sh -c 'echo 512M > /sys/fs/cgroup/agent/memory.max'

Переместите процесс агента в эту cgroup. Сначала узнайте PID процесса внутри контейнера, затем выполните на хосте:

AGENT_PID=$(docker inspect -f '{{.State.Pid}}' agent-sandbox)
sudo sh -c "echo $AGENT_PID > /sys/fs/cgroup/agent/cgroup.procs"

Шаг 3. Установите Hard Stop — перехватчик системных вызовов

Hard Stop (система принудительной остановки) работает на уровне ядра и блокирует опасные операции. Используйте eBPF-программу, которая отслеживает вызовы execve, open, connect и при нарушении политики убивает процесс.

Шаг 3. Установите Hard Stop — перехватчик системных вызовов

Создайте файл hard_stop.c:

#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>

SEC("tracepoint/syscalls/sys_enter_execve")
int handle_execve(void *ctx) {
    char comm[16];
    bpf_get_current_comm(&comm, sizeof(comm));
    if (comm[0] == 'a' && comm[1] == 'g') { // имя процесса агента
        bpf_printk("Blocked execve for agent\n");
        return 0; // блокировать
    }
    return 0;
}

Скомпилируйте и загрузите:

clang -O2 -target bpf -c hard_stop.c -o hard_stop.o
sudo bpftool prog load hard_stop.o /sys/fs/bpf/hard_stop

Примечание: код упрощён для демонстрации. В реальной работе используйте библиотеку libbpf и проверяйте возвращаемое значение.

Шаг 4. Настройте политику остановки

Определите, какие действия агента считать опасными. Например, запрет на подключение к внешним IP, запись в /etc, запуск интерпретаторов. Опишите правила в формате JSON:

{
  "blocked_syscalls": ["execve", "connect", "open"],
  "allowed_paths": ["/tmp", "/home/agent"],
  "blocked_ips": ["0.0.0.0/0"]
}

Загрузите политику в eBPF-программу через map. Пример на Python с использованием bcc:

from bcc import BPF

bpf_text = """
#include <uapi/linux/ptrace.h>
BPF_HASH(policy, u32, u8);
int kprobe__sys_execve(struct pt_regs *ctx) {
    u32 pid = bpf_get_current_pid_tgid();
    u8 *blocked = policy.lookup(&pid);
    if (blocked) {
        bpf_trace_printk("Blocked execve for PID %d\\n", pid);
        return -1; // блокировать
    }
    return 0;
}
"""
b = BPF(text=bpf_text)
# Заполнить policy для PID агента
agent_pid = 1234  # замените на реальный PID
b["policy"][b.ctypes.c_uint(agent_pid)] = b.ctypes.c_ubyte(1)
Шаг 4. Настройте политику остановки

Шаг 5. Проверьте работу Hard Stop

Запустите агента и попробуйте выполнить запрещённое действие. Например, из контейнера попытайтесь запустить curl к внешнему сайту.

docker exec agent-sandbox curl -s http://example.com

Ожидаемый результат: команда завершается с ошибкой, в логах ядра появляется запись о блокировке.

dmesg | tail -5

Вы должны увидеть сообщение Blocked execve for agent.

Шаг 6. Настройте автоматическую остановку при аномалиях

Добавьте мониторинг системных вызовов. Если агент пытается выполнить подозрительную последовательность (например, открыть файл, затем запустить процесс), Hard Stop должен убить процесс.

Используйте bpftrace для простого скрипта:

sudo bpftrace -e 'tracepoint:syscalls:sys_enter_openat /comm == "agent"/ { printf("Agent opened file: %s\n", str(args->filename)); }'

При необходимости добавьте условие и вызовите kill(pid, SIGKILL) через eBPF.

Типичные ошибки и как их узнать

  • Агент обходит блокировку через дочерние процессы. Hard Stop должен наследовать политику для новых PID. Проверьте, что в eBPF-программе вы отслеживаете fork и копируете правила.
  • Сеть всё равно доступна. Убедитесь, что контейнер запущен с --network none и нет других сетевых интерфейсов. Проверьте ip addr внутри контейнера.
  • Hard Stop не загружается. Ошибка BPF program load failed часто связана с отсутствием прав или несовместимой версией ядра. Проверьте uname -r и наличие CONFIG_BPF_SYSCALL=y.
  • Агент использует легитимные вызовы для выхода. Например, open на /proc/self/mem. Ограничьте доступ к /proc через монтирование --mount type=tmpfs.
  • Логи не показывают блокировку. Убедитесь, что bpf_printk включён и dmesg не переполнен. Используйте trace_pipe для отладки.

Следуя этим шагам, вы создадите базовый барьер, который остановит агента до того, как он нанесёт ущерб. Помните: ни одна система не даёт абсолютной гарантии, но Hard Stop снижает риск неконтролируемого поведения.

↗ Первоисточник: Habr