≡ Menu

How To Setup FreeBSD Jails With ezjail

How do I setup operating system-level virtualization that allows me to partition my FreeBSD-based Unix server system into several independent mini-systems called jails? I would like to set one jail for the mail server and web server via 2 public IP address. How can I setup FreeBSD jails?

Each jail under FreeBSD virtual environment runs on the host machine with its own files, processes, user and superuser accounts. From within a jailed process, the environment is almost indistinguishable from a real system. The easiest way to set, create and modify jails is using a framework called ezjail.

WARNING! You need to modify host server daemons to listen to only 127.0.0.1 or a single private or public IP such as 202.54.1.2. At least you need to modify sshd, syslogd and other services before you configure jails.

My sample setup

  1. server.nixcraft.net.in : FreeBSD host server running v11 with public IP address 202.54.1.2.
  2. smtpd.nixcraft.net.in : Mail server jail with public IP address 202.54.1.3
  3. httpd.nixcraft.net.in : Web server jail with public IP address 202.54.1.4

Step # 1: Update your FreeBSD host system

Make sure you are running updated kernel and base system. Use cvsup command to install the latest kernel and base system. See detailed tutorial about upgrading FreeBSD operating system.

Step # 2: Install ezjail

Type the following commands to install ezjail port which contains two scripts to easily create, manipulate and run FreeBSD jails.
# cd /usr/ports/sysutils/ezjail
# make install clean

Or use the binary package system:
# pkg install ezjail
Sample outputs:

Installing FreeBSD jail management utility ezjail

Installing FreeBSD jail management utility ezjail

Enable ezjail at boot time and via service command

Type the following command:

echo 'ezjail_enable=YES' >>  /etc/rc.conf

ezjail default file locations

  1. /usr/jails/ : Default location to store base jail system template.
  2. /usr/jails/flavours/: Customization for each jail can be done via flavours. For e.g. adding default /etc/resolv.conf file or updating existing /etc/make.conf can be done here.
  3. /usr/jails/basejail/ : Base jail will be exported and mounted as read only for each jail. This will save disk space.
  4. /usr/local/etc/rc.d/ezjail.sh : Stop / Start / Restart jails script.
  5. /usr/local/etc/ezjail.conf : Configuration file for ezjail script. contains settings that control the operation of the ezjail rc script. It is also read by the ezjail-admin utility to figure out where it should perform its actions.
  6. /usr/local/etc/ezjail/ : All your jail configuration files are stored here.

Step # 2: Create base jail template

The ezjail-admin utility is used to manage the ezjail environment and all the jails inside the ezjail scope. Type the following command to creates or updates ezjail’s environment (i.e. basejail) from source, enter:
# ezjail-admin install
OR specify mirror location with the -h option as follows:
# ezjail-admin install -h http://ftp.freebsd.org
You can set mirror location by editing /usr/local/etc/ezjail.conf file as follows:

# Set mirror closet to you #
ezjail_ftphost=http://ftp5.uk.freebsd.org

The above command will populate the jail with FreeBSD-RELEASE. To populate the jail with installworld, run:
# ezjail-admin update -p -i
Where,

  • -p : Provide ports for jail.
  • -i : Do not run make world. This will save time and it will use existing buildworld done in step # 1.

Create clone interface

Type the following two commands to create lo1 interface to keep jail loopback traffic off the host’s loopback network interface:

echo 'cloned_interfaces="lo1"' >> /etc/rc.conf
## Restart netif ##
service netif cloneup
## Verify it ##
ifconfig

Sample outputs:

Created clone interfaces: lo1. 

Step # 3: Create SMTPD Mail Server Jail

Type the following command to create smtpd jail with 202.54.1.3 as a public IP address at /usr/jails/smtpd directory:
# ezjail-admin create smtpd 'lo1|127.0.1.1,vtnet0|202.54.1.3'
In this example create httpd with 192.168.2.41 IP address:
# ezjail-admin create httpd 'lo1|127.0.1.1,vtnet0|192.168.2.41'
To list jails, enter:
# ezjail-admin list
Sample outputs:

STA JID  IP              Hostname                       Root Directory
--- ---- --------------- ------------------------------ ------------------------
DS  N/A  127.0.1.1       httpd                          /usr/jails/httpd
    N/A  vtnet0|192.168.2.41

To start httpd jail, run:
# ezjail-admin start httpd
Sample outputs:

Starting jails: httpd.

To login, enter:
# ezjail-admin console httpd
Sample outputs:

root@httpd:~ #

Set root password:
# passwd

How do I start all Jails?

# /usr/local/etc/rc.d/ezjail start

How do I stop all Jails?

# /usr/local/etc/rc.d/ezjail stop

How do I restart all Jails?

# /usr/local/etc/rc.d/ezjail restart
You can also start / stop / restart particular jail using the following syntax:
# /usr/local/etc/rc.d/ezjail {start/stop/restart} jail-name
# /usr/local/etc/rc.d/ezjail start httpd
# /usr/local/etc/rc.d/ezjail stop smtpd.nixcraft.net.in

How do I list all jails?

Use jls command to lists all jails:
# jls
OR
# ezjail-admin list
To display more verbose information including cpusets, jail state, multi-IP, etc. enter:
# jls -v

How do I login to my jail from the host itself?

Use jexec command as follows to attach a console to jail:
# jexec jid csh
OR
# ezjail-admin console httpd
jid can be obtained using jls command. Connect to jail called httpd with jid # 2:
# jexec 2 csh
Now, you can install any software and do work with the jail. Update your /etc/resolv.conf file:
# vi /etc/resolv.conf
Install bash shell, enter:
# pkg install bash
Install Apache 2.2 server:
# cd /usr/ports/www/apache22
# make install clean

How do I login to my jail remotely using ssh?

First, login using jexec command from the host itself. Add the following line to jail /etc/rc.conf:
# echo 'sshd_enable="YES"' >> /etc/rc.conf
Open sshd_config file and update listen parameter to bind to jail IP only. Start OpenSSH server inside the jail:
# /etc/rc.d/sshd start
# sockstat -4

How do I upgrade FreeBSD jail?

Simply run the following command to update the basejail to the latest patched release of the version of FreeBSD host:
# ezjail-admin update -u

How do I upgrade only ports tree?

No need to stop jails, just run the following to update ports tree for all jails:
# ezjail-admin update -P

Jail log files

The default jail console file is located at /var/log directory. For e.g. view log file for httpd jail, enter:
# tail -f /var/log/jail_httpd_console.log
# grep 'error' var/log/jail_httpd_console.log

How do i add additional jails?

Create db1 jail, enter:
# ezjail-admin create db1 'lo1|127.0.1.1,vtnet0|192.168.2.42'
# ezjail-admin list
# ezjail-admin start db1
# ezjail-admin console db1

How do I backup jails?

Use tar, rsync or dump command to backup jail to another server or tape device. For e.g. tar command to backup httpd to tape:
# tar -zcvf /dev/sa0 /usr/jails/httpd
You can also use dump command to backup all jails stored on /jails partition:
# /sbin/dump -0uLf /dev/sa0 /jails/
Later just dump incremental updates:
# /sbin/dump -1uLf /dev/sa0 /jails/

Recommend Readings:

  • FreeBSD Jail chapter from the official FreeBSD handbook.
  • man pages jexec, jls, jail, dump, restore
Share this tutorial on:
{ 11 comments… add one }
  • Valqk June 12, 2009, 11:56 am

    Just to share, I’ve written a command called
    jlog jailname. It makes jexec JID tcsh and logs you into the jail.
    There it is: Link

    p.s. I didn’t find my posts in mailing lists so I’ve posted in my blog. pls. feel free to delete this comment if you consider this as spam or something.

  • Shoaibi June 17, 2009, 1:41 pm

    @Vivek:
    Good going…

    @Valqk:
    thanks, I was thinking to create one after reading the article…

  • Dhenin Jean-Jacques March 22, 2010, 7:09 pm

    Appréciable. Merci beaucoup. Très utile.

  • cleroy61 September 6, 2010, 6:41 pm

    Hello,
    When I create a jail with ezjai, I can not access usr/ports from my jail to install nginx;

    jexec 2 cd /usr/ports/www/nginx && make install clean
    No such file or directory

    It does not exist in fact, how can I link to my jail?
    I’m out of my jail and I am a portsnap extract command
    and then an portsnap fetch update command, thinking I did not open the softwares worn.
    it is present but with the letter ‘l’ in front, preventing me from going there as a directory:

    lrwxr-xr-x 1 root wheel 19 Sep 5 11:12 ports -> /basejail/usr/ports

    Thanking you Sincerely Christophe

  • cleroy61 September 7, 2010, 7:17 pm

    I found answer through freeBSD forum ; the command is not enough

    portsnap fetch extract

    I tried this one after building the jail with ezjail-admin create

    portsnap -p /usr/jails/basejail/usr/ports/ fetch extract

    it’s OK now !

  • Broy January 22, 2011, 7:08 am

    Hello!
    I set up Ezjail in my FreeBSD 8.1 amd64 release-version. After successful installation,
    i did the ” ezjail-admin update -p -i ” command but unfortunately it shows some errors:
    ——————————————————–
    cd /usr/src; make -f Makefile.inc1 hierarchy
    cd /usr/src/etc; make distrib-dirs
    cd: can’t cd to /usr/src/etc
    *** Error code 2

    Stop in /usr/src.
    Error: The command ‘make installworld’ failed.
    Refer to the error report(s) above.
    ———————————————————-

    BTW, i recompiled and build my own kernel first before i install Ezjail. I’m suspecting why does error occurred its because of the new kernel configuration but that was only my presumption.

    Any help bout this?

    Thanks much!

  • Karl Blessing February 22, 2011, 10:56 pm

    Would it be possible to install a jail on a binary distribution. If I don’t have a source tree and I don’t wish to re-build the base system from cvsup but rather keep it easy with freebsd-update?

    • Karl Blessing February 23, 2011, 12:58 am

      I just went with pulling down the source tree, doing buildworld (But not installworld). Was just hoping there’d be a way to update the jails without having to rely on sources.

  • Namotco June 8, 2012, 9:41 pm

    /usr/local/etc/rc.d/ezjail.sh

    is now:

    /usr/local/etc/rc.d/ezjail

  • Michael July 11, 2012, 6:11 am

    Thanks Vivek for this.

    My question is how do I assign a set amount of disk space and RAM to each jail…. just like we do it on openvz for each virtual machine.

    For example I want jail 1 to have 20GB disk and say 256 MB RAM assigned. jail2 should have 100 GB disk and 1 GB RAM etc. How does one do this?

    • jpd August 4, 2012, 1:59 pm

      You need to kompile kernel with quota enabled and then use quota to specify disk limitations. Dunno if RAM limitations have been implemented yet (doubt it).

Security: Are you a robot or human?

Leave a Comment

You can use these HTML tags and attributes: <strong> <em> <pre> <code> <a href="" title="">


   Tagged with: , , , , , , , , , , ,