Las jaulas o jails son espacios virtuales dentro de un sistema en los que ejecutan aplicaciones que viven aisladas dentro de esas jaulas. En linux se llaman contenedores y también me parece un nombre adecuado.

Imaginemos que tenemos una jaula configurada en nuestro sistema en la que ejecutamos un servidor de bases de datos. Si un usuario, aunque este sea supervisor, accede a una de estas jaulas no podría ver las otras jaulas o programas que se están ejecutando en el resto del servidor, para ese usuario solo existe lo que haya en esa jaula.

Si ese usuario resultase ser malicioso podría destrozar la base de datos, lo cual ya es bastante malo, pero al menos el desastre quedaría ahí controlado.

La creación, actualización o destrucción de jaulas puede hacerse con el método descrito en el Manual, pero es más fácil usar un gestor de jaulas. Hay varios, ezjail, pot, cbsd, iocage, pero en el momento de escribir estas líneas, parece que el mejor es BastilleBSD.

Para ponerlo a andar necesitamos instalarlo y lanzar el servicio:

pkg install bastille
service bastille enable
service bastille start

Y luego configurar la red duplicando la interfaz loopback:

sysrc cloned_interfaces+=lo1
sysrc ifconfig_lo1_name="bastille0"
service netif cloneup

Se puede ejecutar así sin más, pero es más práctico para casi todos los usos complementarlo con una configuración adecuada del cortafuegos PF.

En la página de Bastille hay un ejemplo de configuración que es perfecto, lo podemos copiar en /etc/pf.conf tal cual está simplemente cambiando la denominación de nuestra interfaz de red.

ext_if="vtnet0" # <– Esto es lo que hay que cambiar, en lugar de vtnet0 lo que tengamos nosotros

set block-policy return
scrub in on $ext_if all fragment reassemble
set skip on lo

table persist
nat on $ext_if from to any -> ($ext_if:0)
rdr-anchor "rdr/*"

block in all
pass out quick keep state
antispoof for $ext_if inet
pass in inet proto tcp from any to any port ssh flags S/SA keep state

Ahora habilitamos como antes el servicio de cortafuegos y lo arrancamos.

service pf enable
service pf start

Con esto Bastille está funcionando, ahora podemos empezar a crear jaulas. Por ejemplo vamos a crear una con un servidor web (nginx). El comando base para crear es:

bastille create <nombre-jaula> <release> <ip-de-nuestra-red>

En nuestro caso nada empresarial y desde nuestro humilde hogar:

bastille create servidorweb 14.0-RELEASE 192.168.1.231

Una vez creada la jaula podemos acceder a ella con el siguiente comando y allí instalar lo que nos parezca,

bastille console servidorweb

Esto nos da acceso y allí ejecutamos los comandos habituales para instalar nginx:

pkg install nginx
service nginx enable
service nginx start

Cuando hayamos terminado salimos de la jaula con exit.

En realidad podríamos haber hecho lo mismo sin haber entrado en la jaula, Bastille tiene herramientas para trabajar con las jaulas sin entrar en ellas, lo anterior podríamos haberlo hecho con:

bastille pkg servidorweb nginx
bastille service servidorweb nginx enable
bastille service servidorweb nginx start

Podermos comprobar si nuestra jaula está esperando peticiones en el puerto 80 con:

bastille cmd servidorweb sockstat -4

Lo único que falta para tener el servidor web operativo es redirigir las peticiones web que reciba el anfitrión en el puerto 80 al puerto 80 de la jaula:

bastille rdr servidorweb tcp 80 80

Ya está.

Obviamente en la vida real las cosas se complican mucho más: las jaulas necesitan actualizaciones, llenarlas de contenido, exportarlas a otros equipos, hacerles copias de seguridad, utilizar plantillas en su creación, etc. Para todo ello Bastille ofrece soluciones. Dejo más abajo referencias que ya explican todo eso y más.

Referencias: