For the complete documentation index, see llms.txt. This page is also available as Markdown.

32.2 Thick Jail

Configuring Services

Edit the /etc/rc.conf file with a text editor and add the following:

jail_enable="YES"	# Start the Jail service
jail_parallel_start="YES" # Start Jail services in parallel

jail_parallel_start="YES" enables parallel Jail startup; by default Jails start sequentially, and setting this option causes all containers to start in parallel.

Network configuration (cloned_interfaces, bridge0, epair0, etc.) will be set up in the "Configuring Host Network" section below.

Run the following command to install the base system for the Jail. It is recommended to use base.txz extraction for installation to save compilation time. Note that the Jail's user space version must not be newer than the host (the FreeBSD kernel can be backward compatible with older user space versions), and it is recommended to keep it consistent with the host. FreeBSD's kernel and user space form a whole (the base system, also known as world), and inconsistent user space may cause compatibility issues.

Obtaining the Base System

It is not recommended to extract the base system directly into /usr/jail. Instead, create subdirectories within it and place each container in its own directory for easier management. Note that the extraction and compilation methods are alternatives — choose only one, and do not install twice.

Extraction Installation Method

# Create Jail directory
# mkdir -p /usr/jail/myjail
# Fetch the base system (FreeBSD 15 Release)
# fetch https://download.freebsd.org/releases/amd64/amd64/15.0-RELEASE/base.txz
# Extract files to the container directory
# tar -xf base.txz -C /usr/jail/myjail

The compilation method can also be used for installation.

Compilation Installation Method

Configuring Time

Copy the host's timezone and DNS configuration to ensure proper networking and time inside the Jail:

Configuring Host Network

Warning

The following network configuration operations (modifying bridges, physical NIC IP, restarting network services, etc.) must be performed on the local console. Do not perform them remotely via SSH. If executed via SSH, network interruption during the operation will cause the host to become unreachable, making it impossible to complete the configuration. Ensure proper data backup and contingency measures.

First, configure the host network. Create a bridge bridge0 and a virtual Ethernet pair epair for use by VNET (Virtualized Network Stack), then attach the virtual network interface epair0a to the bridge. Edit the /etc/rc.conf file:

bridge0 is a virtual switch (Network Bridge), and epair0a is a port on the virtual switch.

It can be thought of as a virtual switch with an invisible network cable plugged into it. The RJ45 connector is plugged into the switch. The bridge-side port of the cable is called epair0a, and the container-side port is called epair0b.

epair is a fixed prefix assigned by the kernel, followed by a number representing the virtual connection pair index.

To rename a network interface, run the command ifconfig epair0a name newname. This is not recommended to avoid name confusion.

The Jail VNET network topology is as follows:

After configuring the network, restart the network service:

It is not recommended to execute the above command on a remote host. Ensure proper data backup and contingency measures.

Configuring Container Network

Next, configure the container network. Create the Jail configuration file /etc/jail.conf (create it if it does not exist), which applies to all containers. A reference configuration is as follows:

The first three lines of the configuration allow the use of System V IPC (Inter-Process Communication) mechanisms inside the Jail, including shared memory, semaphores, and message queues;

exec.clean ensures that commands like exec.start run in a clean environment when the container starts, rather than inheriting the environment variables from when the Jail was started; environment variables are discarded, retaining only the following:

Variable
Setting Method

HOME

Set to the default of the target login user

SHELL

Set to the default of the target login user

TERM

Imported from the current environment

USER

Set to the target login username

PATH

Set to /bin:/usr/bin

Additionally, environment variables from the capability database of the login class to which the target login user belongs will also be set; JID, JNAME, and JPATH will not be set.

mount.devfs is used to mount the devfs file system in the container's /dev directory and apply the default ruleset to restrict the device nodes visible inside the container.

The final myjail {...} block creates the Jail example myjail:

The first line sets the container hostname;

The second line sets the container path;

vnet; enables the VNET virtual network stack;

vnet.interface sets the container network interface;

allow.raw_sockets = 1; allows the container to create raw sockets, enabling commands like ping to work properly; FreeBSD Jail's default security policy prohibits containers from directly creating raw sockets, and the ping command requires Raw Sockets to send ICMP packets. Without this configuration, running ping will result in Operation not permitted.

The last three lines define the container's behavior on startup and shutdown;

exec.created sets the epair0b interface to the up state in the host environment. This command is executed before vnet.interface moves the interface into the Jail, so the interface is still in the host network stack. After the interface is moved into the Jail, it retains the up state, ensuring that the network configuration inside the Jail works properly.

Set a static IP address in the container's /etc/rc.conf, with the protocol family set to inet (IPv4), the IP address set to 192.168.1.120, the subnet mask set to 255.255.255.0, and the default gateway set to 192.168.1.1. Edit the configuration file inside the container: /usr/jail/myjail/etc/rc.conf, and add the following:

Starting the Container

After configuration is complete, start it using the service command:

After starting, use the jls command to check. If the container was created successfully and is running, it will appear in the list.

In VNET mode, the IP address is managed internally by the container, so it is normal for the Address field to not show an IP.

Common management commands are as follows:

Command
Description

service jail start myjail

Start container myjail

service jail restart myjail

Restart the container

service jail stop myjail

Stop the container

jls

List running containers

jexec myjail sh

Enter the container command line

Run jexec myjail sh to enter the container command line (this operation requires root privileges). Upon success, the command prompt # will appear, and commands can be entered to operate the container.

If raw socket creation has been enabled as described earlier, use ping example.com to confirm internet connectivity:

Testing the Container

First, install the package manager by running the pkg command. When prompted with Do you want to fetch and install it now? [y/N]:, select y.

If the installation is successful, output similar to the following will be displayed:

If the network is restricted and installation fails, refer to earlier chapters of this book to change the software mirror, or install using Ports.

After successful installation, run pkg update -f to force-refresh the package repository catalog, then run pkg ins nginx, and run service nginx onestart to start nginx once. Upon success, the following output will be displayed:

Use the ifconfig command to confirm the IP address. If all steps in this section were followed exactly, the address should be 192.168.1.120.

Press Ctrl+D or type exit to exit the Jail container's command line.

Return to the host environment and run fetch -o - http://192.168.1.120 | grep Welcome to check whether NGINX is working properly.

If the container network is functioning and Nginx is working properly, the following output will be displayed:

Last updated