Sandboxing en Linux

10 minutos de lectura

avatar de usuario
oggy

Quiero crear una aplicación web que permita al usuario cargar código C y ver los resultados de su ejecución (el código se compilaría en el servidor). Los usuarios no son de confianza, lo que obviamente tiene importantes implicaciones de seguridad.

Así que necesito crear algún tipo de sandbox para las aplicaciones. En el nivel más básico, me gustaría restringir el acceso al sistema de archivos a algunos directorios específicos. No puedo usar chroot jails directamente, ya que la aplicación web no se ejecuta como un usuario privilegiado. Supongo que un ejecutable suid que configura la cárcel sería una opción.

Los programas cargados serían bastante pequeños, por lo que deberían ejecutarse rápidamente (un par de segundos como máximo). Por lo tanto, puedo eliminar el proceso después de un tiempo de espera preestablecido, pero ¿cómo me aseguro de que no genere nuevos procesos? O si no puedo, ¿matar todo el pgid es un método confiable?

¿Cuál sería la mejor manera de hacerlo, además de “no hacerlo en absoluto”? 🙂 ¿Qué otros problemas de seguridad evidentes me he perdido?

FWIW, la aplicación web se escribirá en Python.

  • Bienvenido al mundo del software antivirus. ¿Se puede confiar en “el usuario”? Si es así, simplemente compila y ejecuta y no te preocupes por eso. Si no se puede confiar en el usuario, ¿qué impide que esto se convierta en el centro de los piratas informáticos cuando todos intentan que su servidor forme parte de una red de bots?

    – S. Lott

    19 de junio de 2009 a las 20:05

  • Preguntas similares sobre procesos de sandboxing/jailing en Linux o Unix: * unix.stackexchange.com/q/6433/4319 * stackoverflow.com/q/3859710/94687 * stackoverflow.com/q/4410447/94687 * stackoverflow.com/q/4249063/94687

    – imz — Iván Zakharyaschev

    13 de marzo de 2011 a las 13:38

  • posible duplicado de la forma segura de ejecutar el código de otras personas (sandbox) en mi servidor?

    – Ciro Santilli Путлер Капут 六四事

    21 de agosto de 2014 a las 7:02

avatar de usuario
Sweeney

Junto con las otras sugerencias, puede encontrar esto útil.

http://www.eelis.net/geordi/

Esto es de http://codepad.org/about, codepad.org‘s acerca de la página.

  • Gracias. Mientras buscaba en Google, me topé con el mismo sitio en una publicación anterior de stackoverflow: stackoverflow.com/questions/818402/… Me encantaría estafarlo, pero no parece que el teclado sea de código abierto. Así que intento adoptar un enfoque similar. Systrace/ptrace supervisor + chroot jail + . También muchas gracias a todos los demás por sus sugerencias, muy útiles. Otra lectura interesante: crypto.stanford.edu/cs155/lectures/06-sandboxing.ppt

    – oggy

    19 de junio de 2009 a las 22:44

  • @oggy Pero geordi ES de código abierto — eelis.net/geordi/#download , github.com/Eelis/geordi , github.com/Eelis/geordi/blob/master/LICENCIA : “Todos los autores involucrados en la creación de los contenidos de este paquete han acordado publicar sus respectivas contribuciones en el Dominio Público”.

    – imz — Iván Zakharyaschev

    17 de abril de 2013 a las 1:32

Los pocos detalles que proporciona implican que tiene control administrativo sobre el servidor en sí, por lo que mi sugerencia hace esta suposición.

Abordaría esto como un sistema por lotes. El servidor web acepta una carga del archivo fuente, un proceso sondea el directorio de envío, procesa el archivo y luego envía el resultado a otro directorio que la aplicación web sondea hasta que encuentra el resultado y lo muestra.

La parte divertida es cómo manejar con seguridad la ejecución.

Mi sistema operativo de elección es FreeBSD, por lo que configuré una cárcel preconfigurada (que no debe confundirse con una cárcel chroot vainilla) que compilaría, ejecutaría y guardaría la salida. Luego, para cada envío de archivo fuente, inicie una copia prístina de la cárcel para cada ejecución, con una copia del archivo fuente dentro.

Siempre que el /dev de la cárcel se reduzca a casi nada, los límites de recursos del sistema se establezcan de forma segura y que el tráfico no pueda enrutarse fuera de la cárcel (vinculado a una dirección no enrutable o simplemente protegido por un cortafuegos), personalmente me sentiría cómodo ejecutando esto en un servidor bajo mi cuidado.

Ya que usa Linux, investigaría User Mode Linux o Linux-VServer, que son muy similares en concepto a las cárceles de FreeBSD (nunca las he usado, pero he leído sobre ellas). Hay varios otros sistemas similares enumerados aquí.

Este método es mucho más seguro que una cárcel chroot vainilla y es mucho más liviano que usar una virtualización completa como qemu/kvm o VMware.

No soy programador, así que no sé qué tipo de cosa AJAX-y podría usar para sondear los resultados, pero estoy seguro de que podría hacerse. Como administrador, me parecería divertido participar en este proyecto. Diviértete. 🙂

  • El peligro para las cárceles o VServer es que un error del kernel (como la vulnerabilidad de empalme de hace un tiempo) todavía hace que el host sea vulnerable. Del mismo modo, todos los métodos de virtualización (incluido UML) también han tenido errores de seguridad que rompen la cárcel…

    – efímero

    19 de junio de 2009 a las 22:35

  • Muy cierto. Sin embargo, las hazañas son una parte inevitable del juego. El software siempre se puede romper (eventualmente). Todo este concepto (permitir que un código no confiable se ejecute en el servidor de uno) no es para los débiles de corazón. El OP declaró que no aceptaría “no lo hagas en absoluto” como respuesta, así que describí una de varias opciones.

    – Geoff Fritz

    19 de junio de 2009 a las 23:58

avatar de usuario
armador

Yo diría que esto es extremadamente peligroso en muchos niveles. Básicamente, se está abriendo a cualquier vulnerabilidad que se pueda encontrar en su sistema (mientras que normalmente está limitado a las que las personas pueden explotar de forma remota). Yo diría que no lo hagas si puedes evitarlo.

Si desea hacerlo, es posible que desee utilizar algún tipo de máquina virtual para ejecutar el código del usuario. Usando algo como KVM es posible configurar una cantidad de máquinas virtuales usando la misma imagen base (incluso puede almacenar una instantánea en un estado ya iniciado, aunque no estoy seguro de cómo manejará la clonación). Luego puede crear las máquinas virtuales a pedido, ejecutar el código del usuario, devolver los resultados y luego eliminar la máquina virtual. Si mantiene las máquinas virtuales aisladas entre sí y de la red, los usuarios pueden causar los estragos que quieran y no dañarán su servidor físico. El único peligro al que se está exponiendo en estas condiciones sería algún tipo de explotación que les permita escapar de la VM… son extremadamente raros y serán más raros a medida que mejore la virtualización del hardware.

En Fedora 11ahí está el Caja de arena de SELinux que parece hacer exactamente lo que desea (excepto quizás limitar la generación de nuevos procesos; la publicación del blog vinculada no menciona eso).

Por supuesto, siempre existe el riesgo de errores en el kernel; incluso con SELinux, partes del kernel aún están expuestas a todos los procesos.

Ver esta página sobre los métodos de sandboxing de Google Chrome para Linux. Como puede ver, hay muchos métodos, pero ninguno de ellos es excelente para una aplicación distribuible como Chrome porque es posible que algunas distribuciones no los incluyan. Sin embargo, esto no es realmente un problema para una aplicación web, porque puede controlar lo que está instalado en su servidor.

Personalmente, mi favorito es Seccompporque tiene un muy gastos generales bajos en comparación con otras herramientas como ptrace (cambie los espacios de direcciones en cada syscall!) o KVM (máquina virtual con gran cantidad de memoria), y es increíblemente simple en comparación con herramientas como SELinux (y, por lo tanto, es más probable que sea seguro).

  • Puede vincular el código C enviado por el usuario a una biblioteca y cargarlo antes de seccomp, pero eso no es seguro… no puede exec después seccomp, porque eso mata tu proceso… ¿quizás podrías escribir tu propio enlazador que cargue una imagen desde FD 0 y salte a ella? Lamentablemente, no es tan fácil.

    – efímero

    19 de junio de 2009 a las 22:32

  • @ephemient: Biblioteca de enlaces con código C. Comienza el proceso de control. Horquillas de proceso de control y execprograma La biblioteca se ejecuta primero, abre la cola de mensajes con el proceso de control, inicia Seccomp.

    – Zifre

    19 de junio de 2009 a las 22:46

  • Si la biblioteca contiene un símbolo _init o una función marcada con __attribute__((constructor)), se cargará inmediatamente. No hay forma de “pausar” la carga de la biblioteca, encender seccomp y luego permitir que continúe la carga de la biblioteca.

    – efímero

    20 de junio de 2009 a las 0:51

  • Hmm… Tendré que revisar mi antiguo proyecto (Usé Seccomp para algo similar hace un tiempo, y definitivamente no recuerdo haberlo configurado tan complejo…)

    – Zifre

    20 de junio de 2009 a las 0:54

  • s/inmediatamente cuando/ejecutar inmediatamente cuando/ Es posible que no se haya dado cuenta de que era posible que las bibliotecas ejecutaran código simplemente cargándolas, sin que se las llamara de nuevo ni nada por el estilo.

    – efímero

    20 de junio de 2009 a las 4:06

avatar de usuario
Aghoree

supongo caja de arena libre sirve a tu propósito. Su biblioteca principal está escrita para C/C++, pero también tiene un contenedor para programas de Python. Brinda opciones para personalizar qué llamadas al sistema se pueden permitir, cuánta memoria se puede usar, cuánto tiempo se puede ejecutar el programa invitado, etc. Ya se está usando en un par de jueces en línea como HOJ.

  • Puede vincular el código C enviado por el usuario a una biblioteca y cargarlo antes de seccomp, pero eso no es seguro… no puede exec después seccomp, porque eso mata tu proceso… ¿quizás podrías escribir tu propio enlazador que cargue una imagen desde FD 0 y salte a ella? Lamentablemente, no es tan fácil.

    – efímero

    19 de junio de 2009 a las 22:32

  • @ephemient: Biblioteca de enlaces con código C. Comienza el proceso de control. Horquillas de proceso de control y execprograma La biblioteca se ejecuta primero, abre la cola de mensajes con el proceso de control, inicia Seccomp.

    – Zifre

    19 de junio de 2009 a las 22:46

  • Si la biblioteca contiene un símbolo _init o una función marcada con __attribute__((constructor)), se cargará inmediatamente. No hay forma de “pausar” la carga de la biblioteca, encender seccomp y luego permitir que continúe la carga de la biblioteca.

    – efímero

    20 de junio de 2009 a las 0:51

  • Hmm… Tendré que revisar mi antiguo proyecto (Usé Seccomp para algo similar hace un tiempo, y definitivamente no recuerdo haberlo configurado tan complejo…)

    – Zifre

    20 de junio de 2009 a las 0:54

  • s/inmediatamente cuando/ejecutar inmediatamente cuando/ Es posible que no se haya dado cuenta de que era posible que las bibliotecas ejecutaran código simplemente cargándolas, sin que se las llamara de nuevo ni nada por el estilo.

    – efímero

    20 de junio de 2009 a las 4:06

avatar de usuario
mike hordecki

Hay una herramienta llamada rastro – monitorea las llamadas al sistema realizadas por un proceso dado. Solo debe estar atento a llamadas específicas que sugieran acceso a funciones ‘ilegales’. AFAIK, es el método utilizado en los concursos de programación para aislar los programas de los concursantes.

  • Existen muchos entornos limitados basados ​​en ptrace, como UMView. strace permite que el programa se ejecute normalmente, solo con un registro adicional; eso no es suficiente para el sandboxing.

    – efímero

    19 de junio de 2009 a las 19:44

  • @ephemient: debe escribir una respuesta adecuada: UMview de alguna forma parece adaptarse perfectamente a las necesidades de los interrogadores.

    – Chris K.

    22 de junio de 2009 a las 14:27

  • Documentos de UMView: wiki.virtualsquare.org/wiki/index.php/…

    – imz — Iván Zakharyaschev

    17 de abril de 2013 a las 2:42

  • UMView y otros enfoques basados ​​en ptrace: unix.stackexchange.com/a/72697/4319

    – imz — Iván Zakharyaschev

    17 de abril de 2013 a las 3:35

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad