We already have a QND guide to using jails in FreeBSD. The ezjail program's scripts make updating a jail simpler, as well as making it easier to maintain multiple jails. Although this guide will only cover installing a single jail, simply repeat the steps for new jails. Note that both this and the jail page are only for FreeBSD.
The program is installed from ports. As it consists of a few shell scripts, installation is quite quick.
cd /usr/ports/sysutils/ezjail; make install clean
As the man page says, beginners sometimes get confused here. The command is not to create, it is to update. We will assume that you have recently updated the host system. You start with the command
ezjail-admin update -i
The -i flag means that you are installing the jail's world, not building it first. You will now have a directory /usr/jails with three subdirectories, basejail, flavours and newjail. The basejail is how ezjail saves space, putting many things in there so that each new jail doesen't need /bin /boot /sbin and all the rest. Flavours are something that I haven't used and the newjail is a template for any jails created. Note that if you haven't recently updated your host system, (and after updating your host system in the future) you will want to use ezjail-admin update with the -b flag, rather than -i. This also holds true if you do a buildworld on the host system after a long interval.
The ezjail-admin man page points out that it is considered to be a good practice to run ezjail-admin update each time you update your host system with make buildworld and make installworld.
Now that the basejail has been made, let's make our first new jail. In this case, it's going to be used as a webserver, so we'll call it apachejail.
We create a second IP address for it. If the host system is 192.168.1.230, we can make the jail 192.168.1.231. With a network card called fxp0
ifconfig fxp0 alias 192.168.1.231 netmask 0xffffffff
Assuming we will always be running this jail, a line should be added to /etc/rc.conf on the host system.
ifconfig_fxp0_alias0="inet 192.168.1.231/32 polling"
Now we create our new jail
ezjail-admin create apachejail 192.168.1.231
Once the jail is created, you will find a file on the host system /usr/local/etc/ezjail/apachejail. It will have much of what you would put in the host's /etc/rc.conf if you were creating a normal jail.
export jail_apachejail_hostname="apachejail" export jail_apachejail_ip="192.168.1.231" export jail_apachejail_rootdir="/usr/jails/apachejail" export jail_apachejail_exec="/bin/sh /etc/rc" export jail_apachejail_mount_enable="YES" export jail_apachejail_devfs_enable="YES" export jail_apachejail_devfs_ruleset="devfsrules_jail" export jail_apachejail_procfs_enable="YES" export jail_apachejail_fdescfs_enable="YES"
Depending upon how you're planning to set up apache, you might want to change the hostname. This will depend how the outside world will be accessing your website. Regardless of what the hostname is, when you set up apache, be sure to include the hostname in the jail's /etc/hosts file or apache won't start. This is a page about ezjail, not apache, but you should at least have, assuming you left the hostname as apachejail
in the jail's /etc/hosts
The next step is to begin configuring the jail. Much of this is the same as a regular jail. One of the first things I do is copy the host machine's /etc/resolv.conf to the jail's /etc, so that once I'm in the jail, I can reach the outside world. On the host machine
cp /etc/resolv.conf /usr/jails/apachejail/etc/
Enter the jail the same way you would a normal FreeBSD jail. At this point, you can use anything for the hostname, however, what you type will become the jail's temporary hostname. You will have to use an FQDN, fully qualified name, so you can simply stick example.com on the end. If you already have a domain name that you're planning to use, however, use that. First, start or restart ezjail. If you're going to be running ezjail each time you boot, first enable it in /etc/rc.conf. Add the line
Now, start the jail.
That will only work if you've already added ezjail_enable="YES" to /etc/rc.conf. If you haven't yet added that line use forcestart instead.
Now, enter the jail. jail /usr/jails/apachejail apachejail.example.com 192.168.1.231 /bin/sh
This will put you in the jail as root.
At this point, I go back to the jail man page and do similar configuration to that given on our jail page. I edit the jail's /etc/rc.conf.
rpc_bind_enable="NO" network_interfaces="" sshd_enable="YES" sendmail_enable="NO" defautrouter="192.168.1.1" early_late_divider="NETWORKING"
The early_late_divider entry can be found in man(5) rc.conf. It is sometimes necessary in a jail for a jailed apache (or other services) to start at boot.
I give root a password, different than root's password on the host machine. I also add a user, making the user a member of the wheel group so that he will be able to do most of what root does. Remember, a jail is more or less a virtual O/S operating on your host machine, so the commands are the same as they would be on a normal FreeBSD system.
In the jail, I can add packages I want with pkg_add -r. At this point, I just install sudo, bash and apache22.
pkg_add -r sudo bash apache22
(I want bash for the user, as I've gotten used to its features that are lacking in sh, specifically tab completion.)
With sudo installed, I configure the jail's /usr/local/etc/sudoers to allow the user to do what I need done. As this is going to run apache, I make sure that I've put an entry in the jail's /etc/hosts as mentioned above. We're going to call this virtual server apachejail.example.com so my jail's /etc/hosts will have the line
127.0.0.1 apachejail.example.com apachejail
Now I can exit the jail, by simply typing exit at a command prompt.
It's time to restart the jail. I'll be running it at boot, so I add the line mentioned above
You should see a message that the jail has started. Now, I can simply ssh to it as the new user and use sudo to do the rest of the configuration. If my user name in the jail is scott then I would simply do
You might want to add an entry on the host machine's /etc/hosts for the jail.
192.168.1.231 apachejail.example.com apachejail
The jail is now configured. I'm ready to add apache. While in the jail
sudo pkg_add -r apache22
After this, I configure apache. One thing that needs to be done is add the following to the host machine's /boot/loader.conf. (Not the jail's loader.conf).
Otherwise, one gets an error on startup (though apache will still run.)
Like the QND jail page, this isn't a page about apache. My own setup is extremely simple, no php or cgi. I add a line to the jail's /etc/rc.conf
I only make a few changes to the default configuration files. With apache22, rather than a VirtualHosts configuration being in httpd.conf, there's an Include extra/httpd-vhosts.conf file.
Now I'll restart the jail. From the host machine
sudo /usr/local/etc/rc.d/ezjail.sh restart
(Again, that only works if ezjail_enable="YES" is already in /etc/rc.conf. If not then use forcerestart.)
Hopefully, when you start the jail, you will see that apache has also started. You should be able to see httpd running from the host system or while in the jail with top or pgrep.
mount_nullfs /usr/ports /usr/jails/apachejail/usr/ports
Then, I can ssh into the jail, and install ports as I usually would. Once the port is installed, I exit the jail and umount /usr/ports from the jail's /usr/ports.
This is one reason I find it best to run ezjail-admin update as soon as I update a host system. If I've gotten lazy and updated my host system, as well as its ports, mount the ports tree in the jail as detailed above, then, for example, do a portupgrade of apache while within the jail, I've sometimes run into trouble with libexec mismatches.
So, make it a habit to run ezjail-admin update as soon as you've run a make world on the host system.