How to configure and use jailed processes in FreeBSD

Safely Behind Bars

Many Services, One Jail

As already described, among other things, a jail is used to protect hosts against attacks on specific services. The best-known examples are the DNS service, bind, and web servers. It is important that all of these services are always and exclusively bound to the IP address of the jail.

The next example installs the DNS service, bind, in a jail. On small networks, you don't strictly need to assign a separate machine for bind; it is sufficient to create a jail on the central FreeBSD server. Primary and secondary DNS should never run in the same jail on a host system. If the host system failed, both primary and secondary DNS would be inaccessible. Add the following entry to the bind configuration file:

listen-on port 53 { <IP_address_of_jail>; };

You still need to modify the /etc/resolv.conf file on each computer on the network – including the host system!

It is possible to operate a DHCP server a jail [7]. To do this, you need to build the ISC-DHCP3 server port from the /usr/ports/net/isc-dhcp3-server directory:

# make install -DDHCP_PARANOIA  -DDHCP_JAIL -DDHCP_SOCKETS
# make clean

In the jail, add the system configuration, /etc/rc.conf, as shown in Listing 7.

Listing 7

DHCP Configuration

01 dhcpd_enable="YES"
02 dhcpd_flags="-q"
03 dhcpd_conf="/usr/local/etc/dhcpd.conf"
04 dhcpd_umask="022"
05 dhcpd_chuser_enable="YES"
06 dhcpd_withuser="dhcpd"
07 dhcpd_withgroup="dhcpd"
08 dhcpd_devfs_enable="YES"
09 dhcpd_makedev_enable="NO"
10 dhcpd_chroot_enable="NO"
11 dhcpd_jail_enable="NO"
12 dhcpd_rootdir="/var/db/dhcpd"
13 dhcpd_hostname="dns"
14 dhcpd_ipaddress="<IP-address-of-jail>"

Add the following line to the DHCP daemon configuration file, /usr/local/etc/dhcpd.conf:

local-address <IP_address jail>;

Then, on the host system, enable the kernel driver for the Berkeley Packet Filter (bpf), and add this entry to the ruleset for the devfs daemon [devfsrules_jail= 4] section: add path 'bpf*' unhide.

You also need to bind the Apache or Lighttp HTTP services to an address. The entry in httpd.conf looks like this:

Listen <IP_address of jail>:80

You can also install a mail server within a jail. However, the configuration is more complex than for the previous examples. I'll briefly look at the procedure for a mail server with Postfix MTA [8] including anti-spam and anti-virus scanners (see the "Rules for the PF and IPFW Packet Filters" box).

Rules for the PF and IPFW Packet Filters

For routing-enabled jails to be accessible from the outside, you need to compose matching rules for PF and IPFG [10]. These are the rules for PF, the packet filter ported from OpenBSD.

# NAT Rules for PF
# =================
extif = "<Internet_Interface>"
intif = "<Intranet_Interface>"
nat_jail = "<Jail_IP_Address>"
nat on $extif from $intif:network to any -> ($extif)
rdr on $extif proto tcp from any to any port <Port> -> $nat_jail
pass in on $extif inet proto tcp from any to $nat_jail port <Port>

This setup starts by specifying the network interface ($extif) on which to listen to the data stream. PF then forwards all TCP data sent to Port on the external interface to the IP address of the jail ($nat_jail). To allow the data to flow freely through the packet filter, you need to unlock a channel using pass. The setup is more complex for IPFW. You need to create the IPFW script and NAT rules for the NAT daemon. The rules for the NAT daemon (natd) are:

# NAT rules for natd
# /etc/natd.conf
# =================
redirect_port tcp <Jail-IP>:<Port 1> <Port 1>
redirect_port tcp <Jail-IP>:<Port 2> <Port 2>

To make IPFW available on the system, you must enable various kernel options. It makes sense to read the relevant literature, such as the very good manual [10]. To keep everything more easily readable, set the following variable: fwcmd= " /sbin/ipfw -f". You then again need to give the NAT daemon access to the traffic routed via the tun0 interface.

The following rule should be one of the first pieces of information in the script:

${fwcmd} add divert natd all from any to any via tun0

To make sure that nobody can exploit the redirected data stream, now add another rule:

${fwcmd} add allow tcp from any to any <Port> setup keep-state

The final rule should always be:

${fwcmd} add deny ip from any to any

After parsing the configuration for PF or the running the script for IPFW, the rules are now active. It is also very useful to read the documentation for the tools used here for both setups.

You need to replace the localhost address with the jail IP address in the Postfix configuration files, /usr/local/etc/postfix/main.cf and /usr/local/etc/postfix/master.cf. Also, the hostname localhost must be replaced with the jail hostname, unless the jail uses the localhost IP address. The same thing applies to configuring the anti-spam filter and anti-virus scanner. To allow the system to continue to send email on the host system, the DNS service on the network needs an MX record.

Of course, you could install all of the services in separate jails on a host system for a small office or home network. Figure 2 shows the configuration.

Figure 2: Server with services in jails.

I have read in various forums [9] about administrators who run database servers in jails. This is something to avoid, because some database systems use System V IPC to communicate and because the data in a database needs special protection. The recommended approach is to install the database system on the host and communicate with the database via an IP address. Similar precautions also apply to database servers that are managed via a web interface. The WWW service should definitely run in a jail: If a vulnerability in the daemon process is then exploited, at least there is no risk to the database data. Figure 3 shows this configuration.

Figure 3: Database server with WWW connection.

Services based on the RPC protocol cannot be operated in a jail. This is especially true for Network Information Service (NIS). If you really want user administration within a jail, then you either need to copy the host system's /etc/passwd to the jail or install LDAP. The procedure for LDAP is the same as installing on a client system. It is important to note that the jail cannot use user IDs that exist on the host. The reason is simple: If an SSH service runs on the host and a user account is compromised, the attacker could also easily log in to and damage the host system. The best approach is thus to set up the minimum number of user accounts and avoid using the same usernames. This cannot be avoided for system accounts and the root user. In this context, it is extremely important to use different passwords for the root user on the host and in the jail. (Also see the "Important Flags for Jails" box.)

Important Flags for Jails

Only six Management Information Bases (MIBs) for jails can only be changed on the host system, and two parameters can be manipulated by the root user from within the jail. The flags are set using

<C>sysctl<C>: <C>sysctl -w $MIB=0<C>

or

<C>sysctl -w $MIB=1<C>

Using sysctl $MIB lets you query the current status. Table 1 shows the MIBs that can be modified on the host system and affect all jails equally.

Table 1

MIBS

Name of MIB Explanation Default Target
security.jail.set_hostname_allowed The root user can change the hostname in a jail using hostname(1), sethostname(3), or MIB kern.hostname. The jail uses the hostname to communicate with the main system. Therefore this parameter should always be set to 0. 1 0
security.jail.socket_unixiproute_only This MIB decides whether the jails use IP or Unix sockets to communicate. The latter is risky because it opens up a hole in the security design. 1 1
security.jail.sysvipc_allowed If this flag is set, communication with processes outside the jail is possible via System V IPC (Interprocess Communication). Some databases require this flag to be set. Caution! 0 0
security.jail.allow_raw_sockets This MIB allows raw sockets to be used in a jail. This makes it possible to use tools such as ping(8) or traceroute(8). But also note that the network subsystem uses raw sockets! 0 0
security.jail.getfsstatroot_only This lets you configure whether users in a jail see all mount points. 1 1
security.jail.chflags_allowed This MIB checks whether or not a privileged user is allowed to change file flags (chflags(8)). 0 0

Windowing with Jails

Jails are not just useful for security purposes, they also provide a useful approach to building training environments. Each participant can be assigned to a jail where they complete their assignments. Graphical user interfaces (GUIs) based on X11 can also be installed in a jail for this purpose. One important point here is that the X server does not work in a jail because it requires direct access to the hardware. Thanks to the X11 protocol, though, you can redirect the output to, for example, a thin client. The configuration is not particularly difficult, but there are a couple of pitfalls.

First, install the desired X11 applications in the jail either via the ports tree or using pkg_add -r. In both cases, all required libraries and programs are automatically installed to resolve dependencies. You also need the xauth program to support trouble-free authentication. It can be found in /usr/ports/X11/xauth. The next step is to change a parameter in the /etc/ssh/sshd_config settings for the SSH daemon: X11Forwarding yes. This forwards all X11 protocol tokens through the SSH tunnel. Note: At this point, name resolution must be working properly!

On the client side, you need to have the xauth and xhost tools, as well as a display manager in place (xdm, gdm, or kdm depending on your preference). Add the following to the SSH client configuration:

Host *
   ForwardAgent yes
   ForwardX11 yes
   XAuthLocation /usr/bin/xauth
   ForwardX11Trusted yes

Next, tell the X server on the clients to accept data from the X11 applications in the jail:

$ xhost +<IP_address of jail>

If you then use ssh user@x11jail <X11_application> to log in to the jail, the window of the X11 application launched in the jail appears on the client desktop (Figure 4).

Figure 4: On the right, you can see the X11 application launched in the a jail (xclock) on a Gnome 3 desktop. The left-hand window shows the associated SSH terminal.

Building on this setup, you can run Linux applications in a jail with just a few clicks, in case you have applications that are available for Linux, but not FreeBSD. This setup relies on FreeBSD libraries that provide Linux compatibility, so you need to install the linux_base port on the host,

# cd /usr/ports/compat/linux_base
# make install clean

then mount the directory with the libraries in the jail directory:

# mount_nullfs /compat/ <path to jail>/compat/
# mount -t linprocfs linprocfs <path to jail>/compat/linux/proc

It is also important to mount the Linux process filesystem because Linux process management maps to a filesystem. To keep the mount after a restart, you can modify the /etc/fstab on the hosts accordingly with the entries each occupying a single line:

<path to jail>/compat/ /compat nullfs rw 0 0
linprocfs <path to jail>/compat/ linux/proc linprocfs rw 0 0

Also add the following line to the host's /etc/rc.conf system configuration: linux_enable="YES".

Two Worlds, One System

The examples shown in the previous section can be extended to provide a kind of virtualization solution. The jail solution on FreeBSD allows you to create jails that will run 32-bit applications on 64-bit hosts. The procedure for the installation and configuration is the same, except for a few minor differences (Listing 8).

Listing 8

Configuration for 32-bit Applications

# setenv UNAME_m i386
# setenv UNAME_p i386
# cd /usr/src
# make buildworld TARGET=i386
# make installworld TARGET=i386 DESTDIR=<path to jail>
# cd etc/
# make distribution DESTDIR=<path to jail>
# mount -t devfs devfs <path to jail>/dev

To begin, you need to set the environmental variables so the uname command is output correctly. After changing to the directory /usr/src, you need a couple of calls to make. To create a 32-bit jail, use the TARGET=i386 make parameter. (The expression i386 is a synonym for 32-bit technology.) The remaining steps follow the pattern shown in the listing, and the configuration steps within the jail follow the same approach as described previously.

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus