How to Setup Jail with Iocage on FreeBSD

Jail is a term for OS-level virtualization on the FreeBSD. It was introduced by Poul-Henning Kamp in 1999 and adopted by FreeBSD since version 4.x.

The Jail allows the system administrator to create an isolated and independent mini system or 'jail' inside the FreeBSD system. The 'jail' has its root system and configuration, and it's helpful if you want to deploy an application in an isolated environment.

Iocage is a FreeBSD jail manager that is written in Python. It's simple and comes with an easy command syntax. The Iocage jail manager is dedicated to the ZFS dataset inside jails and allows you to create a jail based on the 'VNET' virtual networking stacks and/or the 'Shared IP' based jail. With the Iocage, you can create the jail template, base jail, and normal jail.

This tutorial will show you how to set up and configure FreeBSD jail using Iocage Jail Manager. We will install the Iocage on FreeBSD, set up a new jail using shared IP, set up the pf firewall, and then install the nginx web server inside the jail for testing.

Prerequisite

For this guide, you will be required to install and configure Iocage Jail Manager on the FreeBSD system that installed on the ZFS (Z File System). And make sure you have got the pf Firewall enabled on your FreeBSD system.

Below is the guide for FreeBSD installation on ZFS and the pf firewall configuration.

How to Install FreeBSD 12.0 on ZFS
How to Setup pf Firewall on FreeBSD

What we will do:

  1. Install Iocage Jail Manager
  2. Download FreeBSD Release
  3. Setup Shared IP and Pf Firewall
  4. Create New Jail with Iocage
  5. Testing

Step 1 - Install Iocage on FreeBSD

First, we will install and configure the Iocage Jail manager on the FreeBSD system. The Iocage is written in Python and is available in the FreeBSD binary package repository.

Install Iocage to the FreeBSD system using the pkg command below.

pkg install py36-iocage

Type 'y' to accept the Iocage python package installation, and the installation will begin.

Once the installation is complete, check available ZFS pool on the system using the zpool command below.

zpool list

Now choose the ZFS pool for the Iocage installation. For this guide, we will be using the default ZFS pool for the FreeBSD installed called 'zroot'.

Activate the 'zroot' pool for the Iocage usage using the command below.

iocage activate zroot

Now the Iocage installation on FreeBSD 12.0 has been completed, and you can use the iocage command-line to create and manage FreeBSD jail.

Additionally, you can enable the jail on system boot by adding the iocage service to the '/etc/rc.conf' file using the sysrc command below.

sysrc iocage_enable=yes

Step 2 - Download FreeBSD Release

To create a new jail, you will need to download the FreeBSD Release. And you can create a new jail which is a different version of your host FreeBSD version.

Check the available Release versions using the iocage command below.

iocage fetch

Now, you will get a different version of the Release. Select the version as you need and type the number. Choose the number '2' to download the latest Release version.

Wait for the FreeBSD release image being downloaded.

If you want to download a different image, you can use the following command.

iocage fetch 11.3-RELEASE

As a result, the FreeBSD release image for jail has been downloaded.

Step 3 - Setup Shared IP and Pf Firewall

After downloading the source images for jail, we will configure the networking and the pf firewall on the system. We will create a new network interface called 'bridge0' with network IP address '10.8.8.1/24', and it will be used by the jail.

Add new configuration to the '/etc/rc.conf' file by running the following command.

sysrc cloned_interfaces+="bridge0"
sysrc ifconfig_bridge0="10.8.8.1/24"

Create a new 'bridge0' interface with the network IP address '10.8.8.1/24'.

ifconfig bridge0 create
ifconfig bridge0 10.8.8.1/24 up

Now that the 'bridge0' interface has been created, check it using the following command.

ifconfig bridge0

And you will get the result as below.

Next, we will configure the pf firewall and add a new configuration for the jail environment. We're using the simply pf firewall configuration on this guide.

How to Setup Pf Firewall on FreeBSD 12.0

Goto the '/usr/local/etc' directory and edit the configuration file 'pf.conf'.

cd /usr/local/etc/
vim pf.conf

Add the internal network interface 'bridge0' and its Ip address as 'int_if' and 'localnet' variables.

# Internal interface
int_if = "bridge0"
localnet = $int_if:network

Now define the host jail IP address and ports that will be forwarded to the jail. We will forward the HTTP and HTTPS connections on the system external interface to the jail host IP address '10.8.8.5'.

# Port-Forward http and https to Jail '10.8.8.5'
ports_to_forward="{ 80, 443 }"
forward_host="10.8.8.5"

Enable nat on the 'ext_if' external interface for jail 'localnet' variable, and then enable the port redirection from the 'ports_to_forward' variable to the host 'forward_host'.

# nat jail to internet and internet to jail (http and https only)
nat on $ext_if inet from $localnet to any -> ($ext_if)
rdr on $ext_if proto tcp from any to any port $ports_to_forward -> $forward_host

Now pass all connection from the 'bridge0' interface and pass incoming connection on the external interface to the HTTP and HTTPS 'ports_to_forward'.

pass from { self, $localnet } to any keep state
pass in on $ext_if proto {udp, tcp} from any to any port $ports_to_forward keep state

Save and close.

Now test the pf firewall configuration and make sure there is no error, then reload the pf service.

service pf check
service pf reload

After that, check all rules on the pf firewall using the following command.

pfctl -s rules

And you will get the result as below.

Additionally, you can check the nat status on the pf firewall.

pfctl -v -s nat

As a result, the new interface 'bridge0' has been created, and the pf firewall has been configured. And we're ready to create new first jail.

Below is the complete pf firewall configuration.

cat /usr/local/etc/pf.conf
# Define External Interface and IP Address
ext_if="vtnet0"
ext_ip="198.13.39.207"

# Define TCP and UDP Services
ext_tcp_ports="{ ssh, smtp, smtps, imaps, http, https, domain }"
ext_udp_ports="{ domain, ntp }"

# Internal interface
int_if = "bridge0"
localnet = $int_if:network

# Port-Forward http and https to Jail '10.8.8.5'
ports_to_forward="{ 80, 443 }"
forward_host="10.8.8.5"

# Skip the localhost
set skip on lo0

# Log interface
set loginterface $ext_if

# nat jail to internet and internet to jail (http and https only)
nat on $ext_if inet from $localnet to any -> ($ext_if)
rdr on $ext_if proto tcp from any to any port $ports_to_forward -> $forward_host


# Default Policy
block in all
pass out all keep state

# Allow Ping
pass inet proto icmp icmp-type echoreq

pass from { self, $localnet } to any keep state
pass in on $ext_if proto {udp, tcp} from any to any port $ports_to_forward keep state

# Allow Services
pass in proto tcp from any to any port $ext_tcp_ports
pass in proto tcp from any to any port $ext_udp_ports

# Log access for ssh and http
pass log quick proto tcp from any to any port { ssh,http }

Step 4 - Create a New Jail using Iocage

After configuring the network and pf firewall on the FreeBSD system, we're ready to create a new jail using iocage.

Create a new jail called 'jail01' with the FreeBSD release '12.0-RELEASE' using the iocage command below.

iocage create -n jail01 -r 12.0-RELEASE

Now add the IP address and default router gateway of the jail. We will give the 'jail01' an IP address 10.8.8.5' and the default router gateway is the 'bridge0' host IP address '10.8.8.1'.

iocage set ip4_addr="bridge0|10.8.8.5" jail01
iocage set defaultrouter="10.8.8.1" jail01

Enable the jail to start on boot.

iocage set boot=on jail01

Now check the jail list.

iocage list

And you will get the 'jail01' with IP address '10.8.8.5' and based the FreeBSD release '12.0'.

Next, start the 'jail01' using the command below.

iocage start jail01

Once the jail started, access the jail using the following command.

iocage console jail01

You will get a new shell inside jail01, as shown below.

Inside the jail, check the IP address of 'bridge0' interface on the 'jail01'.

ifconfig bridge0

And you will get the 'bridge0' interface has an IP address '10.8.8.5' as configured.

As a result, a new jail called 'jail01' has been created.

Step 5 - Testing

In this step, we will test the 'jail01' by installing the Nginx web server on it and then try to access the Nginx from the outside of the network, and the connection will be redirected to 'jail01'.

Firstly, update the binary packages on the jail using the pkg command below.

pkg update

After that, install the nginx web server inside the jail using the following pkg command.

pkg install nginx

Once the installation is complete, add the nginx service to the system boot and start the nginx service.

sysrc nginx_enable=yes
service nginx start

Now check the list open port on the 'jail01'.

sockstat -l4

And you will get the Nginx service is up and running in the HTTP port '80'.

Next, we will change the default index.html page on the 'jail01'.

Goto the '/usr/loca/www/' directory and edit the 'index.html' file.

cd /usr/local/www/
edit nginx-dist/index.html

Make some changes and exit.

cat nginx-dist/index.html

Now access the external IP address of the server from your web browser.

http://198.xx.xx.207/

And you will get the nginx index.html page inside the 'jail01'.

As a result, the 'jail01' is up and running with the Nginx installed on it. All HTTP and HTTPS connections to the server will be redirected to the 'jail01'.

Reference

Share this page:

0 Comment(s)