El sandboxing seguro más simple posible (se necesitan recursos limitados)


15

Estoy trabajando en un proyecto que implementa simulaciones distribuidas: el código arbitrario se ejecuta en múltiples nodos y los resultados luego se recopilan y se agregan.

Cada nodo es una instancia de una máquina virtual Ubuntu Linux y ejecuta un proceso maestro que se encarga de reenviar el código para que se ejecute a varios procesos de trabajo (1 para cada núcleo).

Esta pregunta trata sobre cómo asegurarse de que cada trabajador opere en un entorno de espacio aislado sin recurrir al uso de una instancia de máquina virtual para cada uno de ellos. Los requisitos exactos para los trabajadores son:

  • fs : sin permiso de escritura, permiso de solo lectura limitado a un solo directorio (y subcarpetas)
  • net : solo se permiten comunicaciones locales (IPC, TCP, lo que sea ...)
  • mem : límite de uso de memoria (sin memoria de intercambio) matar si supera el límite de memoria
  • CPU : solo se permite 1 núcleo, matar si se supera el límite de tiempo

No se deben imponer otras limitaciones: el trabajador debe poder cargar bibliotecas dinámicas (desde la carpeta de solo lectura), generar nuevos subprocesos o procesos, llamar a la función del sistema, ecc ecc, pero los límites deben ser heredados por las entidades generadas / cargadas y debe aplicarse de manera sumaria (por ejemplo, no podemos hacer que un trabajador genere dos subprocesos que usan 800 MB cada uno, el límite de memoria para ese trabajador es de 1 GB).

No hace falta decir que no debería haber forma de que el trabajador eleve sus derechos.

Pasé un tiempo considerable revisando las alternativas disponibles (SELinux, AppArmor, cgroups, ulimit, espacios de nombres de Linux, LXC, Docker, ...) para encontrar la solución más simple que satisfaga mis requisitos, pero mi experiencia en el campo es limitada.

Conocimiento actual: LXC y Docker son un poco pesados ​​para mi caso de uso y no son completamente seguros 1 . AppArmor preferible a SELinux debido a una configuración más fácil, utilícelo para fs y restricciones de red; cgroups preferible a ulimit (que opera en un solo proceso), lo usó para restricciones mem y cpu.

¿Es esta la forma más sencilla de lograr mi objetivo? ¿Puedo usar AppArmor o cgroups exclusivamente? ¿Hay algún agujero de seguridad obvio en mi modelo? La directriz debería ser "trabajador autorizado para derribar a sí mismo, pero nada más" .


2
Si su objetivo es limitar los recursos [ing] , podría hacerlo mucho mejor que un invitado de Ubuntu (o realmente cualquier derivado de Debian) . En cualquier caso, es probable que desee Linux en modo de usuario y / o (con núcleos recientes) el espacio de nombres de usuario
mikeserv

2
LXC suena exactamente como lo que necesitas. ¿Por qué crees que es pesado e inseguro? (Claro, es tenido errores, pero también lo ha hecho todo lo que pueda utilizar.)
Gilles parada SO ser maligno '

La presentación vinculada (ciertamente de 2011) y la sección de Seguridad de la documentación de Ubuntu LXC que habla sobre 'filtraciones de espacios de nombres' no son muy tranquilizadoras. Parece que LXC, basado principalmente en espacios de nombres y grupos c, podría ser la mejor opción en este momento de todos modos. También encontré Linux-Sandboxing , lectura interesante
StephQ

Puede requerir un poco de actualización, pero ¿ha considerado ejecutar en cárceles BSD?
Ryder

Si bien LXC puede ser 'pesado' en el sentido de que es como un montón de máquinas virtuales, es realmente simple hacerlas. Algunas de estas soluciones, aunque 'más ligeras' pueden requerir mucha configuración. Con LXC, es posible que no necesite configurar cosas como la escritura, ya que una aplicación tendría todo el contenedor.
MikeP

Respuestas:


1

Sí, puede usar cgroups y SELinux / AppArmor exclusivamente para monitorear y controlar el código arbitrario que ejecutará.

Con cgroups, puede hacer lo siguiente:

  1. Limite el uso del núcleo de la CPU a 1 CPU con el cpusetsubsistema
  2. Establezca límites de uso de memoria con el memorysubsistema, rastreando incluso las horquillas. Consulte https://github.com/gsauthof/cgmemtime para ver un ejemplo.
  3. Evite el acceso a la red a todo lo que no esté activado locon el net_priosubsistema.

Y con SELinux / AppArmor, puede limitar el acceso de lectura / escritura del proceso.

Nota: no estoy familiarizado con AppArmor, pero es un sistema de control de acceso obligatorio (MAC), lo que significa que proteger la escritura y la lectura es su trabajo.

El uso de estos sistemas es cuestión de escribir las configuraciones adecuadas. Por supuesto, todo esto es mucho más fácil decirlo que hacerlo. Aquí hay algunos enlaces de referencia para comenzar:

¡Buena suerte!


1

Descartaría SELinux para AppArmor solo si estuviera usando Ubuntu . (realmente bastante difícil)

LXC no es seguro por sí mismo. Si necesita seguridad, debe usarlos a través de libvirt (basado en SELinux MLS ).

Su problema es infinito, así que no intente encontrar ninguna solución inmediata y sin tiempo infinito, recuerde que incluso kernel.org fue expulsado y recientemente el FBI declaró que alguien ha estado usando sus sistemas durante años sin ser detectado hasta ahora.

Iré con LXC / libvirt para una seguridad bastante buena o probaré los "nuevos" contenedores intel clear , que usan una VM muy ligera para su contenedor con un uso claro de DAX / KSM (no los he probado pero se ven muy prometedor de hecho).

Si le preocupa la explotación del kernel, la seguridad es su solución, pero tendría que integrarla con la solución de su contenedor (seguro, dolores de cabeza).

Por lo tanto, no es una tarea fácil, LXC / libvirt son realmente geniales, pero tal vez los contenedores transparentes sean el camino a seguir.

¿Estibador? No usé / no usaría docker para más que pruebas locales cuando no había una caja vagabunda disponible, necesitan mucho más trabajo y una comunidad mucho mejor.

Por supuesto, los contenedores systemd también son agradables, pero supongo que no les gustan o los quieren porque ni siquiera los mencionó y no son una solución independiente del proveedor.

Si desea algo "más fácil" y más aficionado, puede consultar Firejail , lo he estado usando para algunas "aplicaciones" de escritorio y hace el trabajo (es bastante fácil crear la plantilla para su aplicación personalizada, use "privado" se monta en la parte superior de sus directorios y restringe la red solo para uso local, los procesos generados heredan para el padre y continúan ...).

Saludos y diviértete sin volverte loco. ;)


0

seccomp-bpf es otra opción que funciona bien para OpenSSH, vsftpd y Chromium, solo tiene exit (), sigreturn (), read (), también usa write (), aunque permite el filtrado de llamadas al sistema utilizando reglas configurables de Berkeley Packet Filter. También podría usarse junto con cgroups para memoria, CPU, etc.

https://wiki.mozilla.org/Security/Sandbox/Seccomp


0

Es posible que desee examinar los sistemas de computación grid. En particular, BOINC ( http://boinc.berkeley.edu ) verifica casi todas sus casillas.

Creo que opera en sus parámetros como tal:

fs: puede leer / escribir en su propio directorio, en ningún otro lugar

net: se puede configurar para permitir solo el acceso de red a su servidor BOINC, pero no es el predeterminado IIRC de fábrica

mem: sí, límites de memoria separados para máquinas inactivas y no inactivas

cpu: sí, incluso puedo decir "no ejecutar si la computadora no está inactiva"

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.