---
title: "A ilusão do isolamento elegante e a conta operacional do sandboxing no Linux"
author: "Pedro Dalben"
date: "2026-09-21T11:02:00Z"
category: "Arquitetura & CTO"
reading_time: "6 min"
canonical: "https://pedrodalben.com.br/blog/a-ilusao-do-isolamento-elegante-e-a-conta-operacional-do-sandboxing-no-linux"
---

# A ilusão do isolamento elegante e a conta operacional do sandboxing no Linux

> Isolar processos não confiáveis exige escolher entre reescrever sistemas inteiros para capabilities ou assumir o risco de brechas no kernel.

**Autor:** Pedro Dalben (CTO no Integrar Plus)  
**Publicado em:** 21 de September de 2026  
**URL Canônica Oficial:** [https://pedrodalben.com.br/blog/a-ilusao-do-isolamento-elegante-e-a-conta-operacional-do-sandboxing-no-linux](https://pedrodalben.com.br/blog/a-ilusao-do-isolamento-elegante-e-a-conta-operacional-do-sandboxing-no-linux)  

---


Toda discussão sobre isolar execução de código não confiável em produção costuma terminar em dois campos teóricos que ignoram a rotina de quem mantém servidores ligados.

De um lado, os defensores de modelos formais de capabilities apontam para projetos como Capsicum no FreeBSD ou a especificação WASI no WebAssembly. O argumento é impecável no papel: se um processo não herda autoridade ambiente e precisa receber explicitamente cada descritor de arquivo ou recurso de rede que vai tocar, a superfície de ataque diminui drasticamente sem depender de regras de filtragem reativas. Do outro lado, quem precisa entregar software comercial em prazos reais reclama que exigir a reestruturação completa de uma aplicação, trocando chamadas comuns do sistema por manipulações de descritores pré-abertos, é uma barreira intransponível de usabilidade que enterra qualquer chance de adoção prática. Essa segunda corrente prefere soluções declarativas ou filtros aplicados no momento da execução, como pledge e unveil no OpenBSD ou Landlock e seccomp no Linux.

Eu discordo do pessimismo em torno das abordagens baseadas em capabilities, mas a realidade prática da maioria das infraestruturas em produção torna essa discussão quase inútil para quem roda Linux em servidores próprios.

A ideia de que basta plugar algumas regras de Landlock ou seccomp para resolver o problema com vinte linhas de código esconde uma armadilha severa. Quem já tentou manter filtros de seccomp em produção sabe que qualquer atualização de biblioteca compartilhada, do interpretador Ruby ou do runtime de Node pode introduzir uma chamada de sistema legítima que o filtro bloqueia silenciosamente com SIGSYS, derrubando o processo em um caminho de erro que os testes locais nunca capturaram.

Existe um problema estrutural ainda mais grave no ecossistema Linux: o uso excessivo de namespaces desprivilegiados para isolamento rápido.

Ferramentas que dependem de flags como `unshare` para criar namespaces de usuário sem privilégios de root prometem isolamento barato para scripts de terceiros, mas entregam exatamente o oposto na camada de baixo. Ao expor subsistemas do kernel antes restritos a administradores para qualquer processo arbitrário, você amplia a superfície de ataque do próprio sistema operacional. Grande parte das vulnerabilidades críticas de elevação de privilégio descobertas no Linux nos últimos anos decorre de bugs em código de rede ou montagem de sistemas de arquivos que se tornaram acessíveis a usuários comuns por meio de user namespaces.

Quando alguém argumenta que soluções como Landlock trazem uma ergonomia superior porque você não precisa reescrever o programa, essa pessoa está trocando custo de desenvolvimento por incerteza de segurança a longo prazo.

Em infraestruturas enxutas, onde uma única VPS roda o banco de dados PostgreSQL, a aplicação web e tarefas em segundo plano, a contenção de código arbitrário precisa ser previsível. Se um usuário pode subir uma macro, um template ou um script de transformação de dados que roda no mesmo servidor, as alternativas reais se afunilam em trade-offs dolorosos:

| Abordagem | Custo de refatoração | Previsibilidade operacional | Exposição do kernel |
| :--- | :--- | :--- | :--- |
| Filtros de syscall (seccomp) | Médio | Baixa (quebra com atualizações) | Baixa |
| Restrições de caminho (Landlock) | Baixo | Média (depende da versão do kernel) | Baixa |
| Namespaces desprivilegiados | Baixo | Alta | Muito alta |
| Isolamento em WebAssembly (WASI) | Alto | Muito alta | Mínima |
| Processos isolados em microVMs | Nenhum | Muito alta | Mínima (mas consome memória) |

A barreira de entrada do modelo de capabilities é real. Tentar fazer uma biblioteca padrão em C ou módulos comuns em linguagens de script funcionarem sem autoridade global sobre o sistema de arquivos exige shims complexos de resolução de caminhos. Casos simples, como abrir um banco SQLite embutido em um subprocesso restrito, viram pesadelos de engenharia porque o driver espera permissões de criação de arquivos temporários e travas de memória que colidem com as restrições impostas.

É por essa razão que o WebAssembly está ganhando espaço nessa fronteira. Ao descartar completamente a autoridade ambiente desde a concepção do runtime, sem carregar o legado de chamadas POSIX da década de setenta, o WASI contorna a necessidade de interceptar o kernel. O processo simplesmente não enxerga a rede ou o disco, exceto se a aplicação hospedeira fornecer uma ponte explícita.

No entanto, nem todo código executável pode ser compilado para WASM de maneira trivial, principalmente quando dependemos de ecossistemas com extensões em C ou rotinas dinâmicas de linguagens interpretadas.

Para quem opera em servidores Linux sem camadas gigantescas de orquestração gerenciada, a conclusão desconfortável é que tentar isolar código não confiável dentro do mesmo espaço de memória do sistema operacional por meio de hacks no runtime é um risco desnecessário. Se o isolamento precisa acontecer em nível de processo:

## O caminho mais seguro ainda é a separação drástica de privilégios

Em vez de lutar contra as inconsistências do seccomp ou abrir namespaces que podem colocar em risco o hospedeiro inteiro, a tática que sobrevive aos anos sem quebras silenciosas combina regras simples e restritivas aplicadas de fora:

Primeiro, o processo executor roda sob um usuário do sistema totalmente desprovido de privilégios, sem permissão de escrita em nenhum diretório além de um `tmpfs` efêmero montado com `noexec` e `nosuid`.

Segundo, a comunicação com a aplicação principal acontece exclusivamente por pipes ou sockets locais previamente abertos pelo processo pai, nunca por portas de rede genéricas. Isso reproduz o princípio fundamental das capabilities sem exigir que você reescreva a biblioteca padrão da linguagem para usar chamadas específicas do FreeBSD.

Terceiro, limites rígidos de tempo de CPU, uso de memória e número de processos filhos precisam ser cravados via `cgroups` v2 antes da inicialização do script, impedindo ataques de negação de serviço que esgotem os recursos do PostgreSQL que divide a mesma máquina.

Se o código a ser executado requer uma flexibilidade que esse modelo enxuto não suporta, aplicar remendos rápidos via syscalls locais é uma falsa sensação de segurança. Nesses cenários, a única barreira que de fato protege a máquina principal é a fronteira de hardware simulada por microVMs dedicadas, que sobem e morrem junto com a requisição. O overhead de alguns milissegundos a mais e de uma fatia de memória reservada custa infinitamente menos do que lidar com um kernel comprometido por uma regra mal calibrada.

## Fontes

- [https://blog.emilua.org/2025/01/12/software-sandboxing-basics/](https://blog.emilua.org/2025/01/12/software-sandboxing-basics/)
