
Ejecución segura de código
CodeJail gestiona la ejecución de código no confiable en sandboxes seguros. Está diseñado principalmente para la ejecución de Python, pero también puede usarse para otros lenguajes.
La seguridad se aplica con AppArmor. Si su sistema operativo no admite AppArmor, o si el perfil de AppArmor no está definido y configurado correctamente, CodeJail no protegerá la ejecución.
CodeJail está diseñado para ser configurable y se auto-configurará para la ejecución de Python si lo instala correctamente.
Un sandbox de CodeJail consta de varias partes:
#) Entorno del sandbox. Para una configuración de Python, esto sería Python y los paquetes centrales asociados como un virtualenv. Esto se denota a lo largo de este documento como . Es de solo lectura y se comparte entre las instanciaciones del sandbox.
El código en el sandbox también tiene acceso a las bibliotecas del sistema operativo en la medida en que el perfil de AppArmor lo permita.
#) Directorio de ejecución del sandbox. Es un directorio efímero de solo lectura llamado
como /tmp/codejail-XXXXXXXX que contiene el código enviado
(./jailed_code), archivos adicionales opcionales y un directorio temporal
de escritura (./tmp) que el código enviado puede usar como espacio de trabajo.
El código enviado es típicamente el código presentado por el estudiante para ser
probado en el servidor, y los archivos adicionales son típicamente un
python_lib.zip que contiene bibliotecas de calificación o utilidades.
Para ejecutarse, CodeJail requiere dos cuentas de usuario. Una cuenta es la cuenta
principal bajo la cual se ejecuta el código, que tiene acceso para crear
sandboxes. Esta se denominará <SANDBOX_CALLER>. La
segunda cuenta es la cuenta bajo la cual se ejecuta el sandbox. Esta es
típicamente la cuenta sandbox.
Actualmente se ha probado que esta biblioteca funciona con las siguientes versiones
Python:
Ubuntu:
(Tenga en cuenta que la versión de Python utilizada dentro del sandbox puede ser diferente de la versión utilizada para la propia biblioteca).
Estas instrucciones detallan cómo configurar su sistema operativo para que
CodeJail pueda ejecutar código Python de forma segura. Sin embargo, también es posible establecer
codejail.safe_exec.ALWAYS_BE_UNSAFE = True y ejecutar el Python enviado
directamente en la máquina, sin seguridad alguna. Esto puede ser adecuado para
las máquinas de los desarrolladores que no se preocupan por la seguridad y permite probar
una integración con la API de CodeJail. No debe utilizarse si cualquier entrada proviene
de fuentes no confiables. No use esta opción en sistemas de producción.
Para asegurar la ejecución de Python, creará un nuevo virtualenv. Esto significa que tendrá dos: el virtualenv principal para su proyecto y el nuevo para el código Python en el sandbox.
Elija un lugar para el nuevo virtualenv y llámelo . Será
detectado y utilizado automáticamente si lo coloca junto al
virtualenv existente, pero con -sandbox añadido. Así que si su virtualenv existente está en
/home/chris/ve/myproj, haga que sea /home/chris/ve/myproj-sandbox.
El usuario que ejecuta el LMS es <SANDBOX_CALLER>, por ejemplo, usted en
su máquina de desarrollo, o www-data en un servidor.
Otros detalles aquí que dependen de su configuración:
Cree el nuevo virtualenv, usando --copies para que haya un ejecutable de Python distinto que limitar::
$ sudo python3.12 -m venv --copies
De forma predeterminada, el virtualenv simplemente crearía un enlace simbólico al Python del sistema, y la configuración predeterminada de AppArmor en algunos sistemas operativos puede impedir que se aplique el confinamiento a ese enlace.
(Opcional) Si tiene paquetes particulares que desea que estén disponibles para su código en el sandbox, instálelos activando el virtualenv del sandbox y usando pip para instalarlos::
$ /bin/pip install -r requirements/sandbox.txt
Agregue un usuario sandbox::
$ sudo addgroup sandbox $ sudo adduser --disabled-login sandbox --ingroup sandbox
Permita que el servidor web ejecute el Python del sandbox como sandbox. Cree el archivo
/etc/sudoers.d/01-sandbox::
$ sudo visudo -f /etc/sudoers.d/01-sandbox
<SANDBOX_CALLER> ALL=(sandbox) SETENV:NOPASSWD:/bin/python <SANDBOX_CALLER> ALL=(sandbox) SETENV:NOPASSWD:/usr/bin/find <SANDBOX_CALLER> ALL=(ALL) NOPASSWD:/usr/bin/pkill
(Tenga en cuenta que el binario find puede ejecutar código arbitrario, por lo que este no es un archivo sudoers seguro para fines que no sean de codejail).
Edite un perfil de AppArmor. Este es un archivo de texto que especifica los límites del
ejecutable de Python en el sandbox. El archivo debe estar en /etc/apparmor.d y debe
nombrarse según el ejecutable, con las barras reemplazadas por puntos. Por
ejemplo, si su Python del sandbox está en /home/chris/ve/myproj-sandbox/bin/python,
entonces su perfil de AppArmor debe ser /etc/apparmor.d/home.chris.ve.myproj-sandbox.bin.python.
Consulte el perfil de ejemplo en apparmor-profiles/. El perfil debe ser
personalizado para que coincida con la ubicación de su sandbox.
Analice los perfiles::
$ sudo apparmor_parser --replace --warn=all --warn=no-debug-cache --Werror <APPARMOR_FILE>
Reactive el virtualenv principal de su proyecto nuevamente.
Desactive el uso de PAM para establecer rlimits::
sed -i '/pam_limits.so/d' /etc/pam.d/sudo
Si su CodeJail está configurado correctamente para usar safe_exec, pruebe estos comandos en su terminal de Python::
import codejail.jail_code
codejail.jail_code.configure('python', '<SANDENV>/bin/python', user='sandbox')
import codejail.safe_exec
jailed_globals = {}
codejail.safe_exec.safe_exec("output=open('/etc/passwd').read()", jailed_globals)
print(jailed_globals) # should be unreachable if codejail is working properly
Esto debería fallar con una excepción.
Si necesita cambiar los paquetes instalados en el virtualenv de su sandbox, deberá desactivar AppArmor, porque su Python del sandbox no tiene los derechos para modificar los archivos en su directorio site-packages.
Desactive AppArmor para su sandbox::
$ sudo apt-get install apparmor-utils # if you haven't already $ sudo aa-complain /etc/apparmor.d/home.chris.ve.myproj-sandbox.bin.python
Instale o modifique de otro modo los paquetes instalados::
$ pip install -r requirements/sandbox.txt
Vuelva a activar AppArmor para su sandbox::
$ sudo aa-enforce /etc/apparmor.d/home.chris.ve.myproj-sandbox.bin.python
Para ejecutar las pruebas, debe realizar los pasos de instalación estándar. Luego debe establecer las siguientes variables de entorno::
$ export CODEJAIL_TEST_USER=<owner of sandbox (usually 'sandbox')>
$ export CODEJAIL_TEST_VENV=<SANDENV>
Ejecute las pruebas con el Makefile::
$ make tests
Varias pruebas proxy se omiten si el modo proxy no está configurado.
CodeJail es lo suficientemente polivalente como para usarse en una variedad de proyectos para ejecutar código no confiable. Proporciona dos capas:
jail_code.py ofrece ejecución segura de subprocesos. Lo hace
ejecutando el programa en un subproceso gestionado por AppArmor.
safe_exec.py ofrece un manejo especializado de la ejecución de Python, usando
jail_code para proporcionar la semántica de la declaración exec de Python.