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

32.3 Qjail

Jail Management Tools Comparison

Qjail is a wrapper tool for deploying Jail environments, providing security and performance enhancement features.

The conceptual structure of the Jail deployed in this section is shown in the following diagram:

Jail Structure

Reserving Jail IP Addresses: Network Interface Configuration

Add the following configuration to the /etc/rc.conf file. The cloned interface lo1 separates Jail network configuration from the host network configuration, enhancing isolation.

Warning

① To create multiple interfaces, describe them on the same line separated by spaces, rather than creating multiple lines. It should be cloned_interfaces="lo1 lo2". When written on separate lines, only the first line takes effect.

Restart all network interfaces to apply the configuration:

lo1 will have 14 IP addresses available, all of which can be assigned to individual Jails.

Installing Qjail

Install Qjail using pkg:

Or install using Ports:

Enable the qjail service to start at boot:

Deploying the Qjail Directory Structure

Before using Qjail, deploy its directory structure using one of the following two methods:

Method 1: Automatic Download from Official Mirror

Qjail will download the base.txz file from the FreeBSD official site. Example output:

Method 2: Download from a Chinese Mirror

When network access within China is restricted, a mirror site can be used for manual download. Taking the University of Science and Technology of China Open Source Mirror as an example. Use the freebsd-version command to confirm the host's FreeBSD version; Qjail requires the file version to match the host. The following example is for FreeBSD amd64 15.0:

Download the FreeBSD base system file from the mirror server:

Install the base system to the specified Jail using qjail:

After deploying the Qjail directory structure, four directories — sharedfs, template, archive, and flavors — will be automatically generated under the /usr/jails directory. These four directories constitute the core file system architecture of Qjail:

Directory
Description

sharedfs

Contains a read-only operating system executable library, shared among Jails via nullfs to save storage space. nullfs is a special file system provided by FreeBSD that can mount the same file system at multiple locations on the same host

template

Contains the operating system configuration file templates, which will be copied to each Jail's base file system as the initial configuration for new Jails

archive

Stores archive files produced by the Jail archive command, used for Jail backup and restoration

flavors

Contains system flavors and user-created custom flavors, which are essentially predefined configuration file sets for quickly customizing new Jail configurations

File structure:

Deploying Jails

Create Jail jail1, specifying the network interface and IPv4 address:

  • -n specifies lo1 as the network interface

  • -4 specifies the IPv4 address

After creating jail1, a jail1 directory will be created under /usr/jails/ (/usr/jails/jail1/) to store the corresponding files.

Custom configuration files can be created in the aforementioned flavors directory, so that they are automatically copied when deploying new Jails. For example, create a new file /usr/jails/flavors/default/usr/local/etc/pkg/repos/FreeBSD.conf, and subsequently created Jails will automatically copy this file:

After creating jail2, the file /usr/jails/jail2/usr/local/etc/pkg/repos/FreeBSD.conf is automatically generated, effectively modifying the default pkg mirror for all subsequent Jails. However, since the corresponding file was not written to the flavors directory when jail1 was created, jail1 does not have this file.

Qjail Basic Usage

Jails managed by Qjail are essentially standard FreeBSD Jails, so system commands like jls and jexec can also be used to view and operate these Jails. The following are Qjail-specific management commands.

List Jails managed by Qjail:

Start Jails:

Stop Jails:

Restart Jails:

Enter the Jail console:

After entering the Jail console, operations will be performed as the root account within the Jail (no password required). Since the Jail may expose services externally, it is recommended to set a root account password for security.

Back up Jails:

Restore Jails from backup:

Delete Jails:

Updating Jails

Since these files are shared via nullfs as a single copy, some Jail updates are not applied to individual Jails but to all Jails.

Updating the Base System in Jails

Update the files in sharedfs:

Updating Ports

The -P (uppercase) option uses the host's Ports to update the Jail's Ports tree.

Updating System Source Code

Update Process

The complete update process is as follows:

Fetch and install FreeBSD system updates:

Stop all qjail Jails:

Update the qjail base system:

Update qjail source code:

Update qjail Ports:

Start all qjail Jails:

Jail Settings

Qjail provides the qjail config command for customizing each Jail's configuration. Core configuration parameters cannot be safely modified while a Jail is running, so the target Jail must be stopped before executing this command.

The qjail config command provides a rich set of configuration options. The following lists several commonly used parameters.

-h

Quickly configure SSH service for jail1:

This command quickly enables the SSH service for jail1, creates a new wheel group user with the same username and password as the jail name, and the system will require a password change on first login with that user. Alternatively, the sshd service can be configured manually after logging into the jail1 console.

-m, -M

Set jail1 to manual start state:

Set jail1 to manual start state (manual state). After qjail_enable="YES" is written to the /etc/rc.conf file, the system will automatically start all Jails at boot; setting a Jail to manual start means it will not start automatically at boot and must be manually started using qjail start jailname.

Corresponding to the lowercase -m option, there is an uppercase -M option, which disables the manual start state, i.e., clears the manual state, allowing the Jail to start automatically at boot. Qjail has many similar options where lowercase letters enable a feature and uppercase letters disable it. This pattern will not be explained again when both lowercase and uppercase options appear together below.

-r, -R

Set jail1 to not allowed to start (norun state):

This configuration is equivalent to disabling jail1.

-y, -Y

Enable System V IPC (Inter-Process Communication) for jail1:

System V IPC is a classic UNIX inter-process communication mechanism, including shared memory, semaphores, and message queues. This option must be enabled when deploying applications such as PostgreSQL in jail1 that depend on shared memory and semaphores.

Network Configuration

Some tutorials mention using qjail config -k jailname to enable the raw_sockets feature for external network access. This is a common misconception. raw_sockets is only needed for tools like ping and is not a prerequisite for network access. Enabling raw_sockets in a Jail poses security risks, as this is part of the Jail environment's default security design. Unless there is a genuine need to use tools like ping within the Jail, the raw_sockets feature should not be enabled.

This Jail is bound to the lo1 network interface, and lo1 cannot directly access the external network. Therefore, the Jail still cannot connect to external networks at this point. PF must be configured for networking, where em0 is the external network interface. Use the ifconfig command to find the external network interface name on the system.

Write the configuration in the /etc/pf.conf file. Network Address Translation (NAT) allows Jails to access external networks, and port redirection allows external networks to access services on specific Jails:

Warning

The rdr pass rule above redirects all traffic entering port 22 on the em0 interface to jail1. If the host also provides SSH service via em0, this will make the host inaccessible via SSH. It is recommended to change the target port or external port of the redirection to a non-22 port (e.g., change the external port to 2222: rdr pass on em0 inet proto tcp from any to em0 port 2222 -> 192.168.1.1 port 22), or add conditions in the rule to exclude the host, to avoid the host's SSH service being shadowed.

Tip

The em0 in the above example is a placeholder and must be replaced with the actual value.

Start the firewall service:

At this point, Jails bound to lo1 can access external networks, and external networks can connect to jail1's port 22 via the host's port 22.

Example: Deploying a PostgreSQL Jail

After reserving Jail IP addresses and successfully running the qjail install command as described earlier, this section uses PostgreSQL 15 as an example for deployment; other versions are also applicable.

Operations on the Host

Create and configure the PostgreSQL Jail:

Create the jail postgres, bound to the lo1 interface, with the IPv4 address 192.168.1.3:

Configure the postgres jail, enabling SysV IPC:

Start the postgres jail:

Edit the /etc/pf.conf file:

Note

Directly exposing PostgreSQL connections to the outside poses security risks; port forwarding should be enabled cautiously based on actual needs.

Start the PF firewall service:

Enter the jail postgres console:

Operations in the Jail Console

The following commands are all run within the Jail console. When installing with pkg, mirrors can be used as needed. If using a mirror, it can be configured in the Jail console in the same way as on the host; see the relevant chapters for details.

Configuring the PostgreSQL Dataset

The PostgreSQL installation process is omitted here; see other chapters in this book for details.

Enable the PostgreSQL service to start at boot:

Create the PostgreSQL data directory (note the version number):

Set the data directory owner to the postgres user:

Switch to the postgres user:

Initialize the PostgreSQL database:

Here initdb is used instead of /usr/local/etc/rc.d/postgresql initdb as suggested during installation, to avoid repeatedly modifying the pg_hba.conf file when setting the database password. A brief explanation of each option:

Option
Description

-A

Specifies the default authentication method for local users in pg_hba.conf

-E

Selects the encoding for the template databases

-W

Causes initdb to prompt for a password for the database superuser

-D

Specifies the directory where the database cluster should be stored

Return to the jail root user:

Start the PostgreSQL service immediately:

If the qjail config -y postgres command was not used to enable SysV IPC during the above process, the following errors may occur:

Error During Database Cluster Initialization

Initialization Error

Error when starting PostgreSQL.

Startup Error

At this point, run qjail config -y postgres on the host console to fix the error, as follows:

Stop the postgres jail:

Configure the postgres jail, enabling SysV IPC:

Start the postgres jail:

After entering the Jail console again, the database cluster can be initialized and the PostgreSQL service can run normally.

References

Last updated