tmp noexec en servidores virtuales

febrero 19, 2013  |  linux, Presencia Online, Software

Ha sido una de estas pequeñas cosas en la administración de sistemas que nos ha traído de cabeza durante algún tiempo, así que nos ha parecido interesante documentarla en nuestro blog.

En Linux, es una máxima que dado que “/tmp” es un directorio con permisos de escritura muy flexibles (=inseguros) debería montarse siempre con el flags “nosuid,noexec” para impedir cambios de usuario y ejecución de binarios en ese directorio, práctica habitual de muchos exploits de PHP y otros lenguajes. En realidad los expertos dicen que no es en absoluto suficiente con eso, pero al menos es una primera práctica de “buenas costumbres” de seguridad.

El problema surge cuando algunas partes del sistema si que quieren ejecutar desde esas particiones. El caso más obvio es el de aptitude en Debian que al instalar ejecuta por ejemplo, scripts de configuración. Buscando la solución más habitual es la de hacer un remount de tmp para que durante “un rato” permita execs añadiendo un archivo a “/etc/apt/apt.conf.d/” con algo como:

DPkg::Pre-Invoke
{
 "mount -o remount,exec /tmp";
 "mount -o remount,exec /var/tmp";
};
DPkg::Post-Invoke
{
 "mount -o remount /tmp";
 "mount -o remount /var/tmp";
};

Bien, en sistemas virtualizados de contenedores Linux como los que usamos nosotros y en OpenVZ sobre Debian en particular, el sistema de particiones se complica un poco al realizarse desde la maquina host como scripts que se ejecutan durante el arranque de la maquina.  Hasta hace poco hacíamos lo que se conoce como un “bind” mount (algo así como un mount virtual de otra ruta) al /tmp de la maquina limitando esos permisos (noexec,nosuid) o en otros casos montando el /tmp en memoria creando una entrada tmpfs en el script de la maquina XXX.mount

El problema, en ambos casos, es que eso impide hacer remount una vez dentro de la maquina virtual, pues recibiremos un “Permission denied” al intentarlo dado que en realidad es el host quien monto la partición y esta “por encima” del ámbito del sistema virtual.

Para resolverlo hasta ahora hemos encontrado dos soluciones que estamos poniendo a prueba. La primera sirve si el /tmp lo estás montando a una partición en tmpfs (memoria) y consiste simplemente en crear la entrada dentro del /etc/fstab virtualizado (en los contenedores es normal que esté vacío pues su sistema de archivos se genera “fuera”), en este caso algo como :

tmpfs /tmp tmpfs noexec,nosuid 0 0

De este modo la solución anterior de remontarlo funciona correctamente y puede servir.

La segunda solución, que en realidad ya hemos implantado siempre pero que es necesaria cuando queremos seguir montando desde el host y/o a una unidad no desmontable es cambiar la ruta desde la que el apt crea esos temporales (ver //wrightsolutions.wordpress.com/2010/01/11/securing-tmp-and-noexec-apt-considerations/).

APT
{
 ExtractTemplates
 {
 TempDir "/ruta/a/otro/tmp";
 };
};

Esa nueva ruta, como no tiene que existir y residir en alguna partición con permisos de ejecución. Esta es la solución que hemos implantando en nuestro caso en todas las maquinas.