doc/en_US.ISO8859-1/books/handbook/jails/chapter.xml
Warren Block c405269a35 Add new sysutils/ezjail section. Reviewed on IRC, -doc, and with
individuals through email.  Particular thanks to Glen Barber for his
experience and patience.
2014-08-23 17:54:21 +00:00

1619 lines
60 KiB
XML

<?xml version="1.0" encoding="iso-8859-1"?>
<!--
The FreeBSD Documentation Project
$FreeBSD$
-->
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="jails">
<info>
<title>Jails</title>
<authorgroup>
<author><personname><firstname>Matteo</firstname><surname>Riondato</surname></personname><contrib>Contributed
by </contrib></author>
</authorgroup>
</info>
<indexterm><primary>jails</primary></indexterm>
<sect1 xml:id="jails-synopsis">
<title>Synopsis</title>
<para>Since system administration is a difficult task, many tools
have been developed to make life easier for the administrator.
These tools often enhance the way systems are installed,
configured, and maintained. One of the tools which can be used
to enhance the security of a &os; system is
<firstterm>jails</firstterm>. Jails have been available since
&os;&nbsp;4.X and continue to be enhanced in their usefulness,
performance, reliability, and security.</para>
<para>Jails build upon the &man.chroot.2; concept, which is used
to change the root directory of a set of processes, creating a
safe environment, separate from the rest of the system.
Processes created in the chrooted environment can not access
files or resources outside of it. For that reason, compromising
a service running in a chrooted environment should not allow the
attacker to compromise the entire system. However, a chroot has
several limitations. It is suited to easy tasks which do not
require much flexibility or complex, advanced features. Over
time many ways have been found to escape from a chrooted
environment, making it a less than ideal solution for securing
services.</para>
<para>Jails improve on the concept of the traditional chroot
environment in several ways. In a traditional chroot
environment, processes are only limited in the part of the file
system they can access. The rest of the system resources,
system users, running processes, and the networking subsystem
are shared by the chrooted processes and the processes of the
host system. Jails expand this model by virtualizing access to
the file system, the set of users, and the networking subsystem.
More fine-grained controls are available for tuning the access
of a jailed environment. Jails can be considered as a type of
operating system-level virtualization.</para>
<para>A jail is characterized by four elements:</para>
<itemizedlist>
<listitem>
<para>A directory subtree: the starting point from which a
jail is entered. Once inside the jail, a process is not
permitted to escape outside of this subtree.</para>
</listitem>
<listitem>
<para>A hostname: which will be used by the jail.</para>
</listitem>
<listitem>
<para>An <acronym>IP</acronym> address: which is assigned to
the jail. The <acronym>IP</acronym> address of a jail is
often an alias address for an existing network
interface.</para>
</listitem>
<listitem>
<para>A command: the path name of an executable to run inside
the jail. The path is relative to the root directory of the
jail environment.</para>
</listitem>
</itemizedlist>
<para>Jails have their own set of users and their own <systemitem
class="username">root</systemitem> account which are limited
to the jail environment. The <systemitem
class="username">root</systemitem> account of a jail is not
allowed to perform operations to the system outside of the
associated jail environment.</para>
<para>This chapter provides an overview of jail terminology are
how to use &os; jails. Jails are a powerful tool for system
administrators, but their basic usage can also be useful for
advanced users.</para>
<para>After reading this chapter, you will know:</para>
<itemizedlist>
<listitem>
<para>What a jail is and what purpose it may serve in &os;
installations.</para>
</listitem>
<listitem>
<para>How to build, start, and stop a jail.</para>
</listitem>
<listitem>
<para>The basics of jail administration, both from inside and
outside the jail.</para>
</listitem>
</itemizedlist>
<important>
<para>Jails are a powerful tool, but they are not a security
panacea. While it is not possible for a jailed process to
break out on its own, there are several ways in which an
unprivileged user outside the jail can cooperate with a
privileged user inside the jail to obtain elevated privileges
in the host environment.</para>
<para>Most of these attacks can be mitigated by ensuring that
the jail root is not accessible to unprivileged users in the
host environment. As a general rule, untrusted users with
privileged access to a jail should not be given access to the
host environment.</para>
</important>
</sect1>
<sect1 xml:id="jails-terms">
<title>Terms Related to Jails</title>
<para>To facilitate better understanding of parts of the &os;
system related to jails, their internals and the way they
interact with the rest of &os;, the following terms are used
further in this chapter:</para>
<variablelist>
<varlistentry>
<term>&man.chroot.8; (command)</term>
<listitem>
<para>Utility, which uses &man.chroot.2; &os; system call to
change the root directory of a process and all its
descendants.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>&man.chroot.2; (environment)</term>
<listitem>
<para>The environment of processes running in a
<quote>chroot</quote>. This includes resources such as
the part of the file system which is visible, user and
group IDs which are available, network interfaces and
other IPC mechanisms, etc.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>&man.jail.8; (command)</term>
<listitem>
<para>The system administration utility which allows
launching of processes within a jail environment.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>host (system, process, user, etc.)</term>
<listitem>
<para>The controlling system of a jail environment. The
host system has access to all the hardware resources
available, and can control processes both outside of and
inside a jail environment. One of the important
differences of the host system from a jail is that the
limitations which apply to superuser processes inside a
jail are not enforced for processes of the host
system.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>hosted (system, process, user, etc.)</term>
<listitem>
<para>A process, user or other entity, whose access to
resources is restricted by a &os; jail.</para>
</listitem>
</varlistentry>
</variablelist>
</sect1>
<sect1 xml:id="jails-build">
<title>Creating and Controlling Jails</title>
<para>Some administrators divide jails into the following two
types: <quote>complete</quote> jails, which resemble a real &os;
system, and <quote>service</quote> jails, dedicated to one
application or service, possibly running with privileges. This
is only a conceptual division and the process of building a jail
is not affected by it. When creating a <quote>complete</quote>
jail there are two options for the source of the userland: use
prebuilt binaries (such as those supplied on an install media)
or build from source.</para>
<para>To install the userland from installation media, first
create the root directory for the jail. This can be done by
setting the <varname>DESTDIR</varname> variable to the proper
location. The command to use depends on which shell is being
used.</para>
<para>When using &man.sh.1;:</para>
<screen>&prompt.root; <userinput>export DESTDIR=<replaceable>/here/is/the/jail</replaceable></userinput></screen>
<para>If <command>csh</command>/<command>tcsh</command> is used,
execute this instead:</para>
<screen>&prompt.root; <userinput>setenv DESTDIR <replaceable>/here/is/the/jail</replaceable></userinput></screen>
<para>Mount the install media as covered in &man.mdconfig.8;
when using the install ISO:</para>
<screen>&prompt.root; <userinput>mount -t cd9660 /dev/`mdconfig -f cdimage.iso` /mnt</userinput></screen>
<para>Extract the binaries from the tarballs on the install media
into the declared destination. Minimally, only the base set
needs to be extracted, but a complete install can be performed
when preferred.</para>
<para>To install just the base system, run the next command when
using &os;&nbsp;9.x or newer:</para>
<screen>&prompt.root; <userinput>tar -xf /mnt/freebsd_install/usr/freebsd_dist/base.txz -C $DESTDIR</userinput></screen>
<para>On &os; 8.x systems, use this command instead:</para>
<screen>&prompt.root; <userinput>/mnt/8.<replaceable>4</replaceable>-RELEASE/base/install.sh</userinput></screen>
<para>To install everything but the kernel, issue this
command:</para>
<para>When using &man.sh.1; on &os;&nbsp;9.x and newer, issue this
command:</para>
<screen>&prompt.root; <userinput>for <replaceable>sets</replaceable> in BASE DOC GAMES PORTS; do (tar -xf /mnt/FREEBSD_INSTALL/USR/FREEBSD_DIST/$<replaceable>sets</replaceable>.TXZ -C $DESTDIR</userinput></screen>
<para>When using &os;&nbsp;8.x, run this:</para>
<screen>&prompt.root; <userinput>cd /mnt/8.<replaceable>4</replaceable>-RELEASE; for <replaceable>dir</replaceable> in base catpages dict doc games info manpages ports; do (cd $<replaceable>dir</replaceable>; ./install.sh) ; done</userinput></screen>
<para>If <command>csh</command>/<command>tcsh</command> is used on
&os; 9.x and newer, execute this command:</para>
<screen>&prompt.root; <userinput>foreach <replaceable>sets</replaceable> ( BASE DOC GAMES PORTS )
tar -xf /mnt/FREEBSD_INSTALL/USR/FREEBSD_DIST/$sets.TXZ -C $DESTDIR
done</userinput></screen>
<para>On &os;&nbsp;8.x, run this command:</para>
<screen>&prompt.root; <userinput>foreach <replaceable>dir</replaceable> ( base catpages dict doc games info manpages ports )
cd /mnt/8.<replaceable>4</replaceable>-RELEASE/$dir; ./install.sh
done</userinput></screen>
<para>The &man.jail.8; manual page explains the procedure for
building a jail:</para>
<screen>&prompt.root; <userinput>setenv D <replaceable>/here/is/the/jail</replaceable></userinput>
&prompt.root; <userinput>mkdir -p $D</userinput> <co xml:id="jailpath"/>
&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>make buildworld</userinput> <co xml:id="jailbuildworld"/>
&prompt.root; <userinput>make installworld DESTDIR=$D</userinput> <co xml:id="jailinstallworld"/>
&prompt.root; <userinput>make distribution DESTDIR=$D</userinput> <co xml:id="jaildistrib"/>
&prompt.root; <userinput>mount -t devfs devfs $D/dev</userinput> <co xml:id="jaildevfs"/></screen>
<calloutlist>
<callout arearefs="jailpath">
<para>Selecting a location for a jail is the best starting
point. This is where the jail will physically reside within
the file system of the jail's host. A good choice can be
<filename
class="directory">/usr/jail/<replaceable>jailname</replaceable></filename>,
where <replaceable>jailname</replaceable> is the hostname
identifying the jail. The
<filename class="directory">/usr/</filename> file system
usually has enough space for the jail file system, which for
<quote>complete</quote> jails is, essentially, a replication
of every file present in a default installation of the &os;
base system.</para>
</callout>
<callout arearefs="jailbuildworld">
<para>If you have already rebuilt your userland using
<command>make world</command> or
<command>make buildworld</command>, you can skip this step
and install your existing userland into the new jail.</para>
</callout>
<callout arearefs="jailinstallworld">
<para>This command will populate the directory subtree chosen
as jail's physical location on the file system with the
necessary binaries, libraries, manual pages and so
on.</para>
</callout>
<callout arearefs="jaildistrib">
<para>The <buildtarget>distribution</buildtarget> target for
<application>make</application> installs every needed
configuration file. In simple words, it installs every
installable file of
<filename class="directory">/usr/src/etc/</filename> to the
<filename class="directory">/etc</filename> directory of the
jail environment:
<filename class="directory">$D/etc/</filename>.</para>
</callout>
<callout arearefs="jaildevfs">
<para>Mounting the &man.devfs.8; file system inside a jail is
not required. On the other hand, any, or almost any
application requires access to at least one device,
depending on the purpose of the given application. It is
very important to control access to devices from inside a
jail, as improper settings could permit an attacker to do
nasty things in the jail. Control over &man.devfs.8; is
managed through rulesets which are described in the
&man.devfs.8; and &man.devfs.conf.5; manual pages.</para>
</callout>
</calloutlist>
<para>Once a jail is installed, it can be started by using the
&man.jail.8; utility. The &man.jail.8; utility takes four
mandatory arguments which are described in the <xref
linkend="jails-synopsis"/>. Other arguments may be specified
too, e.g., to run the jailed process with the credentials of a
specific user. The
<option><replaceable>command</replaceable></option> argument
depends on the type of the jail; for a
<emphasis>virtual system</emphasis>,
<filename>/etc/rc</filename> is a good choice, since it will
replicate the startup sequence of a real &os; system. For a
<emphasis>service</emphasis> jail, it depends on the service or
application that will run within the jail.</para>
<para>Jails are often started at boot time and the &os;
<filename>rc</filename> mechanism provides an easy way to do
this.</para>
<procedure>
<step>
<para>A list of the jails which are enabled to start at boot
time should be added to the &man.rc.conf.5; file:</para>
<programlisting>jail_enable="YES" # Set to NO to disable starting of any jails
jail_list="<replaceable>www</replaceable>" # Space separated list of names of jails</programlisting>
<note>
<para>Jail names in <varname>jail_list</varname> should
contain alphanumeric characters only.</para>
</note>
</step>
<step>
<para>For each jail listed in <varname>jail_list</varname>, a
group of &man.rc.conf.5; settings, which describe the
particular jail, should be added:</para>
<programlisting>jail_<replaceable>www</replaceable>_rootdir="/usr/jail/www" # jail's root directory
jail_<replaceable>www</replaceable>_hostname="<replaceable>www</replaceable>.example.org" # jail's hostname
jail_<replaceable>www</replaceable>_ip="192.168.0.10" # jail's IP address
jail_<replaceable>www</replaceable>_devfs_enable="YES" # mount devfs in the jail</programlisting>
<para>The default startup of jails configured in
&man.rc.conf.5;, will run the <filename>/etc/rc</filename>
script of the jail, which assumes the jail is a complete
virtual system. For service jails, the default startup
command of the jail should be changed, by setting the
<varname>jail_<replaceable>jailname</replaceable>_exec_start</varname>
option appropriately.</para>
<note>
<para>For a full list of available options, please see the
&man.rc.conf.5; manual page.</para>
</note>
</step>
</procedure>
<para>&man.service.8; can be used to start or stop a jail by hand,
if an entry for it exists in
<filename>rc.conf</filename>:</para>
<screen>&prompt.root; <userinput>service jail start <replaceable>www</replaceable></userinput>
&prompt.root; <userinput>service jail stop <replaceable>www</replaceable></userinput></screen>
<para>A clean way to shut down a &man.jail.8; is not available at
the moment. This is because commands normally used to
accomplish a clean system shutdown cannot be used inside a jail.
The best way to shut down a jail is to run the following command
from within the jail itself or using the &man.jexec.8; utility
from outside the jail:</para>
<screen>&prompt.root; <userinput>sh /etc/rc.shutdown</userinput></screen>
<para>More information about this can be found in the &man.jail.8;
manual page.</para>
</sect1>
<sect1 xml:id="jails-tuning">
<title>Fine Tuning and Administration</title>
<para>There are several options which can be set for any jail, and
various ways of combining a host &os; system with jails, to
produce higher level applications. This section
presents:</para>
<itemizedlist>
<listitem>
<para>Some of the options available for tuning the behavior
and security restrictions implemented by a jail
installation.</para>
</listitem>
<listitem>
<para>Some of the high-level applications for jail management,
which are available through the &os; Ports Collection, and
can be used to implement overall jail-based
solutions.</para>
</listitem>
</itemizedlist>
<sect2 xml:id="jails-tuning-utilities">
<title>System Tools for Jail Tuning in &os;</title>
<para>Fine tuning of a jail's configuration is mostly done by
setting &man.sysctl.8; variables. A special subtree of sysctl
exists as a basis for organizing all the relevant options: the
<varname>security.jail.*</varname> hierarchy of &os; kernel
options. Here is a list of the main jail-related sysctls,
complete with their default value. Names should be
self-explanatory, but for more information about them, please
refer to the &man.jail.8; and &man.sysctl.8; manual
pages.</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>These variables can be used by the system administrator of
the <emphasis>host system</emphasis> to add or remove some of
the limitations imposed by default on the <systemitem
class="username">root</systemitem> user. Note that there
are some limitations which cannot be removed. The
<systemitem class="username">root</systemitem> user is not
allowed to mount or unmount file systems from within a
&man.jail.8;. The <systemitem
class="username">root</systemitem> inside a jail may not
load or unload &man.devfs.8; rulesets, set firewall rules, or
do many other administrative tasks which require modifications
of in-kernel data, such as setting the
<varname>securelevel</varname> of the kernel.</para>
<para>The base system of &os; contains a basic set of tools for
viewing information about the active jails, and attaching to a
jail to run administrative commands. The &man.jls.8; and
&man.jexec.8; commands are part of the base &os; system, and
can be used to perform the following simple tasks:</para>
<itemizedlist>
<listitem>
<para>Print a list of active jails and their corresponding
jail identifier (<acronym>JID</acronym>),
<acronym>IP</acronym> address, hostname and path.</para>
</listitem>
<listitem>
<para>Attach to a running jail, from its host system, and
run a command inside the jail or perform administrative
tasks inside the jail itself. This is especially useful
when the <systemitem class="username">root</systemitem>
user wants to cleanly shut down a jail. The &man.jexec.8;
utility can also be used to start a shell in a jail to do
administration in it; for example:</para>
<screen>&prompt.root; <userinput>jexec <replaceable>1</replaceable> tcsh</userinput></screen>
</listitem>
</itemizedlist>
</sect2>
<sect2 xml:id="jails-tuning-admintools">
<title>High-Level Administrative Tools in the &os; Ports
Collection</title>
<para>Among the many third-party utilities for jail
administration, one of the most complete and useful is
<package>sysutils/jailutils</package>. It is a set of small
applications that contribute to &man.jail.8; management.
Please refer to its web page for more information.</para>
</sect2>
<sect2 xml:id="jails-updating">
<title>Keeping Jails Patched and up to Date</title>
<para>Jails should be kept up to date from the host operating
system as attempting to patch userland from within the jail
may likely fail as the default behaviour in FreeBSD is to
disallow the use of &man.chflags.1; in a jail which prevents
the replacement of some files. It is possible to change this
behavior but it is recommended to use &man.freebsd-update.8;
to maintain jails instead. Use <option>-b</option> to specify
the path of the jail to be updated.</para>
<screen>&prompt.root; <userinput>freebsd-update -b <replaceable>/here/is/the/jail</replaceable> fetch</userinput>
&prompt.root; <userinput>freebsd-update -b <replaceable>/here/is/the/jail</replaceable> install</userinput></screen>
</sect2>
</sect1>
<sect1 xml:id="jails-application">
<info>
<title>Updating Multiple Jails</title>
<authorgroup>
<author>
<personname>
<firstname>Daniel</firstname>
<surname>Gerzo</surname>
</personname>
<contrib>Contributed by </contrib>
</author>
</authorgroup>
<authorgroup>
<author>
<personname>
<firstname>Simon</firstname>
<surname>L. B. Nielsen</surname>
</personname>
<contrib>Based upon an idea presented by </contrib>
</author>
</authorgroup>
<authorgroup>
<author>
<personname>
<firstname>Ken</firstname>
<surname>Tom</surname>
</personname>
<contrib>And an article written by </contrib>
</author>
</authorgroup>
</info>
<para>The management of multiple jails can become problematic
because every jail has to be rebuilt from scratch whenever it is
upgraded. This can be time consuming and tedious if a lot of
jails are created and manually updated.</para>
<para>This section demonstrates one method to resolve this issue
by safely sharing as much as is possible between jails using
read-only &man.mount.nullfs.8; mounts, so that updating is
simpler. This makes it more attractive to put single services,
such as <acronym>HTTP</acronym>, <acronym>DNS</acronym>, and
<acronym>SMTP</acronym>, into individual jails. Additionally,
it provides a simple way to add, remove, and upgrade
jails.</para>
<note>
<para>Simpler solutions exist, such as
<application>ezjail</application>, which provides an easier
method of administering &os; jails but is less versatile than
this setup. <application>ezjail</application> is covered in
more detail in <xref linkend="jails-ezjail"/>.</para>
</note>
<para>The goals of the setup described in this section are:</para>
<itemizedlist>
<listitem>
<para>Create a simple and easy to understand jail structure
that does not require running a full installworld on each
and every jail.</para>
</listitem>
<listitem>
<para>Make it easy to add new jails or remove existing
ones.</para>
</listitem>
<listitem>
<para>Make it easy to update or upgrade existing jails.</para>
</listitem>
<listitem>
<para>Make it possible to run a customized &os; branch.</para>
</listitem>
<listitem>
<para>Be paranoid about security, reducing as much as
possible the possibility of compromise.</para>
</listitem>
<listitem>
<para>Save space and inodes, as much as possible.</para>
</listitem>
</itemizedlist>
<para>This design relies on a single, read-only master template
which is 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 memory device. This example uses read-write
<application>nullfs</application> mounts.</para>
<para>The file system layout is as follows:</para>
<itemizedlist>
<listitem>
<para>The jails are based under the
<filename>/home</filename> partition.</para>
</listitem>
<listitem>
<para>Each jail will be mounted under the
<filename>/home/j</filename> directory.</para>
</listitem>
<listitem>
<para>The template for each jail and the read-only partition
for all of the jails is
<filename>/home/j/mroot</filename>.</para>
</listitem>
<listitem>
<para>A blank directory will be created for each jail under
the <filename>/home/j</filename> directory.</para>
</listitem>
<listitem>
<para>Each jail will have a <filename>/s</filename> directory
that will be linked to the read-write portion of the
system.</para>
</listitem>
<listitem>
<para>Each jail will have its own read-write system that is
based upon <filename>/home/j/skel</filename>.</para>
</listitem>
<listitem>
<para>The read-write portion of each jail will be created in
<filename>/home/js</filename>.</para>
</listitem>
</itemizedlist>
<!-- Insert an image or drawing here to illustrate the example. -->
<sect2 xml:id="jails-service-jails-template">
<title>Creating the Template</title>
<para>This section describes the steps needed to create the
master template.</para>
<para>It is recommended to first update the host &os; system to
the latest -RELEASE branch using the instructions in <xref
linkend="makeworld"/>. Additionally, this template uses the
<package>sysutils/cpdup</package> package or port and
<application>portsnap</application> will be used to download
the &os; Ports Collection.</para>
<procedure>
<step>
<para>First, create a directory structure for the read-only
file system which will contain the &os; binaries for the
jails. Then, change directory to the &os; source tree and
install the read-only file system to the jail
template:</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>Next, prepare a &os; Ports Collection for the jails as
well as a &os; source tree, which is required for
<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>Create a skeleton for the read-write portion of the
system:</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>Use <application>mergemaster</application> to install
missing configuration files. Then, remove the extra
directories that <application>mergemaster</application>
creates:</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>Now, symlink the read-write file system to the
read-only file system. Ensure that the symlinks are
created in the correct <filename>s/</filename> locations
as the creation of directories in the wrong locations will
cause the installation to fail.</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>As a last step, create a generic
<filename>/home/j/skel/etc/make.conf</filename> containing
this line:</para>
<programlisting>WRKDIRPREFIX?= /s/portbuild</programlisting>
<para>This makes it possible to compile &os; ports inside
each jail. Remember that the ports directory is part of
the read-only system. The custom path for
<literal>WRKDIRPREFIX</literal> allows builds to be done
in the read-write portion of every jail.</para>
</step>
</procedure>
</sect2>
<sect2 xml:id="jails-service-jails-creating">
<title>Creating Jails</title>
<para>The jail template can now be used to setup and configure
the jails in <filename>/etc/rc.conf</filename>. This example
demonstrates the creation of 3 jails: <literal>NS</literal>,
<literal>MAIL</literal> and <literal>WWW</literal>.</para>
<procedure>
<step>
<para>Add the following lines to
<filename>/etc/fstab</filename>, so that the read-only
template for the jails and the read-write space will be
available in the respective jails:</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>
<para>To prevent
<application>fsck</application> from checking
<application>nullfs</application> mounts during boot and
<application>dump</application> from backing up the
read-only nullfs mounts of the jails, the last two
columns are both set to <literal>0</literal>.</para>
</step>
<step>
<para>Configure the jails in
<filename>/etc/rc.conf</filename>:</para>
<programlisting>jail_enable="YES"
jail_set_hostname_allow="NO"
jail_list="ns mail www"
jail_ns_hostname="ns.example.org"
jail_ns_ip="192.168.3.17"
jail_ns_rootdir="/usr/home/j/ns"
jail_ns_devfs_enable="YES"
jail_mail_hostname="mail.example.org"
jail_mail_ip="192.168.3.18"
jail_mail_rootdir="/usr/home/j/mail"
jail_mail_devfs_enable="YES"
jail_www_hostname="www.example.org"
jail_www_ip="62.123.43.14"
jail_www_rootdir="/usr/home/j/www"
jail_www_devfs_enable="YES"</programlisting>
<para>The
<varname>jail_<replaceable>name</replaceable>_rootdir</varname>
variable is set to
<filename class="directory">/usr/home</filename> instead
of <filename class="directory">/home</filename> because
the physical path of <filename
class="directory">/home</filename> on a default &os;
installation is <filename
class="directory">/usr/home</filename>. The
<varname>jail_<replaceable>name</replaceable>_rootdir</varname>
variable must <emphasis>not</emphasis> be set to a path
which includes a symbolic link, otherwise the jails will
refuse to start.</para>
</step>
<step>
<para>Create the required mount points for the read-only
file system of each jail:</para>
<screen>&prompt.root; <userinput>mkdir /home/j/ns /home/j/mail /home/j/www</userinput></screen>
</step>
<step>
<para>Install the read-write template into each jail using
<package>sysutils/cpdup</package>:</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>In this phase, the jails are built and prepared to
run. First, mount the required file systems for each
jail, and then start them:</para>
<screen>&prompt.root; <userinput>mount -a</userinput>
&prompt.root; <userinput>service jail start</userinput></screen>
</step>
</procedure>
<para>The jails should be running now. To check if they have
started correctly, use <command>jls</command>. Its output
should be similar to the following:</para>
<screen>&prompt.root; <userinput>jls</userinput>
JID IP Address Hostname Path
3 192.168.3.17 ns.example.org /home/j/ns
2 192.168.3.18 mail.example.org /home/j/mail
1 62.123.43.14 www.example.org /home/j/www</screen>
<para>At this point, it should be possible to log onto each
jail, add new users, or configure daemons. The
<literal>JID</literal> column indicates the jail
identification number of each running jail. Use the following
command to perform administrative tasks in the jail whose
<acronym>JID</acronym> is <literal>3</literal>:</para>
<screen>&prompt.root; <userinput>jexec 3 tcsh</userinput></screen>
</sect2>
<sect2 xml:id="jails-service-jails-upgrading">
<title>Upgrading</title>
<para>The design of this setup provides an easy way to upgrade
existing jails while minimizing their downtime. Also, it
provides a way to roll back to the older version should a
problem occur.</para>
<procedure>
<step>
<para>The first step is to upgrade the host system. Then,
create a new temporary read-only template in
<filename>/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>The <buildtarget>installworld</buildtarget> creates a
few unnecessary directories, which should be
removed:</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>Recreate the read-write symlinks for the master file
system:</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>Next, stop the jails:</para>
<screen>&prompt.root; <userinput>service jail stop</userinput></screen>
</step>
<step>
<para>Unmount the original file systems as the read-write
systems are attached to the read-only system
(<filename>/s</filename>):</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>
</step>
<step>
<para>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
&os; Ports Collection over to the new file system to save
some space and inodes:</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>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:</para>
<screen>&prompt.root; <userinput>mount -a</userinput>
&prompt.root; <userinput>service jail start</userinput></screen>
</step>
</procedure>
<para>Use <command>jls</command> to check if the jails started
correctly. Run <command>mergemaster</command> in each jail to
update the configuration files.</para>
</sect2>
</sect1>
<sect1 xml:id="jails-ezjail">
<info>
<title>Managing Jails with
<application>ezjail</application></title>
<authorgroup>
<author>
<personname>
<firstname>Warren</firstname>
<surname>Block</surname>
</personname><contrib>Originally contributed by </contrib>
</author>
</authorgroup>
</info>
<para>Creating and managing multiple jails can quickly become
tedious and error-prone. Dirk Engling's
<application>ezjail</application> automates and greatly
simplifies many jail tasks. A <emphasis>basejail</emphasis> is
created as a template. Additional jails use &man.mount.nullfs.8;
to share many of the basejail directories without using
additional disk space. Each additional jail takes only a few
megabytes of disk space before applications are installed.
Upgrading the copy of the userland in the basejail automatically
upgrades all of the other jails.</para>
<para>Additional benefits and features are described in detail on
the <application>ezjail</application> web site, <link
xlink:href="https://erdgeist.org/arts/software/ezjail/"></link>.</para>
<sect2 xml:id="jails-ezjail-install">
<title>Installing <application>ezjail</application></title>
<para>Installing <application>ezjail</application> consists of
adding a loopback interface for use in jails, installing the
port or package, and enabling the service.</para>
<procedure xml:id="jails-ezjail-install-procedure">
<step>
<para>To keep jail loopback traffic off the host's loopback
network interface <literal>lo0</literal>, a second
loopback interface is created by adding an entry to
<filename>/etc/rc.conf</filename>:</para>
<programlisting>cloned_interfaces="${cloned_interfaces} lo1"</programlisting>
<para>The second loopback interface <literal>lo1</literal>
will be created when the system starts. It can also be
created manually without a restart:</para>
<screen>&prompt.root; <userinput>service netif cloneup</userinput>
Created clone interfaces: lo1.</screen>
<para>Jails can be allowed to use aliases of this secondary
loopback interface without interfering with the
host.</para>
<para>Inside a jail, access to the loopback address
<systemitem class="ipaddress">127.0.0.1</systemitem> is
redirected to the first <acronym>IP</acronym> address
assigned to the jail. To make the jail loopback
correspond with the new <literal>lo1</literal> interface,
that interface must be specified first in the list of
interfaces and <acronym>IP</acronym> addresses given when
creating a new jail.</para>
<para>Give each jail a unique loopback address in the
<systemitem
class="ipaddress">127.0.0.0</systemitem><systemitem
class="netmask">/8</systemitem> netblock.</para>
</step>
<step>
<para>Install
<package role="port">sysutils/ezjail</package>:</para>
<screen>&prompt.root; <userinput>cd /usr/ports/sysutils/ezjail</userinput>
&prompt.root; <userinput>make install clean</userinput></screen>
</step>
<step>
<para>Enable <application>ezjail</application> by adding
this line to <filename>/etc/rc.conf</filename>:</para>
<programlisting>ezjail_enable="YES"</programlisting>
</step>
<step>
<para>The service will automatically start on system boot.
It can be started immediately for the current
session:</para>
<screen>&prompt.root; <userinput>service ezjail start</userinput></screen>
</step>
</procedure>
</sect2>
<sect2 xml:id="jails-ezjail-initialsetup">
<title>Initial Setup</title>
<para>With <application>ezjail</application> installed, the
basejail directory structure can be created and populated.
This step is only needed once on the jail host
computer.</para>
<para>In both of these examples, <option>-p</option> causes the
ports tree to be retrieved with &man.portsnap.8; into the
basejail. That single copy of the ports directory will be
shared by all the jails. Using a separate copy of the ports
directory for jails isolates them from the host. The
<application>ezjail</application> <acronym>FAQ</acronym>
explains in more detail: <link
xlink:href="http://erdgeist.org/arts/software/ezjail/#FAQ"></link>.</para>
<procedure xml:id="jails-ezjail-initialsetup-procedure">
<step>
<stepalternatives>
<step>
<title>To Populate the Jail with &os;-RELEASE</title>
<para>For a basejail based on the &os; RELEASE matching
that of the host computer, use
<command>install</command>. For example, on a host
computer running &os;&nbsp;10-STABLE, the latest
RELEASE version of &os;&nbsp;-10 will be installed in
the jail):</para>
<screen>&prompt.root; <userinput>ezjail-admin install -p</userinput></screen>
</step>
<step>
<title>To Populate the Jail with
<command>installworld</command></title>
<para>The basejail can be installed from binaries
created by <buildtarget>buildworld</buildtarget> on
the host with
<command>ezjail-admin update</command>.</para>
<para>In this example, &os;&nbsp;10-STABLE has been
built from source. The jail directories are created.
Then <buildtarget>installworld</buildtarget> is
executed, installing the host's
<filename>/usr/obj</filename> into the
basejail.</para>
<screen>&prompt.root; <userinput>ezjail-admin update -i -p</userinput></screen>
<para>The host's <filename>/usr/src</filename> is used
by default. A different source directory on the host
can be specified with <option>-s</option> and a path,
or set with <varname>ezjail_sourcetree</varname> in
<filename>/usr/local/etc/ezjail.conf</filename>.</para>
</step>
</stepalternatives>
</step>
</procedure>
<tip>
<para>The basejail's ports tree is shared by other jails.
However, downloaded distfiles are stored in the jail that
downloaded them. By default, these files are stored in
<filename>/var/ports/distfiles</filename> within each
jail. <filename>/var/ports</filename> inside each jail is
also used as a work directory when building ports.</para>
</tip>
</sect2>
<sect2 xml:id="jails-ezjail-create">
<title>Creating and Starting a New Jail</title>
<para>New jails are created with
<command>ezjail-admin create</command>. In these examples,
the <literal>lo1</literal> loopback interface is used as
described above.</para>
<procedure xml:id="jails-ezjail-create-steps">
<title>Create and Start a New Jail</title>
<step>
<para>Create the jail, specifying a name and the loopback
and network interfaces to use, along with their
<acronym>IP</acronym> addresses. In this example, the
jail is named <literal>dnsjail</literal>.</para>
<screen>&prompt.root; <userinput>ezjail-admin create <replaceable>dnsjail</replaceable> '<replaceable>lo1|127.0.1.1</replaceable>,<replaceable>em0</replaceable>|<replaceable>192.168.1.50</replaceable>'</userinput></screen>
<tip xml:id="jails-ezjail-raw-network-sockets">
<para>Most network services run in jails without
problems. A few network services, most notably
&man.ping.8;, use
<emphasis>raw network sockets</emphasis>. In jails, raw
network sockets are disabled by default for security.
Services that require them will not work.</para>
<para>Occasionally, a jail genuinely needs raw sockets.
For example, network monitoring applications often use
&man.ping.8; to check the availability of other
computers. When raw network sockets are actually needed
in a jail, they can be enabled by editing the
<application>ezjail</application>
configuration file for the individual jail,
<filename>/usr/local/etc/ezjail/<replaceable>jailname</replaceable></filename>.
Modify the <literal>parameters</literal>
entry:</para>
<programlisting>export jail_<replaceable>jailname</replaceable>_parameters="allow.raw_sockets=1"</programlisting>
<para>Do not enable raw network sockets unless services in
the jail actually require them.</para>
</tip>
</step>
<step>
<para>Start the jail:</para>
<screen>&prompt.root; <userinput>ezjail-admin start <replaceable>dnsjail</replaceable></userinput></screen>
</step>
<step>
<para>Use a console on the jail:</para>
<screen>&prompt.root; <userinput>ezjail-admin console <replaceable>dnsjail</replaceable></userinput></screen>
</step>
</procedure>
<para>The jail is operating and additional configuration can be
completed. Typical settings added at this point
include:</para>
<procedure>
<step>
<title>Set the
<systemitem class="username">root</systemitem>
Password</title>
<para>Connect to the jail and set the
<systemitem class="username">root</systemitem> user's
password:</para>
<screen>&prompt.root; <userinput>ezjail-admin console <replaceable>dnsjail</replaceable></userinput>
&prompt.root; <userinput>passwd</userinput>
Changing local password for root
New Password:
Retype New Password:</screen>
</step>
<step>
<title>Time Zone Configuration</title>
<para>The jail's time zone can be set with &man.tzsetup.8;.
To avoid spurious error messages, the &man.adjkerntz.8;
entry in <filename>/etc/crontab</filename> can be
commented or removed. This job attempts to update the
computer's hardware clock with time zone changes, but
jails are not allowed to access that hardware.</para>
</step>
<step>
<title><acronym>DNS</acronym> Servers</title>
<para>Enter domain name server lines in
<filename>/etc/resolv.conf</filename> so
<acronym>DNS</acronym> works in the jail.</para>
</step>
<step>
<title>Edit <filename>/etc/hosts</filename></title>
<para>Change the address and add the jail name to the
<literal>localhost</literal> entries in
<filename>/etc/hosts</filename>.</para>
</step>
<step>
<title>Configure <filename>/etc/rc.conf</filename></title>
<para>Enter configuration settings in
<filename>/etc/rc.conf</filename>. This is much like
configuring a full computer. The host name and
<acronym>IP</acronym> address are not set here. Those
values are already provided by the jail
configuration.</para>
</step>
</procedure>
<para>With the jail configured, the applications for which the
jail was created can be installed.</para>
<tip>
<para>Some ports must be built with special options to be used
in a jail. For example, both of the network monitoring
plugin packages
<package role="port">net-mgmt/nagios-plugins</package> and
<package role="port">net-mgmt/monitoring-plugins</package>
have a <literal>JAIL</literal> option which must be enabled
for them to work correctly inside a jail.</para>
</tip>
</sect2>
<sect2 xml:id="jails-ezjail-update">
<title>Updating Jails</title>
<sect3 xml:id="jails-ezjail-update-os">
<title>Updating the Operating System</title>
<para>Because the basejail's copy of the userland is shared by
the other jails, updating the basejail automatically updates
all of the other jails. Either source or binary updates can
be used.</para>
<para>To build the world from source on the host, then
install it in the basejail, use:</para>
<screen>&prompt.root; <userinput>ezjail-admin update -b</userinput></screen>
<para>If the world has already been compiled on the host,
install it in the basejail with:</para>
<screen>&prompt.root; <userinput>ezjail-admin update -i</userinput></screen>
<para>Binary updates use &man.freebsd-update.8;. These
updates have the same limitations as if
&man.freebsd-update.8; were being run directly. The most
important one is that only -RELEASE versions of &os; are
available with this method. To update the basejail to the
latest patched release of the version of &os; on the host
computer, use:</para>
<screen>&prompt.root; <userinput>ezjail-admin update -r</userinput></screen>
<para>After updating the basejail, &man.mergemaster.8; can be
run to update each jail's configuration files.</para>
<para>How to use &man.mergemaster.8; depends on the purpose
and trustworthiness of a jail. If a jail's services or
users are not trusted, then &man.mergemaster.8; should only
be run from within that jail:</para>
<example xml:id="jails-ezjail-update-mergemaster-untrusted">
<title>&man.mergemaster.8; on Untrusted Jail</title>
<para>Delete the link from the jail's
<filename>/usr/src</filename> into the basejail and
create a new <filename>/usr/src</filename> in the jail
as a mountpoint. Mount the host computer's
<filename>/usr/src</filename> read-only on the jail's
new <filename>/usr/src</filename> mountpoint:</para>
<screen>&prompt.root; <userinput>rm /usr/jails/<replaceable>jailname</replaceable>/usr/src</userinput>
&prompt.root; <userinput>mkdir /usr/jails/<replaceable>jailname</replaceable>/usr/src</userinput>
&prompt.root; <userinput>mount -t nullfs -o ro /usr/src /usr/jails/<replaceable>jailname</replaceable>/usr/src</userinput></screen>
<para>Get a console in the jail:</para>
<screen>&prompt.root; <userinput>ezjail-admin console <replaceable>jailname</replaceable></userinput></screen>
<para>Inside the jail, run <command>mergemaster</command>.
Then exit the jail console:</para>
<screen>&prompt.root; <userinput>cd /usr/src</userinput>
&prompt.root; <userinput>mergemaster -U</userinput>
&prompt.root; <userinput>exit</userinput></screen>
<para>Finally, unmount the jail's
<filename>/usr/src</filename>:</para>
<screen>&prompt.root; <userinput>umount /usr/jails/<replaceable>jailname</replaceable>/usr/src</userinput></screen>
</example>
<example xml:id="jails-ezjail-update-mergemaster-trusted">
<title>&man.mergemaster.8; on Trusted Jail</title>
<para>If the users and services in a jail are trusted,
&man.mergemaster.8; can be run from the host:</para>
<screen>&prompt.root; <userinput>mergemaster -U -D /usr/jails/<replaceable>jailname</replaceable></userinput></screen>
</example>
</sect3>
<sect3 xml:id="jails-ezjail-update-ports">
<title>Updating Ports</title>
<para>The ports tree in the basejail is shared by the other
jails. Updating that copy of the ports tree gives the other
jails the updated version also.</para>
<para>The basejail ports tree is updated with
&man.portsnap.8;:</para>
<screen>&prompt.root; <userinput>ezjail-admin update -P</userinput></screen>
</sect3>
</sect2>
<sect2 xml:id="jails-ezjail-control">
<title>Controlling Jails</title>
<sect3 xml:id="jails-ezjail-control-stop-start">
<title>Stopping and Starting Jails</title>
<para><application>ezjail</application> automatically starts
jails when the computer is started. Jails can be manually
stopped and restarted with <command>stop</command> and
<command>start</command>:</para>
<screen>&prompt.root; <userinput>ezjail-admin stop <replaceable>sambajail</replaceable></userinput>
Stopping jails: sambajail.</screen>
<para>By default, jails are started automatically when the
host computer starts. Autostarting can be disabled
with <command>config</command>:</para>
<screen>&prompt.root; <userinput>ezjail-admin config -r norun <replaceable>seldomjail</replaceable></userinput></screen>
<para>This takes effect the next time the host computer is
started. A jail that is already running will not be
stopped.</para>
<para>Enabling autostart is very similar:</para>
<screen>&prompt.root; <userinput>ezjail-admin config -r run <replaceable>oftenjail</replaceable></userinput></screen>
</sect3>
<sect3 xml:id="jails-ezjail-control-backup">
<title>Archiving and Restoring Jails</title>
<para>Use <command>archive</command> to create a
<filename>.tar.gz</filename> archive of a jail. The file
name is composed from the name of the jail and the current
date. Archive files are written to the archive directory,
<filename>/usr/jails/ezjail_archives</filename>. A
different archive directory can be chosen by setting
<varname>ezjail_archivedir</varname> in the configuration
file.</para>
<para>The archive file can be copied elsewhere as a backup, or
an existing jail can be restored from it with
<command>restore</command>. A new jail can be created from
the archive, providing a convenient way to clone existing
jails.</para>
<para>Stop and archive a jail named
<literal>wwwserver</literal>:</para>
<screen>&prompt.root; <userinput>ezjail-admin stop <replaceable>wwwserver</replaceable></userinput>
Stopping jails: wwwserver.
&prompt.root; <userinput>ezjail-admin archive <replaceable>wwwserver</replaceable></userinput>
&prompt.root; <userinput>ls /usr/jails/ezjail-archives/</userinput>
wwwserver-201407271153.13.tar.gz</screen>
<para>Create a new jail named
<literal>wwwserver-clone</literal> from the archive created
in the previous step. Use the <filename>em1</filename>
interface and assign a new <acronym>IP</acronym> address to
avoid conflict with the original:</para>
<screen>&prompt.root; <userinput>ezjail-admin create -a /usr/jails/ezjail_archives/wwwserver-201407271153.13.tar.gz <replaceable>wwwserver-clone</replaceable> 'lo1|127.0.3.1,em1|192.168.1.51'</userinput></screen>
</sect3>
</sect2>
<sect2 xml:id="jails-ezjail-example-bind">
<title>Full Example: <application>BIND</application> in a
Jail</title>
<para>Putting the <application>BIND</application>
<acronym>DNS</acronym> server in a jail improves security by
isolating it. This example creates a simple caching-only name
server.</para>
<itemizedlist xml:id="jails-ezjail-example-bind-assumptions">
<listitem>
<para>The jail will be called
<literal>dns1</literal>.</para>
</listitem>
<listitem>
<para>The jail will use <acronym>IP</acronym> address
<literal>192.168.1.240</literal> on the host's
<literal>re0</literal> interface.</para>
</listitem>
<listitem>
<para>The upstream <acronym>ISP</acronym>'s DNS servers are
at <literal>10.0.0.62</literal> and
<literal>10.0.0.61</literal>.</para>
</listitem>
<listitem>
<para>The basejail has already been created and a ports tree
installed.</para>
</listitem>
</itemizedlist>
<example xml:id="jails-ezjail-example-bind-steps">
<para>Create a cloned loopback interface by adding a line to
<filename>/etc/rc.conf</filename>:</para>
<programlisting>cloned_interfaces="${cloned_interfaces} lo1"</programlisting>
<para>Immediately create the new loopback interface:</para>
<screen>&prompt.root; <userinput>service netif cloneup</userinput>
Created clone interfaces: lo1.</screen>
<para>Create the jail:</para>
<screen>&prompt.root; <userinput>ezjail-admin create dns1 'lo1|127.0.2.1,re0|192.168.1.240'</userinput></screen>
<para>Start the jail, connect to a console running on it, and
perform some basic configuration:</para>
<screen>&prompt.root; <userinput>ezjail-admin start dns1</userinput>
&prompt.root; <userinput>ezjail-admin console dns1</userinput>
&prompt.root; <userinput>passwd</userinput>
Changing local password for root
New Password:
Retype New Password:
&prompt.root; <userinput>tzsetup</userinput>
&prompt.root; <userinput>sed -i .bak -e '/adjkerntz/ s/^/#/' /etc/crontab</userinput>
&prompt.root; <userinput>sed -i .bak -e 's/127.0.0.1/127.0.2.1/g; s/localhost.my.domain/dns1.my.domain dns1/' /etc/hosts</userinput></screen>
<para>Temporarily set the upstream <acronym>DNS</acronym>
servers in <filename>/etc/resolv.conf</filename> so ports
can be downloaded:</para>
<programlisting>nameserver 10.0.0.62
nameserver 10.0.0.61</programlisting>
<para>Still using the jail console, install
<package role="port">dns/bind99</package>.</para>
<screen>&prompt.root; <userinput>cd /usr/ports/dns/bind99</userinput>
&prompt.root; <userinput>make -C /usr/ports/dns/bind99 install clean</userinput></screen>
<para>Configure the name server by editing
<filename>/usr/local/etc/namedb/named.conf</filename>.</para>
<para>Create an Access Control List (<acronym>ACL</acronym>)
of addresses and networks that are permitted to send
<acronym>DNS</acronym> queries to this name server. This
section is added just before the <literal>options</literal>
section already in the file:</para>
<programlisting>...
// or cause huge amounts of useless Internet traffic.
acl "trusted" {
192.168.1.0/24;
localhost;
localnets;
};
options {
...</programlisting>
<para>Use the jail <acronym>IP</acronym> address in the
<literal>listen-on</literal> setting to accept
<acronym>DNS</acronym> queries from other computers on the
network:</para>
<programlisting> listen-on { 192.168.1.240; };</programlisting>
<para>A simple caching-only <acronym>DNS</acronym> name server
is created by changing the <literal>forwarders</literal>
section. The original file contains:</para>
<programlisting>/*
forwarders {
127.0.0.1;
};
*/</programlisting>
<para>Uncomment the section by removing the
<literal>/*</literal> and <literal>*/</literal> lines.
Enter the <acronym>IP</acronym> addresses of the upstream
<acronym>DNS</acronym> servers. Immediately after the
<literal>forwarders</literal> section, add references to the
<literal>trusted</literal> <acronym>ACL</acronym> defined
earlier:</para>
<programlisting> forwarders {
10.0.0.62;
10.0.0.61;
};
allow-query { any; };
allow-recursion { trusted; };
allow-query-cache { trusted; };</programlisting>
<para>Enable the service in
<filename>/etc/rc.conf</filename>:</para>
<programlisting>named_enable="YES"</programlisting>
<para>Start and test the name server:</para>
<screen>&prompt.root; <userinput>service named start</userinput>
wrote key file "/usr/local/etc/namedb/rndc.key"
Starting named.
&prompt.root; <userinput>/usr/local/bin/dig @192.168.1.240 freebsd.org</userinput></screen>
<para>A response that includes</para>
<screen>;; Got answer;</screen>
<para>shows that the new <acronym>DNS</acronym> server is
working. A long delay followed by a response
including</para>
<screen>;; connection timed out; no servers could be reached</screen>
<para>shows a problem. Check the configuration settings and
make sure any local firewalls allow the new
<acronym>DNS</acronym> access to the upstream
<acronym>DNS</acronym> servers.</para>
<para>The new <acronym>DNS</acronym> server can use itself for
local name resolution, just like other local computers. Set
the address of the <acronym>DNS</acronym> server in the
client computer's
<filename>/etc/resolv.conf</filename>:</para>
<programlisting>nameserver 192.168.1.240</programlisting>
<para>A local <acronym>DHCP</acronym> server can be configured
to provide this address for a local <acronym>DNS</acronym>
server, providing automatic configuration on
<acronym>DHCP</acronym> clients.</para>
</example>
</sect2>
</sect1>
</chapter>