Put in remaining pages and wiki contents.
[ikiwiki.git] / docs / handbook / handbook-jails-application.mdwn
1 \r
2 \r
3 # 12.6 Application of Jails \r
4 \r
5 ## 12.6.1 Service Jails \r
6  ***Contributed by Daniel Gerzo.***\r
7 \r
8 ***\r
9  This section is based upon an idea originally presented by Simon L. Nielsen <simon@freebsd.org> at http://simon.nitro.dk/service-jails.html, and an updated article written by Ken Tom <locals@gmail.com>. This section illustrates how to set up a DragonFly system that adds an additional layer of security, using the [jail(8)](http://leaf.dragonflybsd.org/cgi/web-man?command#jail&section8) feature. It is also assumed that the given system is at least running DragonFly 1.7 and the information provided earlier in this chapter has been well understood.\r
10 \r
11 ### 12.6.1.1 Design \r
12 \r
13  One of the major problems with jails is the management of their upgrade process. This tends to be a problem because every jail has to be rebuilt from scratch whenever it is updated. This is usually not a problem for a single jail, since the update process is fairly simple, but can be quite time consuming and tedious if a lot of jails are created.\r
14 \r
15 ***\r
16  This idea has been presented to resolve such issues by sharing as much as is possible between jails, in a safe way -- using read-only [mount_null(8)](http://leaf.dragonflybsd.org/cgi/web-man?command#mount_null&section8) mounts, so that updating will be simpler, and putting single services into individual jails will become more attractive. Additionally, it provides a simple way to add or remove jails as well as a way to upgrade them.\r
17 \r
18 ***\r
19  ***\r
20    **Note:**  Examples of services in this context are: an HTTP server, a DNS server, a SMTP server, and so forth.\r
21 \r
22 ***\r
23  The goals of the setup described in this section are:\r
24 \r
25 ***\r
26  ***\r
27
28 * Create a simple and easy to understand jail structure. This implies not having to run a full installworld on each and every jail.\r
29 ***\r
30  ***\r
31
32 * Make it easy to add new jails or remove existing ones.\r
33 ***\r
34  ***\r
35
36 * Make it easy to update or upgrade existing jails.\r
37 ***\r
38  ***\r
39
40 * Make it possible to run a customized DragonFly branch.\r
41 ***\r
42  ***\r
43
44 * Be paranoid about security, reducing as much as possible the possibility of compromise.\r
45 ***\r
46  ***\r
47
48 * Save space and inodes, as much as possible.\r
49 \r
50 ***\r
51  As it has been already mentioned, this design relies heavily on having a single master template which is read-only (known as  **nullfs** ) mounted into each jail and one read-write device per jail. A device can be a separate physical disc, a partition, or a vnode backed [md(4)](http://leaf.dragonflybsd.org/cgi/web-man?command#md&section4) device. In this example, we will use read-write nullfs mounts.\r
52 \r
53 ***\r
54  The file system layout is described in the following list:\r
55 ***\r
56  ***\r
57
58 * Each jail will be mounted under the ***/home/jails*** directory.\r
59 ***\r
60  ***\r
61
62 * ***/home/jails/mroot*** is the template for each jail and the read-only partition for all of the jails.\r
63 ***\r
64  ***\r
65
66 * A blank directory will be created for each jail under the ***/home/jails*** directory.\r
67 ***\r
68  ***\r
69
70 * Each jail will have a ***/s*** directory, that will be linked to the read-write portion of the system.\r
71 ***\r
72  ***\r
73
74 * Each jail shall have its own read-write system that is based upon ***/home/jails/skel***.\r
75 ***\r
76  ***\r
77
78 * Each jailspace (read-write portion of each jail) shall be created in ***/home/jailspace***.\r
79 ***\r
80  ***\r
81     **Note:**  This assumes that the jails are based under the ***/home*** partition. This can, of course, be changed to anything else, but this change will have to be reflected in each of the examples below.\r
82 \r
83 ### 12.6.1.2 Creating the Template \r
84 \r
85  This section will describe the steps needed to create the master template that will be the read-only portion for the jails to use.\r
86 \r
87 ***\r
88  It is always a good idea to update the DragonFly system to the latest stable release before. Check the corresponding Handbook Chapter to accomplish this task. In the case the update is not feasible, the buildworld will be required in order to be able to proceed. \r
89 \r
90 ***\r
91  ***\r
92   1.#1 First, create a directory structure for the read-only file system which will contain the DragonFly binaries for our jails, then change directory to the DragonFly source tree and install the read-only file system to the jail template:\r
93 \r
94 ***\r
95  ***\r
96       \r
97     # mkdir /home/jails /home/jails/mroot\r
98     # cd /usr/src\r
99     # make installworld DESTDIR=/home/jails/mroot\r
100 \r
101 \r
102 ***\r
103  ***\r
104   1.#2 Next, prepare a DragonFly Pkgsrc Framework for the jails as well as a DragonFly source tree, which is required for  **mergemaster** :\r
105 \r
106 ***\r
107  ***\r
108       \r
109     # mkdir /home/jails/mroot/usr\r
110     # cd /home/jails/mroot/usr\r
111     # cvs -d anoncvs@anoncvs.us.netbsd.org:/cvsroot co pkgsrc\r
112     # cpdup /usr/src /home/jails/mroot/usr/src\r
113 \r
114 \r
115 ***\r
116  ***\r
117   1.#3 Create a skeleton for the read-write portion of the system:\r
118 \r
119 ***\r
120  ***\r
121       \r
122     # mkdir /home/jails/skel /home/jails/skel/home /home/jails/skel/usr-X11R6 /home/jails/skel/distfiles\r
123     # mv etc /home/jails/skel\r
124     # mv usr/local /home/jails/skel/usr-local\r
125     # mv tmp /home/jails/skel\r
126     # mv var /home/jails/skel\r
127     # mv root /home/jails/skel\r
128 \r
129 \r
130 ***\r
131  ***\r
132   1.#4 Use  **mergemaster**  to install missing configuration files. Then get rid of the extra directories that  **mergemaster**  creates:\r
133 \r
134 ***\r
135  ***\r
136       \r
137     # mergemaster -t /home/jails/skel/var/tmp/temproot -D /home/jails/skel -i\r
138     # cd /home/jails/skel\r
139     # rm -R bin boot lib libexec mnt proc rescue sbin sys usr dev\r
140 \r
141 \r
142 ***\r
143  ***\r
144   1.#5 Now, symlink the read-write file system to the read-only file system. Please make sure that the symlinks are created in the correct s/ locations. Real directories or the creation of directories in the wrong locations will cause the installation to fail.\r
145 \r
146 ***\r
147  ***\r
148       \r
149     # cd /home/jails/mroot\r
150     # mkdir s\r
151     # ln -s s/etc etc\r
152     # ln -s s/home home\r
153     # ln -s s/root root\r
154     # ln -s ../s/usr-local usr/local\r
155     # ln -s ../s/usr-X11R6 usr/X11R6\r
156     # ln -s ../../s/distfiles usr/ports/distfiles\r
157     # ln -s s/tmp tmp\r
158     # ln -s s/var var\r
159 \r
160 \r
161 ***\r
162  ***\r
163   1.#6 As a last step, create a generic ***/home/jails/skel/etc/make.conf*** with its contents as shown below:\r
164 \r
165 ***\r
166  ***\r
167       \r
168     WRKDIRPREFIX?=/s/portbuild\r
169 \r
170 \r
171 ***\r
172  ***\r
173   Having WRKDIRPREFIX set up this way will make it possible to compile DragonFly packages inside each jail. Remember that the pkgsrc directory is part of the read-only system. The custom path for WRKDIRPREFIX allows builds to be done in the read-write portion of every jail.\r
174 \r
175 ### 12.6.1.3 Creating Jails \r
176 \r
177  Now that we have a complete DragonFly jail template, we can setup and configure the jails in ***/etc/rc.conf***. This example demonstrates the creation of 3 jails: “NS”, “MAIL” and “WWW”.\r
178 \r
179 ***\r
180  ***\r
181   1.#1 Put the following lines into the ***/etc/fstab*** file, so that the read-only template for the jails and the read-write space will be available in the respective jails:\r
182 \r
183 ***\r
184  ***\r
185       \r
186     /home/jails/mroot   /home/jails/ns     null  ro  0   0\r
187     /home/jails/mroot   /home/jails/mail   null  ro  0   0\r
188     /home/jails/mroot   /home/jails/www    null  ro  0   0\r
189     /home/jailspace/ns     /home/jails/ns/s   null  rw  0   0\r
190     /home/jailspace/mail   /home/jails/mail/s null  rw  0   0\r
191     /home/jailspace/www    /home/jails/www/s  null  rw  0   0\r
192 \r
193 \r
194 ***\r
195  ***\r
196   ***\r
197     **Note:**  Partitions marked with a 0 pass number are not checked by [fsck(8)](http://leaf.dragonflybsd.org/cgi/web-man?command#fsck&section8) during boot, and partitions marked with a 0 dump number are not backed up by [dump(8)](http://leaf.dragonflybsd.org/cgi/web-man?command=dump&section=8). We do not want fsck to check null mounts or dump to back up the read-only null mounts of the jails. This is why they are marked with “0 0” in the last two columns of each fstab entry above.\r
198 \r
199 ***\r
200  ***\r
201   1.#2 Configure the jails in ***/etc/rc.conf***:\r
202 \r
203 ***\r
204  ***\r
205       \r
206     jail_enable="YES"\r
207     jail_set_hostname_allow="NO"\r
208     jail_list="ns mail www"\r
209     jail_ns_hostname="ns.example.org"\r
210     jail_ns_ip="192.168.3.17"\r
211     jail_ns_rootdir="/home/jails/ns"\r
212     jail_mail_hostname="mail.example.org"\r
213     jail_mail_ip="192.168.3.18"\r
214     jail_mail_rootdir="/home/jails/mail"\r
215     jail_www_hostname="www.example.org"\r
216     jail_www_ip="62.123.43.14"\r
217     jail_www_rootdir="/home/jails/www"\r
218 \r
219 \r
220 ***\r
221  ***\r
222   1.#3 Create the required mount points for the read-only file system of each jail:\r
223 \r
224 ***\r
225  ***\r
226       \r
227     # mkdir /home/jails/ns /home/jails/mail /home/jails/www\r
228 \r
229 \r
230 ***\r
231  ***\r
232   1.#4 Install the read-write template into each jail. Note the use of ***cpdup***, which helps to ensure that a correct copy is done of each directory:\r
233 \r
234 ***\r
235  ***\r
236       \r
237     # mkdir /home/jailspace\r
238     # cpdup /home/jails/skel /home/jailspace/ns\r
239     # cpdup /home/jails/skel /home/jailspace/mail\r
240     # cpdup /home/jails/skel /home/jailspace/www\r
241 \r
242 \r
243 ***\r
244  ***\r
245   1.#5 In this phase, the jails are built and prepared to run. First, mount the required file systems for each jail, and then start them using the ***/etc/rc.d/jail*** script:\r
246 \r
247 ***\r
248  ***\r
249       \r
250     # mount -a\r
251     # /etc/rc.d/jail start\r
252 \r
253 \r
254 ***\r
255  The jails should be running now. To check if they have started correctly, use the [jls(8)](http://leaf.dragonflybsd.org/cgi/web-man?command#jls&section8) command. Its output should be similar to the following:\r
256 \r
257  ***\r
258      \r
259     # jls\r
260        JID  IP Address      Hostname                      Path\r
261          3  192.168.3.17    ns.example.org                /home/jails/ns\r
262          2  192.168.3.18    mail.example.org              /home/jails/mail\r
263          1  62.123.43.14    www.example.org               /home/jails/www\r
264 \r
265 \r
266 ***\r
267  At this point, it should be possible to log onto each jail, add new users or configure daemons. The JID column indicates the jail identification number of each running jail. Use the following command in order to perform administrative tasks in the jail whose JID is 3:\r
268 \r
269 ***\r
270      \r
271     # jexec 3 tcsh\r
272 \r
273 \r
274 ### 12.6.1.4 Upgrading \r
275 \r
276  In time, there will be a need to upgrade the system to a newer version of DragonFly, either because of a security issue, or because new features have been implemented which are useful for the existing jails. The design of this setup provides an easy way to upgrade existing jails. Additionally, it minimizes their downtime, as the jails will be brought down only in the very last minute. Also, it provides a way to roll back to the older versions should any problems occur.\r
277 \r
278 ***\r
279  ***\r
280   1.#1 The first step is to upgrade the host system in the usual manner. Then create a new temporary read-only template in ***/home/jails/mroot2***.\r
281 \r
282 ***\r
283  ***\r
284       \r
285     # mkdir /home/jails/mroot2\r
286     # cd /usr/src\r
287     # make installworld DESTDIR=/home/jails/mroot2\r
288     # cd /home/jails/mroot2\r
289     # cpdup /usr/src usr/src\r
290     # mkdir s\r
291 \r
292 \r
293 ***\r
294  ***\r
295   The ***installworld*** run creates a few unnecessary directories, which should be removed:\r
296 \r
297 ***\r
298  ***\r
299       \r
300     # chflags -R 0 var\r
301     # rm -R etc var root usr/local tmp\r
302 \r
303 \r
304 ***\r
305  ***\r
306   1.#2 Recreate the read-write symlinks for the master file system:\r
307 \r
308 ***\r
309  ***\r
310       \r
311     # ln -s s/etc etc\r
312     # ln -s s/root root\r
313     # ln -s s/home home\r
314     # ln -s ../s/usr-local usr/local\r
315     # ln -s ../s/usr-X11R6 usr/X11R6\r
316     # ln -s s/tmp tmp\r
317     # ln -s s/var var\r
318 \r
319 \r
320 ***\r
321  ***\r
322   1.#3 The right time to stop the jails is now:\r
323 \r
324 ***\r
325  ***\r
326       \r
327     # /etc/rc.d/jail stop\r
328 \r
329 \r
330 ***\r
331  ***\r
332   1.#4 Unmount the original file systems:\r
333 \r
334 ***\r
335  ***\r
336       \r
337     # umount /home/jails/ns/s\r
338     # umount /home/jails/ns\r
339     # umount /home/jails/mail/s\r
340     # umount /home/jails/mail\r
341     # umount /home/jails/www/s\r
342     # umount /home/jails/www\r
343 \r
344 \r
345 ***\r
346  ***\r
347   ***\r
348     **Note:**  The read-write systems are attached to the read-only system (***/s***) and must be unmounted first.\r
349 \r
350 ***\r
351  ***\r
352   1.#5 Move the old read-only file system and replace it with the new one. This will serve as a backup and archive of the old read-only file system should something go wrong. The naming convention used here corresponds to when a new read-only file system has been created. Move the original DragonFly Packagesource Framework over to the new file system to save some space and inodes:\r
353 \r
354 ***\r
355  ***\r
356       \r
357     # cd /home/jails\r
358     # mv mroot mroot.20060601\r
359     # mv mroot2 mroot\r
360     # mv mroot.20060601/usr/ports mroot/usr\r
361 \r
362 \r
363 ***\r
364  ***\r
365   1.#6 At this point the new read-only template is ready, so the only remaining task is to remount the file systems and start the jails:\r
366 \r
367 ***\r
368  ***\r
369       \r
370     # mount -a\r
371     # /etc/rc.d/jail start\r
372 \r
373 \r
374 ***\r
375  Use [jls(8)](http://leaf.dragonflybsd.org/cgi/web-man?command#jls&section8) to check if the jails started correctly. Do not forget to run mergemaster in each jail. The configuration files will need to be updated as well as the rc.d scripts.\r
376 \r
377 ----\r
378 \r