Je travaille sur un projet qui implémente des simulations distribuées: du code arbitraire est exécuté sur plusieurs nœuds et les résultats sont ensuite collectés et agrégés.
Chaque nœud est une instance d'une machine virtuelle Ubuntu Linux et exécute un processus maître qui s'occupe de transmettre le code à exécuter à un certain nombre de processus de travail (1 pour chaque cœur).
Cette question porte sur la façon de s'assurer que chaque travailleur fonctionne dans un environnement en bac à sable sans recourir à l'utilisation d'une instance de machine virtuelle pour chacun d'eux. Les exigences exactes pour les travailleurs sont:
- fs : aucune autorisation d'écriture, autorisation de lecture seule limitée à un seul répertoire (et sous-dossiers)
- net : seules les communications locales sont autorisées (IPC, TCP, peu importe ...)
- mem : plafonner l'utilisation de la mémoire (pas de mémoire d'échange) tuer si dépassé la limite de mem
- cpu : seulement 1 noyau autorisé, tuer si dépassé la limite de temps
Aucune autre limitation ne doit être imposée: le travailleur doit pouvoir charger des bibliothèques dynamiques (à partir du dossier en lecture seule), générer de nouveaux threads ou processus, appeler la fonction système, ecc ecc mais les limites doivent être héritées par les entités générées / chargées et devrait s'appliquer d'une manière somme (par exemple, nous ne pouvons pas avoir un travailleur engendrer deux threads qui utilisent 800 Mo chacun est la limite de mémoire pour un tel travailleur est de 1 Go).
Il va sans dire que le travailleur ne devrait pas pouvoir faire valoir ses droits.
J'ai passé beaucoup de temps à passer en revue les alternatives disponibles (SELinux, AppArmor, cgroups, ulimit, espaces de noms Linux, LXC, Docker, ...) pour la solution la plus simple qui réponde à mes exigences mais mon expérience sur le terrain est limitée.
Connaissance actuelle: LXC et Docker sont un peu lourds pour mon cas d'utilisation et ne sont pas complètement sécurisés 1 . AppArmor préférable à SELinux en raison d'une configuration plus facile, utilisez-le pour fs et les restrictions net; cgroups préférable à ulimit (qui fonctionne sur un seul processus), l'a utilisé pour les restrictions mem et cpu.
Est-ce le moyen le plus simple d'atteindre mon objectif? Puis-je utiliser exclusivement AppArmor ou cgroups? Y a-t-il une faille de sécurité évidente dans mon modèle? La ligne directrice devrait être «le travailleur doit pouvoir s'abattre, mais rien d'autre» .