Skip to content

Creating and Configuring Jails in FreeBSD 14.3 (arm64)

FreeBSD jails are a lightweight, secure way to isolate processes and services, similar to Linux containers but older and natively integrated into the FreeBSD kernel. With jails, you can run multiple independent environments on a single host – each with its own users, files, network stack, and processes.

In this post, we’ll walk through creating and configuring a jail on FreeBSD 14.3-RELEASE arm64 from scratch, and then demonstrate installing and running Nginx inside it.

Why Use Jails?

Jails are useful for:

  • Running services (like Nginx, PostgreSQL, or BIND) in isolation.
  • Improving security by containing applications.
  • Testing and development without affecting the host.
  • Lightweight virtualization without the overhead of VMs.

Step 1: Enable Jail Support

FreeBSD includes jail functionality by default. Enable it so it starts on boot:

sysrc jail_enable="YES"

Step 2: Create a Jail Directory

We need a root filesystem for the jail. First, create a directory:

mkdir -p /usr/jails/myjail

Step 3: Fetch the Base System for arm64

Since our host is FreeBSD 14.3-RELEASE arm64, fetch the matching base system:

fetch https://download.freebsd.org/ftp/releases/arm64/aarch64/14.3-RELEASE/base.txz

Extract it into the jail directory:

tar -xpf base.txz -C /usr/jails/myjail

Step 4: Configure the Jail

Add a jail definition in /etc/jail.conf:

myjail {
    host.hostname = myjail.local;
    path = /usr/jails/myjail;
    ip4.addr = 192.168.1.100;
    interface = em0;
    persist;
    mount.devfs;
    allow.raw_sockets = 1;
}

Step 5: Start the Jail

Now start the jail:

service jail start myjail

Check if it’s running:

jls

root@freebsd:~ # jls
   JID  IP Address      Hostname                      Path
     4  192.168.1.100   myjail.local                  /usr/jails/myjail

Step 6: Enter the Jail

To access the jail, use:

jexec myjail /bin/sh

Step 7: Install Nginx Inside the Jail

First, bootstrap the package manager:

pkg bootstrap

Then install Nginx:

pkg install nginx

Enable Nginx to start on jail boot:

sysrc nginx_enable="YES"

Start the service:

service nginx start

Step 8: Test Nginx with curl

From inside the jail:

curl http://127.0.0.1

You should see the Nginx default welcome page HTML.

From the host system (replace with your jail IP):

curl http://192.168.1.100

If everything is configured correctly, you’ll get the same response.

Optional: Share the Host’s IP Instead of Assigning a New One

By default, jails are usually given their own IP address (e.g., ip4.addr = em0|192.168.1.100).
However, you might want your jail to share the host’s IP and simply run services on a different port (similar to how Docker containers can map ports).

This can be done with the ip4=inherit option.

1. Configure Jail to Inherit the Host IP

Edit /etc/jail.conf and update your jail configuration:

myjail {
    path = /usr/jails/myjail;
    host.hostname = myjail.local;
    ip4 = inherit;     # Share host’s IP instead of assigning a new one
    exec.start = "/bin/sh /etc/rc";
    exec.stop = "/bin/sh /etc/rc.shutdown";
    exec.clean;
    mount.devfs;
}

2. Configure Nginx to Listen on a Different Port

Since both the host and jail now share the same IP, you need to avoid port conflicts.
For example, configure nginx in the jail to listen on port 8080:

server {
    listen 8080;
    server_name localhost;

    location / {
        root /usr/local/www/nginx;
        index index.html;
    }
}

Restart nginx inside the jail:

service nginx restart

3. Test the Setup

On the host machine:

curl http://127.0.0.1:8080

Or from another machine on the network, replacing <host-ip> with the actual IP of your host:

curl http://<host-ip>:8080

With this setup:

  • The host keeps its SSH service accessible (default port 22).
  • The jail shares the host’s IP but exposes nginx on port 8080 (or another free port of your choice).

Step 9: Manage Jails

  • Stop a jail:service jail stop myjail
  • Restart a jail:service jail restart myjail
  • List running jails:jls

Optional: Use iocage

If you want an easier jail manager, install iocage

Example usage:

iocage fetch release=14.3-RELEASE
iocage create -r 14.3-RELEASE -n webjail ip4_addr="em0|192.168.1.101/24"
iocage start webjail

iocage handles fetching the correct base system, simplifying jail lifecycle management.

With just a few steps, you can set up a working jail on FreeBSD 14.3 arm64. Jails are secure, lightweight, and flexible – perfect for running multiple isolated environments on the same machine.

In this example, we built a jail, installed Nginx, and successfully tested it with curl. Whether you manage jails manually or with iocage, FreeBSD makes it straightforward to create safe, container-like environments for your services.

Published inFreeBSDOtherSecurity