Creating and Managing FreeBSD Jails

A comprehensive guide to creating and managing FreeBSD jails, a lightweight, secure method for partitioning a FreeBSD system into multiple independent environments.

FreeBSD jails represent one of the original container technologies in the Unix world, predating many of today’s popular containerization solutions. First introduced in FreeBSD 4.0 in 2000, jails provide a lightweight, secure method for partitioning a FreeBSD system into multiple independent environments. Unlike full virtualization solutions, jails share the same kernel as the host system while maintaining isolation at the filesystem, process, and networking levels.

This article provides a detailed walkthrough of creating, configuring, and managing FreeBSD jails, suitable for system administrators looking to improve resource utilization, enhance security, or simplify service deployment.

Table of Contents

  1. Understanding FreeBSD Jails
  2. Prerequisites
  3. Setting Up the Host System
  4. Creating Your First Jail
  5. Managing Jails
  6. Network Configuration
  7. Resource Limits
  8. Jail Security Considerations
  9. Advanced Configuration with jail.conf
  10. Jail Management Tools
  11. Troubleshooting Common Issues
  12. Conclusion

Understanding FreeBSD Jails

FreeBSD jails provide operating system-level virtualization that allows system administrators to partition a FreeBSD system into multiple independent mini-systems called “jails.” Each jail:

  • Has its own files, processes, user accounts, and root user
  • Can have its own IP address
  • Cannot interact with processes or files outside of its environment
  • Shares the same kernel as the host system

Jails are particularly useful for:

  • Hosting multiple services with isolation
  • Testing environments
  • Security compartmentalization
  • Resource allocation
  • Multi-tenant hosting

Prerequisites

Before creating jails, ensure you have:

  • A working FreeBSD installation (version 12.0 or newer recommended)
  • Root access to the host system
  • Sufficient disk space for jail environments
  • Basic understanding of FreeBSD administration
  • Network connectivity (if jails need network access)

Setting Up the Host System

1. Update the Base System

Always start with an updated system:

# freebsd-update fetch install
# pkg update && pkg upgrade

2. Enable Jail Support in rc.conf

Edit /etc/rc.conf to add:

jail_enable="YES"

This enables the jail service to start at boot time.

3. Configure Network Forwarding (Optional)

If your jails need to communicate with external networks, enable IP forwarding by adding these lines to /etc/rc.conf:

gateway_enable="YES"     # For IPv4
ipv6_gateway_enable="YES" # For IPv6 (if needed)

Then apply these settings:

# service routing restart

Creating Your First Jail

Method 1: Manual Creation

1. Create the Jail Directory

# mkdir -p /usr/jails/myjail

2. Install the Base System

You can install the base system using one of these methods:

Using base.txz:

# fetch https://download.freebsd.org/ftp/releases/amd64/13.1-RELEASE/base.txz -o /tmp/base.txz
# tar -xf /tmp/base.txz -C /usr/jails/myjail

Using bsdinstall:

# bsdinstall jail /usr/jails/myjail

3. Configure the Jail

Create a basic /etc/jail.conf file:

myjail {
    host.hostname = "myjail.local";
    path = "/usr/jails/myjail";
    ip4.addr = "192.168.1.100";
    interface = "em0";
    exec.start = "/bin/sh /etc/rc";
    exec.stop = "/bin/sh /etc/rc.shutdown";
}

Replace 192.168.1.100 with an appropriate IP address for your network and em0 with your network interface name.

4. Start the Jail

# service jail start myjail

Method 2: Using ezjail

ezjail is a popular tool that simplifies jail management.

1. Install ezjail

# pkg install ezjail

2. Enable and Configure ezjail

Add to /etc/rc.conf:

ezjail_enable="YES"

Initialize ezjail:

# ezjail-admin install

3. Create a Jail with ezjail

# ezjail-admin create myjail 192.168.1.100

4. Start the Jail

# ezjail-admin start myjail

Managing Jails

Basic Jail Operations

Starting a jail:

# service jail start myjail

Stopping a jail:

# service jail stop myjail

Restarting a jail:

# service jail restart myjail

Viewing running jails:

# jls

Accessing a Jail

To access a running jail’s shell:

# jexec myjail /bin/sh

For a more user-friendly experience, use:

# jexec myjail login -f root

Configuring a New Jail

After creating a jail, you’ll want to:

  1. Set the root password:

    # jexec myjail passwd
    
  2. Configure the time zone:

    # jexec myjail tzsetup
    
  3. Update the jail:

    # jexec myjail freebsd-update fetch install
    
  4. Install the package manager:

    # jexec myjail pkg
    

    (Follow the prompts to bootstrap pkg)

  5. Install necessary software:

    # jexec myjail pkg install nginx
    

Network Configuration

Basic Network Setup

For a simple jail with a single IP address, the configuration in /etc/jail.conf might look like:

myjail {
    host.hostname = "myjail.local";
    path = "/usr/jails/myjail";
    ip4.addr = "192.168.1.100";
    interface = "em0";
}

Multiple IP Addresses

To assign multiple IP addresses:

myjail {
    host.hostname = "myjail.local";
    path = "/usr/jails/myjail";
    ip4.addr = "192.168.1.100,192.168.1.101";
    interface = "em0";
}

VNET (Virtual Network Stack)

For more advanced networking with dedicated network stacks:

myjail {
    host.hostname = "vnetjail.local";
    path = "/usr/jails/vnetjail";
    vnet;
    vnet.interface = "epair0b";
    exec.prestart = "ifconfig epair0 create";
    exec.prestart += "ifconfig epair0a up";
    exec.prestart += "ifconfig epair0b up";
    exec.prestart += "ifconfig bridge0 addm epair0a";
    exec.poststop = "ifconfig epair0a destroy";
}

Resource Limits

FreeBSD jails can be constrained with resource limits:

CPU Limits

myjail {
    ...
    exec.system_jail_user = "root";
    exec.jail_user = "root";
    exec.system_user = "root";
    cpuset.id = "1";    # Restrict to CPU core 1
}

Memory Limits

Using rctl (Resource Control):

# rctl -a jail:myjail:memoryuse:deny=2G

This limits the jail to 2GB of RAM.

Disk Space Quotas

You can use ZFS quotas if your jails are on ZFS:

# zfs create zroot/jails/myjail
# zfs set quota=10G zroot/jails/myjail

Jail Security Considerations

Securing Jails

  1. Keep jail systems updated:

    # jexec myjail freebsd-update fetch install
    # jexec myjail pkg upgrade
    
  2. Restrict system calls: In /etc/jail.conf:

    myjail {
        ...
        allow.raw_sockets = 0;
        allow.sysvipc = 0;
        allow.mount = 0;
        allow.mount.devfs = 0;
        allow.mount.fdescfs = 0;
        allow.mount.procfs = 0;
    }
    
  3. Use separate users for different services:

    # jexec myjail pw useradd -n webuser -c "Web Server User" -m
    
  4. Restrict file access:

    # jexec myjail chmod 0600 /etc/master.passwd
    

Advanced Configuration with jail.conf

The /etc/jail.conf file supports inheritance and defaults:

# Global defaults
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
exec.clean;
mount.devfs;

# Jail definitions
webserver {
    host.hostname = "webserver.local";
    path = "/usr/jails/webserver";
    ip4.addr = "192.168.1.100";
    interface = "em0";
}

database {
    host.hostname = "database.local";
    path = "/usr/jails/database";
    ip4.addr = "192.168.1.101";
    interface = "em0";
    # Database-specific settings
    allow.raw_sockets = 1;
}

Jail Management Tools

Besides ezjail, several other tools can help manage jails:

iocage

iocage is a modern jail management tool that leverages ZFS features:

# pkg install iocage
# iocage activate zroot
# iocage fetch
# iocage create -n webjail ip4_addr="em0|192.168.1.100/24" -r 13.1-RELEASE
# iocage start webjail

BastilleBSD

BastilleBSD is another modern jail management system:

# pkg install bastille
# bastille bootstrap 13.1-RELEASE
# bastille create myjail 13.1-RELEASE 192.168.1.100
# bastille start myjail

Troubleshooting Common Issues

Jail Won’t Start

Check for errors in:

# service jail start myjail

Verify IP address conflicts:

# ifconfig
# ping 192.168.1.100

Network Issues

For connectivity problems:

  • Ensure IP forwarding is enabled
  • Check firewall rules
  • Verify network interface configuration
# sysctl net.inet.ip.forwarding
# pfctl -s rules    # If using pf firewall
# ifconfig

Resource Limitations

If your jail is running out of resources:

# rctl -u jail:myjail

Adjust as needed:

# rctl -a jail:myjail:memoryuse:deny=4G

Conclusion

FreeBSD jails offer a powerful, mature solution for system virtualization and service isolation. While they require more manual configuration than some newer containerization technologies, they provide excellent performance, security, and flexibility for FreeBSD environments.

By mastering jails, system administrators can:

  • Improve security through isolation
  • Optimize resource usage
  • Simplify service deployment and management
  • Create cleaner, more maintainable infrastructure

As you become more comfortable with basic jail operations, consider exploring advanced features like VNET networking, ZFS integration, and jail templates to further enhance your FreeBSD infrastructure.