<?xml version="1.0" encoding="iso-8859-1"?> <!-- The FreeBSD Documentation Project The FreeBSD Spanish Documentation Project %SOURCE% en_US.ISO8859-1/books/handbook/jails/chapter.xml %SRCID% 1.14 $FreeBSD$ --> <chapter id="jails"> <chapterinfo> <authorgroup> <author> <firstname>Matteo</firstname> <surname>Riondato</surname> <contrib>Escrito por </contrib> </author> </authorgroup> </chapterinfo> <title>Jaulas</title> <indexterm><primary>jails</primary></indexterm> <sect1 id="jails-synopsis"> <title>Sinopsis</title> <para>En este capítulo se explica qué son las jaulas en &os; y cómo usarlas. Las jaulas, citadas con frecuencia como la nueva generación de <emphasis>entornos chroot</emphasis>, son una herramienta muy poderosa que se ha puesto al servicio de los administradores de sistemas, aunque su uso más básico puede ser también de suma utilidad para usuarios avanzados.</para> <para>Tras leer este capítulo sabrá usted:</para> <itemizedlist> <listitem> <para>Qué es una jaula y para qué puede usarse en sistemas &os;.</para> </listitem> <listitem> <para>Cómo generar, arrancar y parar una jaula.</para> </listitem> <listitem> <para>Cómo manejarse con los rudimentos de la administración de las jaulas, tanto desde dentro como desde fuera de la jaula.</para> </listitem> </itemizedlist> <para>Otras fuentes de información útil sobre las jaulas:</para> <itemizedlist> <listitem> <para>La página de manual &man.jail.8;. Es la referencia completa de <command>jail</command>, la herramienta administrativa de &os; con la que se arrancan, paran y controlan las jaulas.</para> </listitem> <listitem> <para>Las listas de correo y sus respectivos archivos. Los archivos de la &a.questions;, entre otras listas de correo alojadas en el &a.mailman.lists; contienen una enorme cantidad de información sobre jaulas. La ayuda que está buscando puede obtenerla, por tanto, de una búsqueda en los archivos de las listas o de enviar una pregunta que nadie haya hecho en la lista de correo &a.questions.name;.</para> </listitem> </itemizedlist> </sect1> <sect1 id="jails-terms"> <title>Términos relacionados con las jaulas</title> <para>Para ayudar a comprender las partes de &os; que intervienen en el funcionamiento de las jaulas, su funcionamiento interno y el modo en que interactuan con el resto de &os;, durante el resto del capítulo se utilizarán los siguientes términos:</para> <variablelist> <varlistentry> <term>&man.chroot.2; (comando)</term> <listitem> <para>Es una llamada al sistema de &os; que restringe el directorio raiz de un proceso y sus hijos.</para> </listitem> </varlistentry> <varlistentry> <term>&man.chroot.2; (entorno)</term> <listitem> <para>Es el entorno de procesos que se ejecutan en un <quote>chroot</quote>. Esto incluye recursos como la parte visible del sistema de ficheros, los ID de usuario y grupo disponibles, interfaces de red u otros mecanismos IPC.</para> </listitem> </varlistentry> <varlistentry> <term>&man.jail.8; (comando)</term> <listitem> <para>La herramienta de administración que permite arrancar procesos dentro del entorno de una jaula.</para> </listitem> </varlistentry> <varlistentry> <term>servidor (sistema, proceso, usuario, etc)</term> <listitem> <para>El sistema que controla una jaula. El servidor tiene acceso a todos los recursos de hardware y puede controlar procesos tanto dentro como fuera de la jaula. Una de las diferencias importantes entre el sistema que aloja la jaula y la jaula propiamente dicha: las limitaciones que afectan a los procesos que se ejecutan con privilegios de superusuario dentro de la jaula no dependen de los procesos del servidor que la aloja.</para> </listitem> </varlistentry> <varlistentry> <term>enjaulado (sistema, proceso, usuario, etc.)</term> <listitem> <para>Un proceso, usuario u otra entidad, cuyo acceso a los recursos está restringido por una jaula de &os;.</para> </listitem> </varlistentry> </variablelist> </sect1> <sect1 id="jails-intro"> <title>Introducción</title> <para>Dado lo dificil y desconcertante de la tarea de administrar sistemas se han ido desarrollando poderosas herramientas con el fin de hacer la vida del administrador más sencilla. Dichas herramientas suelen facilitar cierto tipo de mejoras en la instalación, configuración o mantenimiento de los sistemas. Una de las tareas que se espera que cumpla un administrador de sistemas es la configuración adecuada de la seguridad, de modo que pueda dar el servicio para el que se ha destinado sin que pueda verse comprometido.</para> <para>Una de las herramientas disponibles para mejorar los niveles de seguridad de un sistema &os; es el uso de <emphasis>jaulas</emphasis>. Las jaulas fueron introducidas en &os; 4.X por &a.phk;, pero en &os; 5.X sus capacidades fueron aumentadas hasta hacer de ellas un subsistema poderoso y flexible. Su desarrollo sigue avanzando, aumentando así su utilidad, rendimiento, fiabilidad y seguridad.</para> <sect2 id="jails-what"> <title>Qué es una jaula</title> <para>Los sistemas tipo BSD disponen de &man.chroot.2; desde la época de 4.2BSD. &man.chroot.8; permite restringir el directorio raiz de un conjunto de procesos, creando un entorno seguro y separado del resto del sistema. Los procesos creados dentro de un entorno chroot no pueden acceder a ficheros o recursos ubicados fuera del mismo. Por esta razón, si un atacante logra comprometer un servicio que se ejecuta en un entorno chroot no debería automáticamente poder acceder al resto del sistema. &man.chroot.8; es una buena herramienta para tareas sencillas que no requieran mucha flexibilidad o características complejas o muy avanzadas. Por desgracia, desde la invención de chroot se han ido encontrando muchas formas de saltarse las barreras que chroot impone y, aunque estén corregidas en las versiones más modernas del kernel de &os;, era evidente que &man.chroot.2; no era la solución ideal para ejecutar servicios con seguridad. Había que implementar un nuevo subsistema.</para> <para>Este es uno de los principales motivos por los que se crearon las <emphasis>jaulas</emphasis>.</para> <para>Las jaulas llevan más allá en muchos sentidos el concepto tradicional de entorno &man.chroot.2;. En un entorno &man.chroot.2; tradicional los procesos solo ven limitada la parte del sistema de ficheros a la que pueden acceder. El resto de recursos del sistema, es decir, el conjunto de usuarios del sistema, los procesos en ejecución o el subsistema de red están compartidos entre el sistema alojado y el servidor. Las jaulas extienden este modelo virtualizando no solamente el acceso al sistema de ficheros, sino al conjunto de usuarios, al subsistema de red del kernel de &os; y unas cuantas cosas más. En la <xref linkend="jails-tuning"/> se detallan diversas opciones de control exhaustivo para configurar el acceso a recursos de un entorno enjaulado.</para> <para>Una jaula se caracteriza por disponer de cuatro elementos:</para> <itemizedlist> <listitem> <para>Un <quote>subárbol</quote> de directorios: el punto desde el que se entra a una jaula. Una vez dentro de la jaula un proceso no puede escapar de dicho <quote>subárbol</quote>. Los típicos problemas de seguridad que aparecín una y otra vez en el diseño del &man.chroot.2; original no afectan a las jaulas de &os;.</para> </listitem> <listitem> <para>Un nombre de máquina (<quote>hostname</quote>), que definirá a la jaula. Las jaulas se usan principalmente para albergar servicios de red, por lo que disponer de un nombre de máquina descriptivo ayuda enormemente al administrador de sistemas.</para> </listitem> <listitem> <para>Una dirección <acronym>IP</acronym>: debe asignarse a la jaula y no cambiarse durante el ciclo de vida de la jaula. La dirección IP de una jaula suele ser un alias de un interfaz de red, aunque no es imprescindible que así sea.</para> </listitem> <listitem> <para>Un comando: La ruta de un ejecutable ubicado dentro de la jaula. La ruta es relativa al directorio raiz de la jaula, por lo que puede ser muy diferentes según el entorno.</para> </listitem> </itemizedlist> <para>Además, las jaulas pueden tener sus propios usuarios e incluso su propio <username>root</username>. Es obvio que este usuario <username>root</username> tiene su poder para hacer circunscrito a la jaula y, desde el punto de vista del servidor, el usuario <username>root</username> de la jaula no es omnipotente. El usuario <username>root</username> de la jaula no puede ejecutar tareas críticas fuera de la jaula (&man.jail.8;) a la que pertenece. Más adelante, en la <xref linkend="jails-tuning"/>, se dará más información sobre las restricciones del usuario <username>root</username>.</para> </sect2> </sect1> <sect1 id="jails-build"> <title>Creación y gestión de jaulas</title> <para>Algunos administradores dividen las jaulas en dos tipos: jaulas <quote>completas</quote>, que recrean un sistema &os; real, y jaulas <quote>de servicio</quote>, que son aquellas que están dedicadas a una sola aplicación o servicio, en muchos casos ejecutándose sin privilegios. Se trata de una división exclusivamente conceptual, por lo que el proceso de generación de una jaula no se ve afectado por ella. La página de manual &man.jail.8; explica claramente el procedimiento a seguir para generar una jaula:</para> <screen>&prompt.root; <userinput>setenv D <replaceable>/aquí/está/la/jaula</replaceable></userinput> &prompt.root; <userinput>mkdir -p $D</userinput> <co id="jailpath"/> &prompt.root; <userinput>cd /usr/src</userinput> &prompt.root; <userinput>make world DESTDIR=$D</userinput> <co id="jailworld"/> &prompt.root; <userinput>cd etc/</userinput> <footnote><para>Este paso no es necesario en &os; 6.0 y versiones posteriores.</para></footnote> &prompt.root; <userinput>make distribution DESTDIR=$D</userinput> <co id="jaildistrib"/> &prompt.root; <userinput>mount_devfs devfs $D/dev</userinput> <co id="jaildevfs"/></screen> <calloutlist> <callout arearefs="jailpath"> <para>El mejor punto de partida es la elección del punto del sistema de ficheros del servidor donde estará físicamente ubicada la jaula. <filename class="directory">/usr/jail/<replaceable>nombredelajaula</replaceable></filename> es un buen sitio. <replaceable>nombredelajaula</replaceable> es el nombre de máquina que identifica a la jaula. El sistema de ficheros <filename class="directory">/usr/</filename> suele tener espacio suficiente para albergar el sistema de ficheros de la jaula que, cuando se trata de jaulas <quote>completas</quote>, es esencialmente lo necesario para alojar todos y cada uno de los sistemas de ficheros en una instalación del sistema base por omisión de &os;.</para> </callout> <callout arearefs="jailworld"> <para>Este comando creará el contenido necesario (binarios, bibliotecas, páginas de manual, etc.) y lo copiará al <quote>subárbol</quote> elegido como ubicación física de la jaula. Todo se hace al típico estilo &os;: se compila todo y luego se instala en la ruta de destino.</para> </callout> <callout arearefs="jaildistrib"> <para>Al pasar el <quote>target</quote> <maketarget>distribution</maketarget> a <application>make</application> se instalan todos los ficheros de configuración necesarios. En pocas palabras, instala cada fichero instalable que haya en <filename class="directory">/usr/src/etc/</filename> en el directorio <filename class="directory">/etc</filename> de la jaula, es decir, en <filename class="directory">$D/etc/</filename>.</para> </callout> <callout arearefs="jaildevfs"> <para>No es imprescindible montar el sistema de ficheros &man.devfs.8; dentro de la jaula aunque por otra parte (casi) todas las aplicaciones necesitan acceso al menos a un dispositivo, dependiendo esto del propósito de la aplicación. Es muy importante el control del acceso a dispositivos desde la jaula, puesto que una configuración descuidada puede permitir que un atacante haga de las suyas. El control sobre &man.devfs.8; se gestiona mediante reglas que se detallan en las páginas de manual &man.devfs.8; y &man.devfs.conf.5;.</para> </callout> </calloutlist> <para>Una vez instalada la jaula puede arrancarla mediante &man.jail.8;. &man.jail.8; usa los cuatro argumentos que se detallan en la <xref linkend="jails-what"/>. Puede pasarle otros argumentos además de estos, por ejemplo para ejecutar procesos enjaulados bajo los permisos de un usuario específico. El argumento <option><replaceable>comando</replaceable></option> depende del tipo de jaula; si se trata de un <emphasis>virtual system</emphasis> <filename>/etc/rc</filename> es una buena elección, puesto que ejecutará la secuencia de arranque de un sistema &os; real. Si se trata de una jaula <emphasis>de servicio</emphasis> depende del servicio o aplicación que se quiera ejecutar mediante la jaula.</para> <para>Con frecuencia las jaulas se arrancan durante el arranque del servidor que las aloja; el sistema <filename>rc</filename> de &os; permite hacerlo de un modo muy sencillo.</para> <procedure> <step> <para>Puede crear una lista de jaulas que quiera arrancar en el inicio del sistema en el fichero &man.rc.conf.5;:</para> <programlisting>jail_enable="YES" # Ponga NO si quiere desactivar el arranque de jaulas jail_list="<replaceable>www</replaceable>" # Lista de nombres de jaulas separados por espacios</programlisting> </step> <step> <para>Tendrá que añadir parámetros específicos para cada jaula al fichero &man.rc.conf.5;:</para> <programlisting>jail_<replaceable>www</replaceable>_rootdir="/usr/jail/www" # directorio raiz de la jaula jail_<replaceable>www</replaceable>_hostname="<replaceable>www</replaceable>.example.org" # nombre de máquina de la jaula jail_<replaceable>www</replaceable>_ip="192.168.0.10" # dirección IP de la jaula jail_<replaceable>www</replaceable>_devfs_enable="YES" # montar devfs en la jaula jail_<replaceable>www</replaceable>_devfs_ruleset="<replaceable>www_ruleset</replaceable>" # reglas a aplicar a devfs dentro de la jaula</programlisting> <para>El arranque de jaulas por omisión que se configure en &man.rc.conf.5; ejecutará el script <filename>/etc/rc</filename> de la jaula y asumirá que es un sistema virtual completo. Si se trata de una jaula de servicio el comando de arranque por omisión tendrá que cambiarse configurando la opción <varname>jail_<replaceable>nombredejaula</replaceable>_exec_start</varname> según convenga.</para> <note> <para>Si quiere consultar la lista completa de opciones consulte la página de manual &man.rc.conf.5;.</para> </note> </step> </procedure> <para>Puede arrancar o parar a mano una jaula mediante el script <filename>/etc/rc.d/jail</filename> siempre y cuando la jaula aparezca en <filename>rc.conf</filename>:</para> <screen>&prompt.root; <userinput>/etc/rc.d/jail start <replaceable>www</replaceable></userinput> &prompt.root; <userinput>/etc/rc.d/jail stop <replaceable>www</replaceable></userinput></screen> <para>De momento no hay una forma limpia de apagar una jaula (&man.jail.8;) debido a que los comandos que se usan normalmente para producir un apagado limpio del sistema no pueden usarse dentro de una jaula. La mejor forma de parar una jaula es ejecutar el siguiente comando desde dentro de la propia jaula o bien mediante &man.jexec.8; desde fuera:</para> <screen>&prompt.root; <userinput>sh /etc/rc.shutdown</userinput></screen> <para>Para más información consulte la página de manual &man.jail.8;.</para> </sect1> <sect1 id="jails-tuning"> <title>Administración y personalización a fondo</title> <para>Hay diversas opciones que pueden usarse en las jaulas y varios tipos de formas de combinar un sistema &os; servidor y las jaulas y poder disponer de aplicaciones de alto nivel. En esta sección se muestra lo siguiente:</para> <itemizedlist> <listitem> <para>Algunas de las opciones disponibles para personalizar el comportamiento y las restricciones de seguridad que pueden aplicarse en una jaula.</para> </listitem> <listitem> <para>Algunas de las aplicaciones de alto nivel creadas para la administración de jaulas. Estas aplicaciones están en la colección de ports y pueden utilizarse en conjunto para implementar productos basados en jaulas.</para> </listitem> </itemizedlist> <sect2 id="jails-tuning-utilities"> <title>Herramientas del sistema para la personalización de jaulas en &os;</title> <para>La personalización a fondo de las jaulas se hace en su mayor parte mediante la configuración de variables &man.sysctl.8;. Hay una subcategoría especial de sysctl para que sea más sencillo organizar las opciones más más importantes: se trata de las opciones de la jerarquía <varname>security.jail.*</varname> del kernel de &os;. A continuación veremos una lista de las principales sysctl relacionadas con las jaulas y los valores que tienen por omisión. Los nombres deberían describir por sí mismos qué función tienen (N. del T.: En inglés, claro) pero si necesita más información sobre ellas consulte las páginas de manual &man.jail.8; y &man.sysctl.8;.</para> <itemizedlist> <listitem> <para><varname>security.jail.set_hostname_allowed: 1</varname></para> </listitem> <listitem> <para><varname>security.jail.socket_unixiproute_only: 1</varname></para> </listitem> <listitem> <para><varname>security.jail.sysvipc_allowed: 0</varname></para> </listitem> <listitem> <para><varname>security.jail.enforce_statfs: 2</varname></para> </listitem> <listitem> <para><varname>security.jail.allow_raw_sockets: 0</varname></para> </listitem> <listitem> <para><varname>security.jail.chflags_allowed: 0</varname></para> </listitem> <listitem> <para><varname>security.jail.jailed: 0</varname></para> </listitem> </itemizedlist> <para>El administrador del <emphasis>servidor</emphasis> puede usar estas variables para añadir o quitar limitaciones impuestas por omisión al usuario <username>root</username>. Tenga en cuenta que hay ciertas limitaciones que no pueden quitarse. El usuario <username>root</username> no puede montar o desmontar sistemas de ficheros desde su jaula. El usuario <username>root</username> no puede cargar o descargar reglas de &man.devfs.8;, configurar reglas de cortafuegos ni ejecutar muchas otras tareas administrativas que requieran modificaciones o acceso a datos internos del kernel, como cambiar el nivel de seguridad <varname>securelevel</varname> del kernel.</para> <para>El sistema base de &os; contiene un conjunto básico de herramientas que permiten el acceso a información sobre jaulas activas en el sistema, así como la conexión a una jaula para ejecutar comandos administrativos. &man.jls.8; y &man.jexec.8; forman parte del sistema base de &os; y permiten ejecutar las siguientes tareas:</para> <itemizedlist> <listitem> <para>Mostrar una lista de jaulas activas y sus correspondientes identificadores de jaula (<acronym>JID</acronym>), dirección <acronym>IP</acronym>, nombre de máquina y ruta.</para> </listitem> <listitem> <para>Conectarse a una jaula en ejecució desde el servidor y ejecutar un comando dentro de la jaula o realizar tareas administrativas dentro de dicha jaula. Esto es muy útil cuando el usuario <username>root</username> quiere apagar la jaula de forma limpia. La herramienta &man.jexec.8; permite también arrancar una shell dentro de la jaula para realizar tareas administrativas. Veamos un ejemplo:</para> <screen>&prompt.root; <userinput>jexec <replaceable>1</replaceable> tcsh</userinput></screen> </listitem> </itemizedlist> </sect2> <sect2 id="jails-tuning-admintools"> <title>Herramientas para tareas administrativas de alto nivel en la Colección de Ports</title> <para>Entre las variadas aplicaciones ajenas al Proyecto &os; que han ido apareciendo para administrar jaulas una de las más completas y útiles es <filename role="package">sysutils/jailutils</filename>. Es un conjunto de pequeñas aplicaciones de mucha ayuda en la gestión de una jaula (&man.jail.8;). Por favor, consulte su página web para más información.</para> </sect2> </sect1> <sect1 id="jails-application"> <title>Uso de las jaulas</title> <sect2 id="jails-service-jails"> <sect2info> <authorgroup> <author> <firstname>Daniel</firstname> <surname>Gerzo</surname> <contrib>Escrito por </contrib> <!-- 15. May 2007 --> </author> </authorgroup> </sect2info> <title>Jaulas <quote>de servicio</quote></title> <para>Esta sección está basada en una idea que &a.simon; presentó por primera vez en <ulink url="http://simon.nitro.dk/service-jails.html"></ulink> y en un artículo con contenido adicional escrito por Ken Tom <email>locals@gmail.com</email>. En esta sección se detalla cómo configurar un sistema &os; que añade una capa adicional de seguridad mediante el uso de &man.jail.8;. Para su verdadero aprovechamiento se asume que el sistema en el que se vaya a aplicar ejecuta al menos RELENG_6_0 y que la información que contienen las secciones previas de este capítulo se ha comprendido totalmente.</para> <sect3 id="jails-service-jails-design"> <title>Diseño</title> <para>Uno de los mayores problemas de las jaulas es la gestión de su proceso de actualización. Este proceso tiene a ser un problema porque cada jaula tiene que recompilarse íntegramente desde el código fuente cada vez que hay que actualizarla. Esto no es un gran problema si tenemos una sola jaula puesto que el proceso de actualización es bastante simple, pero si hay muchas jaulas será un trabajo largo y tedioso.</para> <warning> <para>: Esta configuración requiere mucha experiencia con &os; y el uso de sus características. Si los pasos que se detallan a continuación le parecen demasiado complicados puede echar un vistazo a sistemas más sencillos como <filename role="package">sysutils/ezjail</filename>, que le permitirá acceder a un método de administración de jaulas en &os; más sencillo y no es tan sofisticado como el que le proponemos a continuación.</para> </warning> <para>El origen de esta idea es resolver los problemas antes descritos compartiendo el máximo posible entre distintas jaulas, de un modo seguro (utilizando montajes using read-only &man.mount.nullfs.8; mounts) para que la actualización sea más sencilla y el ubicar servicios aislados en jaulas sea más interesante. Además, se presenta una forma sencilla de añadir o borrar jaulas así como una forma de actualizarlas.</para> <note> <para>Los ejemplos de servicios en este contexto son: un servidor <acronym>HTTP</acronym>,un servidor <acronym>DNS</acronym>, un servidor <acronym>SMTP</acronym>, etc.</para> </note> <para>Los objetivos de la configuración descrita en esta sección son:</para> <itemizedlist> <listitem> <para>Crear una estructura de jaulas simple y fácil de entender. Esto implica <emphasis>no</emphasis> tener que ejecutar un <quote>installworld</quote> completo en todas y cada una de las jaulas.</para> </listitem> <listitem> <para>Facilitar la creación de nuevas jaulas o el borrado de jaulas previamente existentes.</para> </listitem> <listitem> <para>Facilitar la actualización de jaulas ya existentes.</para> </listitem> <listitem> <para>Hacer posible el uso de una rama de &os; personalizada.</para> </listitem> <listitem> <para>Ser paranoico en cuanto a seguridad, reduciendo todo lo posible la posibilidad de que los sistemas se vean comprometidos.</para> </listitem> <listitem> <para>Ahorrar todo el espacio e inodos que sea posible.</para> </listitem> </itemizedlist> <para>Como ya se ha dicho, este diseño se basa en gran medida en el disponer de una única plantilla en modo de sólo lectura (a la que llamaremos <application>nullfs</application>) montada en cada jaula y un dispositivo en modo lectura-escritura por cada jaula. El dispositivo puede ser otro disco físico adicional, una partición o un dispositivo &man.md.4; basado en un vnode. En este ejemplo utilizaremos montajes <application>nullfs</application> en modo lectura-escritura.</para> <para>La estructura del sistema de ficheros se detalla en la siguiente lista:</para> <itemizedlist> <listitem> <para>Cada jaula se montará bajo <filename class="directory">/home/j</filename>.</para> </listitem> <listitem> <para><filename class="directory">/home/j/mroot</filename> será la plantilla para cada jaula y la partición de sólo lectura para todas las jaulas.</para> </listitem> <listitem> <para>Se creará un directorio vacío para cada jaula bajo el directorio <filename class="directory">/home/j</filename>.</para> </listitem> <listitem> <para>Cada jaula tendrá un directorio <filename class="directory">/s</filename> que estará enlazado con la parte de lectura-escritura del sistema.</para> </listitem> <listitem> <para>Cada jaula tendrá su propio sistema en modo lectura-escritura basado en <filename class="directory">/home/j/skel</filename>.</para> </listitem> <listitem> <para>Cada parte de lectura-escritura correspondiente a cada jaula se creará en <filename class="directory">/home/js</filename>.</para> </listitem> </itemizedlist> <note> <para>Se asume que las jaulas se instalarán bajo la partición <filename class="directory">/home</filename>. Por supuesto esto no es en absoluto obligatorio, pero hay que tener en cuenta que debe hacerse el mismo cambio en cada uno de los ejemplos que se muestran más adelante.</para> </note> <!-- Insert an image or drawing here to illustrate the example. --> </sect3> <sect3 id="jails-service-jails-template"> <title>Creación de la plantilla</title> <para>En esta sección se describen los pasos necesarios para crear la plantilla maestra que conformará la parte de sólo lectura que usarán las jaulas.</para> <para>Siempre es recomendable actualizar el sistema &os; a la última rama -RELEASE. Consulte el <ulink url="&url.books.handbook;/makeworld.html">capítulo</ulink> correspondiente de este libro si necesita más información. En caso de que la actualización no sea posible tendrá que usar <quote>buidworld</quote> para poder seguir adelante. También necesitará el paquete <filename role="package">sysutils/cpdup</filename>. Usaremos &man.portsnap.8; para descargar la Colección de Ports de &os;. El capítulo sobre <ulink url="&url.books.handbook;/portsnap.html">Portsnap</ulink> es siempre una lectura muy recomendable para quienes no tengan experiencia con su funcionamiento.</para> <procedure> <step> <para>Lo primero que haremos será crear una estructura de directorios para el sistema de ficheros de sólo lectura que contendrá los binarios de nuestras jaulas, luego iremos al directorio que contiene el árbol de código de &os; e instalaremos el sistema de ficheros de sólo lectura en la plantilla de las jaulas:</para> <screen>&prompt.root; <userinput>mkdir /home/j /home/j/mroot</userinput> &prompt.root; <userinput>cd /usr/src</userinput> &prompt.root; <userinput>make installworld DESTDIR=/home/j/mroot</userinput></screen> </step> <step> <para>Una vez hecho esto, prepararemos la Colección de Ports de &os; para nuestras jaulas así como un árbol de código &os;, necesario para usar <application>mergemaster</application>:</para> <screen>&prompt.root; <userinput>cd /home/j/mroot</userinput> &prompt.root; <userinput>mkdir usr/ports</userinput> &prompt.root; <userinput>portsnap -p /home/j/mroot/usr/ports fetch extract</userinput> &prompt.root; <userinput>cpdup /usr/src /home/j/mroot/usr/src</userinput></screen> </step> <step> <para>Crear la estructura de directorios necesaria para la parte de lectura-escritura del sistema:</para> <screen>&prompt.root; <userinput>mkdir /home/j/skel /home/j/skel/home /home/j/skel/usr-X11R6 /home/j/skel/distfiles</userinput> &prompt.root; <userinput>mv etc /home/j/skel</userinput> &prompt.root; <userinput>mv usr/local /home/j/skel/usr-local</userinput> &prompt.root; <userinput>mv tmp /home/j/skel</userinput> &prompt.root; <userinput>mv var /home/j/skel</userinput> &prompt.root; <userinput>mv root /home/j/skel</userinput></screen> </step> <step> <para>Usamos <application>mergemaster</application> para instalar los ficheros de configuración que falten. Después nos libramos de los directorios adicionales que haya creado <application>mergemaster</application>:</para> <screen>&prompt.root; <userinput>mergemaster -t /home/j/skel/var/tmp/temproot -D /home/j/skel -i</userinput> &prompt.root; <userinput>cd /home/j/skel</userinput> &prompt.root; <userinput>rm -R bin boot lib libexec mnt proc rescue sbin sys usr dev</userinput></screen> </step> <step> <para>Ahora enlazamos simbólicamente el sistema de ficheros de lectura-escritura con el sistema de ficheros de sólo lectura. Por favor, asegúrese de que los enlaces simbólicos se crean en las ubicaciones correctas: <filename class="directory">s/</filename>. Si se usan directorios reales o directorios erróneos la instalación no funcionará.</para> <screen>&prompt.root; <userinput>cd /home/j/mroot</userinput> &prompt.root; <userinput>mkdir s</userinput> &prompt.root; <userinput>ln -s s/etc etc</userinput> &prompt.root; <userinput>ln -s s/home home</userinput> &prompt.root; <userinput>ln -s s/root root</userinput> &prompt.root; <userinput>ln -s ../s/usr-local usr/local</userinput> &prompt.root; <userinput>ln -s ../s/usr-X11R6 usr/X11R6</userinput> &prompt.root; <userinput>ln -s ../../s/distfiles usr/ports/distfiles</userinput> &prompt.root; <userinput>ln -s s/tmp tmp</userinput> &prompt.root; <userinput>ln -s s/var var</userinput></screen> </step> <step> <para>Como último paso, cree un <filename>/home/j/skel/etc/make.conf</filename> genérico con el siguiente contenido:</para> <programlisting>WRKDIRPREFIX?= /s/portbuild</programlisting> <para>El tener <literal>WRKDIRPREFIX</literal> configurado de este modo hará posible compilar ports de &os; dentro de cada jaula. Recuerde que el el directorio de los ports es de sólo lectura. La ruta personalizada por <literal>WRKDIRPREFIX</literal> permite ejecutar compilaciones en la parte de sólo lectura de cada jaula.</para> </step> </procedure> </sect3> <sect3 id="jails-service-jails-creating"> <title>Creación de las jaulas</title> <para>Ya tenemos una plantilla de jaulas de &os; completa, así que podemos configurar nuestras jaulas en <filename>/etc/rc.conf</filename>. En este ejemplo crearemos 3 jaulas: <quote>NS</quote>, <quote>MAIL</quote> y <quote>WWW</quote>.</para> <procedure> <step> <para>Introduzca las siguientes lineas en el fichero <filename>/etc/fstab</filename>; con esto cada jaula tendrá acceso a la plantilla de sólo lectura y al espacio de lectura-escritura:</para> <programlisting>/home/j/mroot /home/j/ns nullfs ro 0 0 /home/j/mroot /home/j/mail nullfs ro 0 0 /home/j/mroot /home/j/www nullfs ro 0 0 /home/js/ns /home/j/ns/s nullfs rw 0 0 /home/js/mail /home/j/mail/s nullfs rw 0 0 /home/js/www /home/j/www/s nullfs rw 0 0</programlisting> <note> <para>Las particiones que tienen un 0 en la columna <quote>pass</quote> no serán revisadas por &man.fsck.8; durante el arranque y las que tienen un 0 en la columna <quote>dump</quote> no serán copiadas por &man.dump.8;. No nos interesa que <application>fsck</application> compruebe la integridad de montajes <application>nullfs</application> ni que <application>dump</application> haga copias de seguridad de montajes nullfs de sólo lectura de las jaulas. Por esta razón el ejemplo de <filename>fstab</filename> tiene en las dos últimas columnas <quote>0 0</quote>.</para> </note> </step> <step> <para>Configure las jaulas en <filename>/etc/rc.conf</filename>:</para> <programlisting>jail_enable="YES" jail_set_hostname_allow="NO" jail_list="ns mail www" jail_ns_hostname="ns.ejemplo.org" jail_ns_ip="192.168.3.17" jail_ns_rootdir="/usr/home/j/ns" jail_ns_devfs_enable="YES" jail_mail_hostname="mail.ejemplo.org" jail_mail_ip="192.168.3.18" jail_mail_rootdir="/usr/home/j/mail" jail_mail_devfs_enable="YES" jail_www_hostname="www.ejemplo.org" jail_www_ip="62.123.43.14" jail_www_rootdir="/usr/home/j/www" jail_www_devfs_enable="YES"</programlisting> <warning> <para>: La razón por la que <varname>jail_<replaceable>nombre</replaceable>_rootdir</varname> contiene <filename class="directory">/usr/home</filename> y no <filename class="directory">/home</filename> es que la ruta física del directorio<filename class="directory">/home</filename> en una instalación de &os; por omisión es <filename class="directory">/usr/home</filename>. La variable <varname>jail_<replaceable>nombre</replaceable>_rootdir</varname> <emphasis>no</emphasis> debe apuntar a una ruta que contenga un enlace simbólico porque sería imposible arrancar las jaulas. Utilice la herramienta &man.realpath.1; para asegurarse del valor exacto que debe asignar a la variable. Por favor, consulte el aviso de seguridad &os;-SA-07:01.jail para más información.</para> </warning> </step> <step> <para>Creamos los puntos de montaje de sistemas de ficheros de sólo lectura correspondientes a cada jaula:</para> <screen>&prompt.root; <userinput>mkdir /home/j/ns /home/j/mail /home/j/www</userinput></screen> </step> <step> <para>Instalamos la plantilla de lectura-escritura dentro de cada jaula. Observe que utilizamos <filename role="package">sysutils/cpdup</filename> para asegurarnos de que se hace una copia exacta de cada directorio:</para> <!-- keramida: Why is cpdup required here? Doesn't cpio(1) already include adequate functionality for performing this job *and* have the advantage of being part of the base system of FreeBSD? --> <screen>&prompt.root; <userinput>mkdir /home/js</userinput> &prompt.root; <userinput>cpdup /home/j/skel /home/js/ns</userinput> &prompt.root; <userinput>cpdup /home/j/skel /home/js/mail</userinput> &prompt.root; <userinput>cpdup /home/j/skel /home/js/www</userinput></screen> </step> <step> <para>Llegados a este punto las jaulas están configuradas y listas para arrancar. Monte los sistemas de ficheros de cada jaula y luego arránquelas con el script <filename>/etc/rc.d/jail</filename>:</para> <screen>&prompt.root; <userinput>mount -a</userinput> &prompt.root; <userinput>/etc/rc.d/jail start</userinput></screen> </step> </procedure> <para>Las jaulas deberían haber arrancado. Asegúrese de ello con &man.jls.8;. La salida que verá debe parecerse a esta:</para> <screen>&prompt.root; <userinput>jls</userinput> JID IP Address Hostname Path 3 192.168.3.17 ns.ejemplo.org /home/j/ns 2 192.168.3.18 mail.ejemplo.org /home/j/mail 1 62.123.43.14 www.ejemplo.org /home/j/www</screen> <para>En este punto debería ser posible entrar a cada una de las jaulas, añadir nuevos usuarios o configurar dæmons. La columna <literal>JID</literal> indica el número de identificación de cada jaula que esté funcionando en el sistema. Con el siguiente comando puede ejecutar tareas administrativas en la jaula cuyo <literal>JID</literal> sea 3:</para> <screen>&prompt.root; <userinput>jexec 3 tcsh</userinput></screen> </sect3> <sect3 id="jails-service-jails-upgrading"> <title>Actualización</title> <para>Llegará el momento en el que sea necesario actualizar el sistema, bien por seguridad o porque sea útil para las jaulas disponer de alguna nueva característica del sistema. El diseño de esta configuración facilita una forma fácil de actualizar sus jaulas. Además, minimiza la pérdida de servicio, puesto que las jaulas deben apagarse sólamente al final de todo el proceso. Se ofrece también la posibilidad de volver a la versión anterior en caso de que algo salga mal.</para> <procedure> <step> <para>El primer paso es actualizar el servidor que aloja las jaulas de la forma habitual. Después creamos una plantilla de sólo lectura temporal en <filename class="directory">/home/j/mroot2</filename>.</para> <screen>&prompt.root; <userinput>mkdir /home/j/mroot2</userinput> &prompt.root; <userinput>cd /usr/src</userinput> &prompt.root; <userinput>make installworld DESTDIR=/home/j/mroot2</userinput> &prompt.root; <userinput>cd /home/j/mroot2</userinput> &prompt.root; <userinput>cpdup /usr/src usr/src</userinput> &prompt.root; <userinput>mkdir s</userinput></screen> <para>La ejecución de <maketarget>installworld</maketarget> crea unos cuantos directorios innecesarios que debemos borrar:</para> <screen>&prompt.root; <userinput>chflags -R 0 var</userinput> &prompt.root; <userinput>rm -R etc var root usr/local tmp</userinput></screen> </step> <step> <para>Creamos de nuevo los enlaces simbólicos de lectura-escritura del sistema de ficheros principal:</para> <screen>&prompt.root; <userinput>ln -s s/etc etc</userinput> &prompt.root; <userinput>ln -s s/root root</userinput> &prompt.root; <userinput>ln -s s/home home</userinput> &prompt.root; <userinput>ln -s ../s/usr-local usr/local</userinput> &prompt.root; <userinput>ln -s ../s/usr-X11R6 usr/X11R6</userinput> &prompt.root; <userinput>ln -s s/tmp tmp</userinput> &prompt.root; <userinput>ln -s s/var var</userinput></screen> </step> <step> <para>Ha llegado el momento de parar las jaulas:</para> <screen>&prompt.root; <userinput>/etc/rc.d/jail stop</userinput></screen> </step> <step> <para>Desmontamos los sistemas de ficheros originales:</para> <!-- keramida: Shouldn't we suggest a short script-based loop here, instead of tediously copying the same commands multiple times? --> <screen>&prompt.root; <userinput>umount /home/j/ns/s</userinput> &prompt.root; <userinput>umount /home/j/ns</userinput> &prompt.root; <userinput>umount /home/j/mail/s</userinput> &prompt.root; <userinput>umount /home/j/mail</userinput> &prompt.root; <userinput>umount /home/j/www/s</userinput> &prompt.root; <userinput>umount /home/j/www</userinput></screen> <note> <para>Los sistemas de ficheros de lectura-escritura cuelgan del sistema de sólo lectura <filename class="directory">/s</filename> y por tanto deben desmontarse antes.</para> </note> </step> <step> <para>Movemos el sistema de ficheros de sólo lectura viejo y lo reemplazamos por el nuevo. Nos servirá de copia de seguridad y como archivo en caso de que haya problemas. Para darle un nombre usamos la fecha en la que se creado una nueva copia del sistema de ficheros de sólo lectura. Movemos también la Colección de Ports de &os; al sistema de ficheros nuevo para ahorrar un poco más de espacio e inodos:</para> <screen>&prompt.root; <userinput>cd /home/j</userinput> &prompt.root; <userinput>mv mroot mroot.20060601</userinput> &prompt.root; <userinput>mv mroot2 mroot</userinput> &prompt.root; <userinput>mv mroot.20060601/usr/ports mroot/usr</userinput></screen> </step> <step> <para>Una vez llegados a este punto la nueva plantilla de sólo lectura está lista, de manera que lo único que nos queda por hacer es montar los sistemas de ficheros y arrancar las jaulas:</para> <screen>&prompt.root; <userinput>mount -a</userinput> &prompt.root; <userinput>/etc/rc.d/jail start</userinput></screen> </step> </procedure> <para>Compruebe con &man.jls.8; si las jaulas han arrancado sin contratiempos. No olvide ejecutar mergemaster en cada jaula. Tendrá que actualizar tanto los ficheros de configuración como los scripts rc.d.</para> </sect3> </sect2> </sect1> </chapter>