Exécutez le code utilisateur en toute sécurité

Je dois marquer le code C et une partie de celui-ci implique l'exécution et le calendrier de leurs soumissions. Le problème est que leur code fonctionne alors comme moi et qu'ils peuvent, en principe, faire ce qu'ils aiment en utilisant mes paramètres d'autorisation. Par exemple, ils pourraient copier ma clé privée ssh.

Je pourrais configurer une machine virtuelle et exécuter leur code (même si je ne suis pas tout à fait sûr de la meilleure façon de verrouiller cela). Un problème avec cela est que les performances de la vitesse ne seront plus réalistes. Je pourrais fournir la même machine virtuelle à tous les utilisateurs pour tester leur code au préalable, au moins ils ont la même configuration pour tester.

Existe-t-il un bon moyen de configurer un environnement où vous pouvez exécuter un code écrit par d'autres, mais limiter les dégâts qu'il peut faire?

En réalité, il existe de multiples types de machines virtuelles, ce qui est un peu égaré dans les autres réponses. Vous pouvez avoir ce qu'on appelle la virtualisation des conteneurs – quelque chose comme Linux vServer ou OpenVZ. Ils partagent le noyau de l'hôte, exécutant ce qu'on appelle des «conteneurs» (avec leurs propres environnements) plutôt que de virtualiser n'importe quel matériel et sont presque aussi rapides que le métal nu . (OpenVZ est plus fréquent dans les services VPS moins chers, mais ne supporte que le noyau personnalisé 2.6.x, tandis que vServer monte jusqu'à la dernière version stable).

En dehors de cela, les frais généraux de la virtualisation complète sur une machine moderne ne sont pas aussi mauvais que vous le pensez! Avec la virtualisation du matériel sur une CPU à mi-haut niveau, la plupart des utilisations ne se remarqueraient même pas de pénalité de performance, à moins qu'il n'y ait eu conflit pour les ressources (par exemple, l'hôte ou une autre machine virtuelle utilisait beaucoup). Ce sera un peu plus lent, car certaines ressources sont utilisées par le système d'exploitation invité, mais le coût de la virtualisation elle-même est presque négligeable – en particulier l'utilisation du processeur, puisqu'il peut être transmis au matériel brut avec (presque) aucune traduction, si c'est Accélération matérielle. Vous pourriez essayer, vous pourriez être surpris.


Notez que chacun possède également différents niveaux d'isolement. La virtualisation des conteneurs rend beaucoup plus facile d'exploiter le noyau et d'autres bugs pour «sortir» du conteneur – LXC n'est pas sûr du tout, bien que OpenVZ soit considéré comme très mature et sécurisé (et est couramment utilisé dans les services VPS, où vous vendez Conteneurs aux personnes non approuvées). VServer est quelque part entre les deux. La virtualisation complète a une meilleure isolation, mais certaines attaques existent encore pour éclater.

Cela dépend de la distance que vous attendez d'un élève malveillant. Il pourrait suffire de simplement fonctionner comme un utilisateur différent. Vous voudrez peut-être un conteneur pour plus de sécurité. Les chances sont qu'un conteneur est suffisant pour tout ce que vous rencontrerez dans ces circonstances.

Créez un compte utilisateur unique avec des privilèges limités (ce qui signifie l'accès à un ensemble restreint de routines de bibliothèque, éventuellement même à un accès de shell simplifié).

ssh comme utilisateur dans votre système, et exécutez leurs programmes.

Vous pouvez même écrire un petit script shell bash (ou tout autre script shell) pour y parvenir.

  1. Exécutez le code comme nobody , ce qui devrait vous donner des privilèges minimaux. Selon la façon dont la configuration est élevée, cela peut ne pas être sûr
  2. Courir dans une prison de chroot . Selon le code, cela peut changer le comportement, et les prisons peuvent souvent être éclatées. Ils ne sont pas une fonctionnalité de sécurité.
  3. Exécutez dans une machine virtuelle. Je pense qu'il n'y a que très peu d'exemples connus de pouvoir sortir de ceux-ci, mais je n'en suis pas sûr. Vous pouvez utiliser par exemple Vagrant pour configurer une virtualisation très simple. Exemple de configuration et de commandes .

Il y a quelques possibilités différentes, selon l'isolement que vous voulez.

Le plus simple est de simplement faire confiance au code. Il semble que cela ne soit pas possible pour vous, ou vous ne le demanderez pas.

La prochaine étape consiste à exécuter le code sur un compte d'utilisateur distinct, comme l' a suggéré Vigneshwaren . Si vous souhaitez restreindre l'accès au réseau spécifiquement pour un compte d'utilisateur particulier, cela peut être accompli grâce à l' appariement des propriétaires d'iptables . Une fois terminé, le compte d'utilisateur peut être laissé ou supprimé, et tous les processus en cours d'exécution en tant qu'utilisateur peuvent être complètement éliminés.

Une étape supplémentaire est d'ajouter une prison chroot au compte d'utilisateur distinct. Cela peut causer des problèmes avec les bibliothèques ou les fichiers de configuration qui doivent être en place, mais s'il s'agit, par exemple, d'un exercice purement croquant, cela peut être pratique. Il garantit que seuls les fichiers que vous souhaitez que le code des étudiants puissent accéder soient accessibles à ce code.

La dernière étape consisterait à exécuter le code dans un environnement complètement distinct. Pensez à la machine virtuelle, ici, bien qu'un ordinateur physique distinct puisse accomplir la même chose. Le code peut s'exécuter dans un environnement complètement isolé, y compris avec le câble réseau virtuel débranché, et tout dommage qu'il pourrait faire, y compris le remplissage du disque ou du bombardement à fourche, sera isolé dans la machine virtuelle et le pire qui pourrait se produire est Que vous devez l'éteindre. Étant donné que la machine virtuelle aura une installation complètement OS distincte, surtout si vous supprimez la connexion réseau avant d'exécuter le logiciel, cela ne peut pas échapper à vos données sensibles. Avec une VM, vous pouvez utiliser des instantanés de disque pour vous permettre de revenir rapidement et facilement à un état connu après avoir exécuté le programme de chaque élève.

Tout dépend de l'endroit où l'échelle d'effort par rapport à la confiance que vous placez vos élèves. Moins de confiance exige plus d'efforts de votre part pour vous assurer que rien ne se passe.

I have to mark C code

Ensuite, vous avez un accès complet au code source, regardez-le – il est douteux qu'ils pourront transmettre tout ce qui est malicieux dans le code sans que vous ne le remarquiez.

Si vous n'êtes pas sûr de l'exécuter par une machine virtuelle, mais dans la plupart des cas, vous saurez ce qui se passe

J'ai travaillé sur un système similaire il y a quelques années. Ce que j'ai fait était d'utiliser ptrace pour limiter les appels système (voir le code ici ), et éventuellement changer l'identifiant utilisateur ou le chroot. Si les programmes sont simples, impliquant uniquement des algorithmes purs et des tâches d'E / S de base, cela devrait être une solution pratique que vous pourriez envisager.

BTW, il convient de mentionner que vous devez également limiter l'utilisation du temps / mémoire du compilateur. Certains programmes malveillants peuvent inclure des directives comme #include </dev/random> ce qui pourrait provoquer un accrochage du compilateur pendant une longue période, ou des macros récursives permettant au compilateur de consommer beaucoup de mémoire.