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» .
Réponses:
Oui, vous pouvez utiliser cgroups et SELinux / AppArmor exclusivement pour surveiller et contrôler le code arbitraire que vous exécuterez.
Avec cgroups, vous pouvez effectuer les opérations suivantes:
cpuset
sous - systèmememory
sous - système, en surveillant même les fourches. Voir https://github.com/gsauthof/cgmemtime pour un exemple.lo
avec lenet_prio
sous-système.Et avec SELinux / AppArmor, vous pouvez limiter l'accès en lecture / écriture du processus.
Remarque: Je ne suis pas familier avec AppArmor, mais il s'agit d'un système de contrôle d'accès obligatoire (MAC), ce qui signifie que la protection de l'écriture et de la lecture est son travail.
L'utilisation de ces systèmes est une question d'écriture des configurations appropriées. Bien sûr, tout cela est beaucoup plus facile à dire qu'à faire. Voici donc quelques liens de référence pour vous aider à démarrer:
Bonne chance!
la source
Je ne supprimerais SELinux pour AppArmor que si j'utilisais Ubuntu . (vraiment assez difficile)
LXC n'est pas sécurisé en soi Si vous avez besoin de sécurité, vous devez les utiliser via libvirt (basé sur SELinux MLS ).
Votre problème est infini alors n'essayez pas de trouver une solution standard et sans temps infini, rappelez-vous que même kernel.org a été pwoned et très récemment le FBI a déclaré que quelqu'un utilisait ses systèmes depuis des années sans être détecté jusqu'à présent.
J'irai avec LXC / libvirt pour une assez bonne sécurité ou j'essaierai les "nouveaux" conteneurs intel clear , qui utilisent une VM très légère pour votre conteneur avec une utilisation claire de DAX / KSM (je ne les ai pas testés mais ils ont l'air très prometteur en effet).
Si vous êtes préoccupé par l'exploitation du noyau, grsecurity est votre solution, mais vous devrez l'intégrer à votre solution de conteneur (maux de tête à coup sûr).
Ce n'est donc pas une tâche facile à coup sûr, LXC / libvirt sont vraiment bien, mais peut-être que des conteneurs clairs sont le chemin à parcourir.
Docker? Je n'ai pas / n'utiliserais pas docker pour plus que des tests locaux quand il n'y avait pas de boîte vagabonde disponible, ils ont besoin de beaucoup plus de travail et d'une meilleure communauté.
Bien sûr, les conteneurs systemd sont également agréables, mais je suppose que vous ne les aimez pas / ne les voulez pas car vous ne les avez même pas mentionnés et ils ne sont pas une solution indépendante du fournisseur.
Si vous voulez quelque chose de "plus facile" et plus amateur, vous pouvez consulter Firejail , je l'ai utilisé pour certaines "applications" de bureau et il fait le travail (il est assez facile de créer le modèle pour votre application personnalisée, utilisez "privé"). se monte au-dessus de vos répertoires et restreint le réseau à un usage local uniquement, les processus engendrés héritent du parent et continuent ...).
Vive et amusez-vous sans devenir fou. ;)
la source
seccomp-bpf est une autre option qui fonctionne bien pour OpenSSH, vsftpd et Chromium, il n'a que exit (), sigreturn (), read (), il utilise également write () bien qu'il permette le filtrage des appels système à l'aide de règles de filtrage de paquets Berkeley configurables. Il pourrait également être utilisé en conjonction avec des cgroups pour la mémoire, le processeur, etc.
https://wiki.mozilla.org/Security/Sandbox/Seccomp
la source
Vous voudrez peut-être examiner les systèmes informatiques de grille. En particulier, BOINC ( http://boinc.berkeley.edu ) vérifie presque toutes vos cases.
Je crois que cela fonctionne sur vos paramètres en tant que tels:
fs: peut lire / écrire dans son propre répertoire, nulle part ailleurs
net: peut être configuré pour autoriser uniquement l'accès réseau à votre serveur BOINC, mais n'est pas par défaut IIRC
mem: oui, limites de mémoire séparées pour les machines inactives et non inactives
cpu: oui, peut même dire "ne pas fonctionner si l'ordinateur n'est pas inactif"
la source