В данный момент я учавствую в разработке одного проекта, где необходима возможность запуска пользовательского кода на стороне сервера (вообще говоря написанного на различных языках программирования). В связи с этим возник вопрос — как лучше всего реалиовать данный функционал, чтобы не иметь с ним проблем. В частности интересны следующие аспекты:
- Обеспечение безопасности сервера (не будем забывать, что недобросовестных пользователей это прямо открытая возможно собрать и запустить вирус/эксплоит прямо на сервере).
- Обеспечение достаточной производительности, а также введение некоторых ограничений на исполняемый код (например ограничения на используемую память для процесса и т.п.)
- О других возможных проблемах.
Вот такой вопрос.
PS: Было бы очень интересно услышать мнение и советы тех кто делал что-либо подбное/администрации данного ресурса (при условии что это не является комерческой тайной =) ).
Ответ на ваш вопрос существенно зависит от операционной системы. В Линуксе есть целая куча путей такое сделать (патчи к ядру вроде ejudge'овского, какая-то недавно появившаяся функциональность ядра вроде cgroups, виртуализация на уровне ядра kvm). В freebsd есть что-то подобное линуксовым фичам, например, jail. В windows уже гораздо сложнее - например, на этом сайте такое не очень реализовано (в частности, многие системные вызовы работают, и эксплоиты скорее всего прокатят). Так что если нужна безопасность - разумнее запускать в виртуальной машине.
Собственно ограничить-то нужно запись в файлы - для этого просто отдельный пользователь совсем ограниченный или chroot и запретить по сети стучаться - с помощью фаервола или того же AppArmor.
Потом, когда концепт дойдёт до какой-то актуальной стадии, можно будет о более сложных идеях подумать в зависимости от типа сервера на котором запускаетесь и т.п. %)
UPD: Виртуальная машина (или просто машина отделённая от сервера и забирающая с него файлы для проверки по особому каналу) вообще говоря удобнее, но для этого нужно чтоб сервер был довольно мощным (и уж точно не виртуальным), чтоб машину можно было клонировать (предпочтительно) и т.п. Так что это я б отложил на потом...
Если уж использовать что-то вроде AppArmor - лучше сразу SELinux, он более активно развивается и вроде возможностей у него побольше.
По поводу виртуальных машин - если критична производительность, можно попробовать использовать "псевдо"-виртуальные машины вроде lxm (которые реализованы при помощи того же cgroups), правда, там уровень безопасности конечно гораздо ниже, чем при использовании полноценных виртуальных машин.
UPD. А вообще, если с непривычки, то AppArmor по-моему всё-таки попроще настроить.
Вообще же тут автору вопрос - компилирует ли он запускаемые программулины на своей стороне, или запускет полученые бинарники. Если первое - то появляются некоторые дополнительные возможности...