my configuration
My setup is rather simple, it's ezjail on top of ZFS with separate filesystem for every jail. I am using packet filter to redirect traffic to jails.
In this example we will create two jails:
- ns - as for Name Server
- www - as for Web Server
install ezjail and tweak basic settings
cd /usr/ports/sysutils/ezjail && make install clean
edit /usr/local/etc/ezjail.conf:
ezjail_jaildir=/jails
ezjail_use_zfs="YES"
ezjail_use_zfs_for_jails="YES"
ezjail_jailzfs="zroot/jails"
ezjail_zfs_properties="-o atime=off"
ezjail_ftphost=ftp.XX.freebsd.org
Do not start it yet, we still have to setup few things.
1. Configure loopback devices for every jail:
ifconfig lo1 create
ifconfig lo1 alias 10.0.0.1 netmask 255.255.255.255 up
ifconfig lo2 create
ifconfig lo2 alias 10.0.0.2 netmask 255.255.255.255 up
2. Add it to /etc/rc.conf:
echo 'cloned_interfaces="lo1 lo2"' >> /etc/rc.conf
echo 'ifconfig_lo1_alias0="inet 10.0.0.1 netmask 255.255.255.255"' >> /etc/rc.conf
echo 'ifconfig_lo2_alias0="inet 10.0.0.2 netmask 255.255.255.255"' >> /etc/rc.conf
3. Update /etc/hosts:
echo "10.0.0.1 ns" >> /etc/hosts
echo "10.0.0.2 www" >> /etc/hosts
4. Create jail flavour if needed (I bet it is, helps to deploy settings to future jails) - as it will copy the whole structure to newly created jail.
mkdir -p /jails/flavours/thinkunix/etc/
cp /etc/hosts /jails/flavours/thinkunix/etc/
cat << EOF > /jails/flavours/thinkunix/etc/rc.conf
sendmail_enable="NONE"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
cron_flags="$cron_flags -J 1800"
EOF
echo "nameserver 10.0.0.1" > /jails/flavours/thinkunix/etc/resolv.conf
cp /etc/localtime /jails/flavours/thinkunix/etc/
touch /jails/flavours/thinkunix/etc/motd
5. Enable ezjail in /etc/rc.conf and start it:
echo 'ezjail_enable="YES"' >> /etc/rc.conf
service ezjail start
6. Last, but not least, create zfs filesystem for jails:
zfs create zroot/jails
Creating jails
Now, when your ezjail is running you can actually create first jail. Note that I'll use my 'thinkunix' flavour to propagate configuration files to jails.
ezjail-admin create -f thinkunix ns 10.0.0.1
ezjail-admin create -f thinkunix www 10.0.0.2
ezjail-admin start ns
ezjail-admin start www
Now you may connect to your jail to check if everything works as expected:
ezjail-admin console ns
Network access for jails
In order to provide network access to your jails we have to set up two things:
1. enable ip forwarding:
sysctl net.inet.ip.forwarding=1
echo "net.inet.ip.forwarding=1" >> /etc/sysctl.conf
2. Configure packet filter.
Config is simple and pretty self-explanatory:
# Macros:
ext_if="em0"
ext_ip="XXX.XXX.XXX.XXX" # your external IP address
jail_net="10.0.0.0/24"
# JAIL IPs:
ns_ip="10.0.0.1"
www_ip="10.0.0.2"
# enable NAT - needed for rdr rules
nat pass on $ext_if from $jail_net to any -> $ext_ip
# jail redirects
rdr pass on $ext_if proto { tcp, udp } from any to $ext_ip port 53 -> $ns_ip
rdr pass on $ext_if proto tcp from any to $ext_ip port 953 -> $ns_ip
rdr pass on $ext_if proto tcp from any to $ext_ip port 80 -> $www_ip
3. Start firewall:
For safety reasons - in case your server is remote and you do not have console access - I recommend checking syntax and using tmux or screen to test and load packet filter rules.
pfctl -nf /etc/pf.conf <-- that will test syntax without loading ruleset yet.
tmux
pfctl -ef /etc/pf.conf; sleep 120; pfctl -d
In case you cut yourself out of the system in 2 minutes rules will be unloaded.