Quiero ejecutar un comando en Linux de una manera que no pueda crear ni abrir ningún archivo para escribir. Todavía debería poder leer archivos de manera normal (por lo que un chroot vacío no es una opción), y aún así poder escribir en archivos ya abiertos (especialmente stdout).
Puntos de bonificación si todavía es posible escribir archivos en ciertos directorios (es decir, el directorio actual).
Estoy buscando una solución que sea de proceso local, es decir, que no implique configurar cosas como AppArmor o SELinux para todo el sistema, ni privilegios de root. Sin embargo, puede implicar la instalación de sus módulos de kernel.
Estaba mirando las capacidades y estas habrían sido agradables y fáciles, si hubiera una capacidad para crear archivos. ulimit es otro enfoque que sería conveniente, si cubriera este caso de uso.
strace
te dice qué archivos está abriendo el programa. ¿Por qué quieres hacer esto? ¿Es un programa específico, o quieres esto para probar u otra cosa? ¿Puede ejecutar el programa como un usuario / grupo que no tiene permiso para escribir en casi todas partes, excepto en el directorio actual? Las distribuciones modernas de Linux utilizan la idea de un grupo para cada usuario, por lo que debería ser relativamente fácil de configurar.Respuestas:
¿Qué tal crear un chroot vacío, luego montar en bind el sistema de archivos principal como de solo lectura dentro del chroot?
Probablemente debería ser algo como esto para crear un montaje de enlace de solo lectura:
Puede enlazar y montar otros directorios a los que desea que la cárcel también tenga acceso de escritura. Tenga cuidado si necesita enlazar-montar directorios especiales (/ dev /, / proc /, / sys /), montarlos tal cual puede ser inseguro.
fuente
/foo/
la ruta al sistema de archivos principal?Parece que la herramienta adecuada para este trabajo se
fseccomp
basa en elsync-ignoring
código f de Bastian Blank. Se me ocurrió este archivo relativamente pequeño que hace que todos sus hijos no puedan abrir un archivo para escribir:Aquí puede ver que todavía es posible leer archivos:
No impide eliminar archivos, moverlos u otras operaciones de archivos además de abrir, pero eso podría agregarse.
Una herramienta que permite esto sin tener que escribir código C es syscall_limiter .
fuente
¿Consideraría escribir un sustituto para la
open(…)
función y cargarlo usando LD_PRELOAD?fuente
open
... Bueno, consideraría usar una solución existente que use este enfoque, sí.write(…)
.La solución más simple es probablemente un programa contenedor que crea un nuevo espacio de nombres del sistema de archivos con los sistemas de archivos relevantes montados de solo lectura y luego ejecuta el programa que está tratando de restringir.
Esto es lo que
systemd
hace cuando usaReadOnlyDirectories=
para marcar ciertos directorios como de solo lectura para un servicio. También hay ununshare
comandoutil-linux
que puede hacer el trabajo de crear un nuevo espacio de nombres, por lo que puede hacer algo como:donde
wrapper
entonces solo tendría que volver a montar los sistemas de archivos según sea necesario antes de iniciar el programa de destino real.El único problema es que debes ser
root
para crear el nuevo espacio de nombres ...fuente
Podrías ejecutarlo en un chroot, montando versiones especiales de
/tmp
y dentro. Quizás systemd sea de ayuda, y particularmente systemd-nspawn (1) , que se parece a lo que quieres.fuente
Una máquina virtual permitiría que el script escriba en cualquier lugar sin afectar el sistema host, e inspeccionar en dónde realmente está tratando de escribir, lo que parece ser el objetivo.
Por ejemplo, puede iniciar fácilmente Arch Linux con
fuente
Hacer una configuración inicial como root es realmente la forma más fácil. Específicamente, un chroot en un montaje de enlace de solo lectura es el camino de menor resistencia.
Puede usar bindfs en lugar de
mount --bind
crear la vista de solo lectura sin necesidad de ser root. Sin embargo, debe hacer algo como root para evitar el acceso a otros archivos, como chroot.Otro enfoque es
LD_PRELOAD
una biblioteca que se engancha en la apertura de archivos y se niega a permitir la escritura. Esto no requiere privilegios especiales. Desde una perspectiva de seguridad, esto se puede omitir, pero está bien para su caso de uso donde solo necesita contener una característica específica y no un código nativo arbitrario. Sin embargo, no conozco una biblioteca existente para esto.LD_PRELOAD
también podría usarse para limitar el programa a la vista de solo lectura creada conmount --bind
obindfs
; De nuevo, no sé de una biblioteca existente.En Debian y derivados, puede configurar un entorno schroot . Schroot es una raíz setuid y necesita ser configurada como root, pero puede ser ejecutada por cualquier usuario autorizado.
Un método que no requiere ninguna cooperación desde la raíz es ejecutar el proceso en una máquina virtual. Puede configurar KVM o VirtualBox, o Linux en modo de usuario . Es un poco pesado y significará un consumo de memoria adicional, pero no debería afectar significativamente la velocidad del cálculo simbólico en bruto.
¿Cómo "encarcelar" un proceso sin ser root? podría proporcionar algo de inspiración.
fuente
Una forma de evitar al menos que el proceso escriba los archivos (pero no los cree) es llamar
ulimit -f 0
primero. Esto anulará el proceso tan pronto como intente escribir en un archivo, pero aún es posible crear archivos vacíos.fuente