<h2 id="freebsd-jails-with-iocage">FreeBSD Jails with iocage</h2>
<h3 id="introduction">Introduction</h3>
<p>FreeBSD jails allow users to run multiple, isolated instances of FreeBSD on a single server. Iocage simplifies the management of FreeBSD Jails.</p>
<p><a href="https://en.wikipedia.org/wiki/OS-level_virtualization">https://en.wikipedia.org/wiki/OS-level_virtualization</a></p>
<p>The jails will be configured to bind to an IP address on the jail host's internal network. The host OS will pass traffic from the external network to the jail.</p>
<p>The jails will be managed with Iocage. Iocage uses ZFS properties to store configuration data for each jail, so a ZFS file system is required.</p>
<h3 id="network-setup">Network setup</h3>
<p>These steps will:</p>
<ol>
<li>Set up the internal network.</li>
<li>Enable the <strong>pf</strong> packet filter</li>
<li>Configure pf pass internet traffic to and from the jail.</li>
</ol>
<p>PF is full featured firewall, and can do more than just pass traffic to an internal network. Refer to the PF documentation for additional configuration options.</p>
<h4 id="run-the-following-to-configure-the-internal-network-and-enable-pf">Run the following to configure the internal network and enable pf.</h4>
<pre><code>sysrc cloned_interfaces+=&quot;lo1&quot;
sysrc ifconfig_lo1=&quot;inet 192.0.2.1/24&quot;
sysrc pf_enable=&quot;YES&quot;
</code></pre>
<h4 id="put-the-following-in-etcpfconf">Put the following in <code>/etc/pf.conf</code></h4>
<pre><code># Variables
# ext_if should be set to the hosts external NIC
ext_if = &quot;vtnet0&quot;
jail_if = &quot;lo1&quot;
jail_net = $jail_if:network

# NAT allows the jails to access the external network
nat on $ext_if from $jail_net to any -&gt; ($ext_if)

# Redirect traffic on port 80 to the web server jail
# Add similar rules for additional jails
rdr pass on $ext_if inet proto tcp to port 80 -&gt; 192.0.2.10
</code></pre>
<p><em>Reboot</em> to activate the network changes</p>
<h3 id="zfs">ZFS</h3>
<p>The best way to use ZFS on a VPS is to attach block storage as a new disk.</p>
<p>If block storage is not available, you can optionally use a file as the ZFS device.</p>
<h4 id="enable-and-start-zfs">Enable and start ZFS.</h4>
<pre><code>sysrc zfs_enable=&quot;YES&quot;
service zfs start
</code></pre>
<h4 id="zfs-using-block-storage">ZFS using Block storage</h4>
<p>List the available disks. If you are using a VPS, the block store will probably be the second disk.</p>
<pre><code>geom disk list
</code></pre>
<p>Create a ZFS pool named jailstore.</p>
<pre><code>zpool create jailstore  /dev/vtbd1
</code></pre>
<h4 id="zfs-using-a-file">ZFS using a file</h4>
<p>Create the ZFS file.</p>
<pre><code>dd if=/dev/zero of=/zfsfile bs=1M count=4096
</code></pre>
<p>Create a ZFS pool named jailstore.</p>
<pre><code>zpool create jailstore /zfsfile
</code></pre>
<h3 id="install-iocage">Install iocage</h3>
<pre><code>pkg install py36-iocage
</code></pre>
<h3 id="using-iocage">Using iocage</h3>
<pre><code>iocage activate jailstore
iocage fetch

iocage create -n www ip4_addr=&quot;lo1|192.0.2.10/24&quot; -r 11.1-RELEASE
iocage start www
iocage console www
</code></pre>
<p>Once you have a shell <strong>inside the jail</strong>, install and start Apache.</p>
<pre><code>pkg install apache24
sysrc apache24_enable=&quot;yes&quot;
service apache24 start
</code></pre>
<p>Port 80 on the jail will now be accessible on the hosts IP address.</p>
<h3 id="multiple-jails">Multiple jails.</h3>
<p>Additional jails can be installed using the example above.</p>
<ol>
<li>Install the new jail with the <code>iocage create</code> command , but use a different IP address</li>
<li>Expose the new jail to the network by adding additional rules to pf.conf.</li>
</ol>
<h3>Book recommendation</h3>
<ul>
<li><a href="https://www.tiltedwindmillpress.com/product/fmjail"><em>FreeBSD Mastery: Jails</em>, Michael W Lucas</a><br/>
Michael W Lucas is great Technical book author.</li>
</ul>
