DragonFly BSD

Jails

Contributed by Matteo Riondato. Updated for DragonFly by Dario Banno.

Synopsis

This chapter will provide an explanation of what DragonFly jails are and how to use them. Jails, sometimes referred to as an enhanced replacement of chroot environments, are a very powerful tool for system administrators, but their basic usage can also be useful for advanced users.

After reading this chapter, you will know:


Other sources of useful information about jails are:



For information on how to setup a jail, see: Setting up a jail


Terms Related to Jails

To facilitate better understanding of parts of the DragonFly system related to jails, their internals and the way they interact with the rest of DragonFly, the following terms are used further in this chapter:

chroot(8) (command)

A system call of DragonFly, which changes the root directory of a process and all its descendants.


chroot(2) (environment)

The environment of processes running in a “chroot”. 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.


* jail(8) (command)*

The system administration utility which allows launching of processes within a jail environment.


host (system, process, user, etc.)

The controlling system of a jail environment. The host system has access to all the hardware resources available, and can control processes both outside and inside of 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 on the host system processes.


hosted (system, process, user, etc.)

A process, user or other entity, whose access to resources is restricted by a DragonFly jail.


Introduction

Since system administration is a difficult and perplexing task, many powerful tools were developed to make life easier for the administrator. These tools mostly provide enhancements of some sort to the way systems are installed, configured and maintained. One of the tasks an administrator is expected to do is to properly configure the security of a system, so that it can continue serving its real purpose free of security violations.


One of the tools which can be used to enhance the security of a DragonFly system are jails. The jail feature was written by Poul-Henning Kamp phk@freebsd.org for R&D Associates http://www.rndassociates.com/ who contributed it to FreeBSD 4.X. Support for multiple IPs and IPv6 were introduced in DragonFly 1.7. Their development still goes on, enhancing their usefulness, performance, reliability, and security.

What is a Jail

BSD-like operating systems have had chroot(2) since the time of 4.2BSD. The chroot(8) utility can be 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. The chroot(8) utility is good for easy tasks, which do not require a lot of flexibility or complex and advanced features. Since the inception of the chroot concept, however, many ways have been found to escape from a chrooted environment and, although they have been fixed in modern versions of the DragonFly kernel, it was clear that chroot(2) was not the ideal solution for securing services. A new subsystem had to be implemented.

This is one of the main reasons why jails were developed.

Jails improve on the concept of the traditional chroot(2) environment, in several ways. In a traditional chroot(2) environment, processes are only limited in the part of the file system they can access. The rest of the system resources (like the set of system users, the running processes, or the networking subsystem) are shared by the chrooted processes and the processes of the host system. Jails expand this model by virtualizing not only access to the file system, but also the set of users, the networking subsystem of the DragonFly kernel and a few other things. A more complete set of fine-grained controls available for tuning the access of a jailed environment is described in Section 12.5.


A jail is characterized by four elements:


Apart from these, jails can have their own set of users and their own root user. Naturally, the powers of the root user are limited within the jail environment and, from the point of view of the host system, the jail root user is not an omnipotent user. In addition, the root user of a jail is not allowed to perform critical operations to the system outside of the associated jail(8) environment. More information about capabilities and restrictions of the root user will be discussed in Section 12.5 below.


Creating and Controlling Jails

Some administrators divide jails into the following two types: complete jails, which resemble a real DragonFly system, and service 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. The jail(8) manual page is quite clear about the procedure for building a jail:

# setenv D /here/is/the/jail
# mkdir -p $D                                     (1)
# cd /usr/src
# make installworld DESTDIR=$D                    (2)
# cd etc 
# make distribution DESTDIR=$D                    (3)
# cd $D
# ln -sf dev/null kernel
# mount_devfs -o jail $D/dev
#

(1)

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 /usr/jail/jailname, where jailname is the hostname identifying the jail. The /usr/ file system usually has enough space for the jail file system, which for complete jails is, essentially, a replication of every file present in a default installation of the DragonFly base system.


(2)

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. Everything is done in the typical DragonFly style -- first everything is built/compiled, then installed to the destination path.


(3)

The distribution target for make installs every needed configuration file. In simple words, it installs every installable file of /usr/src/etc/ to the /etc directory of the jail environment: $D/etc/.


Once a jail is installed, it can be started by using the jail(8) utility. The jail(8) utility takes four mandatory arguments which are described in the Section 12.3.1. Other arguments may be specified too, e.g., to run the jailed process with the credentials of a specific user. The command argument depends on the type of the jail; for a virtual system, /etc/rc is a good choice, since it will replicate the startup sequence of a real DragonFly system. For a service jail, it depends on the service or application that will run within the jail.

Jails are often started at boot time and the DragonFly rc mechanism provides an easy way to do this.


A list of the jails which are enabled to start at boot time should be added to the rc.conf(5) file:

jail_enable="YES"   # Set to NO to disable starting of any jails
jail_list="www"     # Space separated list of names of jails
#

For each jail listed in jail_list, a group of rc.conf(5) settings, which describe the particular jail, should be added:

jail_www_rootdir="/usr/jail/www"     # jail's root directory
jail_www_hostname="www.example.org"  # jail's hostname
jail_www_ip="192.168.0.10"           # jail's IP address
#

The default startup of jails configured in rc.conf(5), will run the /etc/rc 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 jail_jailname_exec_start option appropriately.

Note: For a full list of available options, please see the rc.conf(5) manual page.

The /etc/rc.d/jail script can be used to start or stop a jail by hand, if an entry for it exists in rc.conf:

# /etc/rc.d/jail start www
# /etc/rc.d/jail stop www

A clean way to shut down a 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 jexec(8) utility from outside the jail:

# sh /etc/rc.shutdown

More information about this can be found in the jail(8) manual page.


Fine Tuning and Administration

There are several options which can be set for any jail, and various ways of combining a host DragonFly system with jails to produce higher level applications. This section presents some of the options available for tuning the behavior and security restrictions implemented by a jail installation.

System tools for jail tuning in DragonFly

Fine tuning of a jail's configuration is mostly done by setting sysctl(8) variables. A special subtree of sysctl exists as a basis for organizing all the relevant options: the securityjail* hierarchy of DragonFly 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 jail(8) and sysctl(8) manual pages.

These variables can be used by the system administrator of the host system to add or remove some of the limitations imposed by default on the root user. Note that there are some limitations which cannot be removed. The root user is not allowed to mount or unmount file systems from within a jail(8). The root inside a jail may not set firewall rules or do many other administrative tasks which require modifications of in-kernel data, such as setting the securelevel of the kernel.


The base system of DragonFly contains a basic set of tools for viewing information about the active jails, and attaching to a jail to run administrative commands. The jls(8) and jexec(8) commands are part of the base DragonFly system, and can be used to perform the following simple tasks: