Estou trabalhando em um projeto que implementa simulações distribuídas: código arbitrário é executado em vários nós e os resultados são posteriormente coletados e agregados.
Cada nó é uma instância de uma máquina virtual Ubuntu Linux e executa um processo mestre que cuida do encaminhamento do código a ser executado para vários processos de trabalho (1 para cada núcleo).
Esta pergunta é sobre como garantir que cada trabalhador opere em um ambiente em área restrita sem recorrer ao uso de uma instância de máquina virtual para cada um deles. Os requisitos exatos para os trabalhadores são:
- fs : sem permissão de gravação, permissão somente leitura limitada a um único diretório (e subpastas)
- net : somente comunicações locais permitidas (IPC, TCP, qualquer que seja ...)
- mem : limite de uso de memória (sem memória swap) mata se estiver acima do limite de mem
- CPU : apenas 1 núcleo permitido, matar se ao longo do tempo
Nenhuma outra limitação deve ser imposta: o trabalhador deve poder carregar bibliotecas dinâmicas (da pasta somente leitura), gerar novos threads ou processos, chamar a função do sistema, ecc ecc, mas os limites devem ser herdados pelas entidades geradas / carregadas e deve aplicar-se de maneira sumária (por exemplo, não podemos ter um trabalhador gerando dois threads que usam 800 MB cada, o limite de memória para esse trabalhador é de 1 GB).
Escusado será dizer que não deve haver maneira para o trabalhador aumentar seus direitos.
Passei um tempo considerável revisando as alternativas disponíveis (SELinux, AppArmor, cgroups, ulimit, namespaces do Linux, LXC, Docker, ...) para a solução mais simples que satisfaz meus requisitos, mas minha experiência em campo é limitada.
Entendimento atual: o LXC e o Docker estão um pouco pesados para o meu caso de uso e não são completamente seguros 1 . O AppArmor é preferível ao SELinux devido à configuração mais fácil, use-o para restrições de rede e rede; cgroups preferível ao ulimit (que opera em um único processo), usou-o para restrições de mem e cpu.
Essa é a maneira mais simples de alcançar meu objetivo? Posso usar o AppArmor ou cgroups exclusivamente? Existe alguma falha de segurança óbvia no meu modelo? A diretriz deve ser "permitida ao trabalhador derrubar a si mesma, mas nada mais" .