Skip to content

Set up vimage/vnet jail on FreeBSD 8.2

With epair, there are two interfaces created epair0a and eapir0b that are direct connections between each other (like an Ethernet cable). When used with jails using an ifconfig vnet command, one side (epair0b for example) sgoes inside the jail. Since the other side of this virtual direct-connection stays on the outside of the jail, the epair pairs act as an Ethernet tunnel inside/outside the jail. You can use firewall rules either outside the jail or inside the jail to control traffic.

I’m using ezjail-admin with the following patch to /etc/rc.d/jail (taken from the FreeBSD Forums):

<               eval ${_setfib} jail ${_flags} -i ${_rootdir} ${_hostname} \
<                       \"${_addrl}\" ${_exec_start} > ${_tmp_jail} 2>&1
>               if [ -z "${_addrl}" ] ; then

>                       eval ${_setfib} jail -i ${_flags} path=${_rootdir} host.hostname=${_hostname} \
>                               command=${_exec_start} > ${_tmp_jail} 2>&1
>               else
>                       eval ${_setfib} jail -i ${_flags} ${_rootdir} ${_hostname} \
>                                 \"${_addrl}\" ${_exec_start} > ${_tmp_jail} 2>&1
>               fi

For example, I have two jails. I create the interfaces like so in /etc/rc.conf:

# ezjail with vimage/epair config
cloned_interfaces="epair0 epair1 bridge0"
ifconfig_bridge0="name jailbridge addm re0 up"

On the inside of the jail, I just need to set the IP address of the epair0b and epair1b interfaces. I'm using ezjail Here's a sample /usr/local/etc/ezjail/<jail_name>, in this case for a subsonic server:

# To specify the start up order of your ezjails, use these lines to
# create a Jail dependency tree. See rcorder(8) for more details.
# PROVIDE: standard_ezjail

# vnet stuff:
export jail_subsonic_flags="-c vnet name=subsonic"
#export jail_subsonic_exec_prestart0="ifconfig epair0 create"
#export jail_subsonic_exec_prestart1="ifconfig epair0a up"

# sometiems rc.conf doesn't do this:
export jail_subsonic_exec_prestart0="ifconfig jailbridge addm re0"
export jail_subsonic_exec_prestart1="ifconfig jailbridge addm epair0a up"
export jail_subsonic_exec_prestart2="mount_nullfs -o ro /tank/music /usr/jails/subsonic/var/music"
export jail_subsonic_exec_prestart3="mount_nullfs -o rw /tank/music/Playlists /usr/jails/subsonic/var/playlists"

export jail_subsonic_exec_poststart0="ifconfig epair0b vnet subsonic"
#export jail_subsonic_exec_poststart1="jexec subsonic /etc/rc.d/ipfw start"
export jail_subsonic_exec_poststart1="jexec subsonic ifconfig lo0"
export jail_subsonic_exec_poststart2="jexec subsonic ifconfig epair0b netmask"
export jail_subsonic_exec_poststart3="jexec subsonic route add default"
export jail_subsonic_exec_poststop0="umount /usr/jails/subsonic/var/music"
export jail_subsonic_exec_poststop1="umount /usr/jails/subsonic/var/playlists"

export jail_subsonic_hostname="subsonic"
export jail_subsonic_ip=""
export jail_subsonic_rootdir="/usr/jails/subsonic"
export jail_subsonic_exec_start="/bin/sh /etc/rc"       # /bin/sh /etc/rc by default
export jail_subsonic_exec_stop=""
export jail_subsonic_mount_enable="YES"
export jail_subsonic_devfs_enable="YES"
export jail_subsonic_devfs_ruleset="devfsrules_jail2"
export jail_subsonic_procfs_enable="NO"
export jail_subsonic_fdescfs_enable="NO"
export jail_subsonic_image=""
export jail_subsonic_imagetype=""
export jail_subsonic_attachparams=""
export jail_subsonic_attachblocking=""
export jail_subsonic_forceblocking=""
export jail_subsonic_zfs_datasets=""
export jail_subsonic_cpuset=""
export jail_subsonic_fib=""

Also, don't forget that you need something like the following within your jail's /etc/resolv.conf:


I'm using FreeBSD's IPFW. I have it set up so that it by default passes all packets. I can then control all firewall rules from the host (rather than in the jail). The last line of my host rules is a deny all to implementing the blocking on the host. I leave default rules within the jails (with epair/vnet each jail gets its own firewall rules). I have things set up like:

oif="re0"       # out interface
jail_brif="jailbridge"  # jail interface
subsonic_ip="" # jail IP
cmd="/sbin/ipfw -q add "


$cmd 02000 allow ip from any to any via $oif
$cmd 03300 allow log icmp from $ipdns to $subsonic_ip $ks
$cmd 03310 allow log icmp from $ipdns to $jabber_ip $ks
$cmd 03350 allow log icmp from $subsonic_ip to $ipdns $ks
$cmd 03355 allow log icmp from $jabber_ip to $ipdns $ks
# DNS:
$cmd 03400 allow udp from $subsonic_ip to $ipdns 53 $ks
# subsonic:
$cmd 04500 allow ip from any to $subsonic_ip dst-port 8180 setup $ks
# allow scrobbling (etc):
$cmd 06600 allow log ip from $subsonic_ip to any dst-port 80 setup $ks
$cmd 06700 allow log ip from $subsonic_ip to any dst-port 443 setup $ks
$cmd 65500 deny log ip from any to any

It's been a while since I set this up, and I'm not sure if the allow all on $oif (command 02000) is really necessary.

2 people like this post.

Post a Comment

Your email is never published nor shared. Required fields are marked *