1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
|
<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
<!--
The FreeBSD Documentation Project
The FreeBSD Spanish Documentation Project
%SOURCE% en_US.ISO8859-1/books/handbook/jails/chapter.sgml
%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
role="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
role="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 role="directory">/usr/src/etc/</filename> en el
directorio <filename role="directory">/etc</filename> de la
jaula, es decir, en
<filename role="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
role="directory">/home/j</filename>.</para>
</listitem>
<listitem>
<para><filename role="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
role="directory">/home/j</filename>.</para>
</listitem>
<listitem>
<para>Cada jaula tendrá un directorio <filename
role="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
role="directory">/home/j/skel</filename>.</para>
</listitem>
<listitem>
<para>Cada parte de lectura-escritura correspondiente a cada
jaula se creará en <filename
role="directory">/home/js</filename>.</para>
</listitem>
</itemizedlist>
<note>
<para>Se asume que las jaulas se instalarán bajo
la partición <filename
role="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
role="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
role="directory">/usr/home</filename> y no
<filename role="directory">/home</filename> es que la ruta
física del directorio<filename
role="directory">/home</filename> en una instalación
de &os; por omisión es <filename
role="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
role="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
role="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>
|