FreeBSD VNET Jails

Tags:  bsd

Configuration

The VNET is set up using an if_epair(4) interface bridged with the actual network interface, in my case re0. Just like if_tap(4) interfaces, epairs can be used by one jail at a time, so if you need to run more than one jail at the same time, you have to make more epairs.

If you’re using tap interfaces for bhyve VMs, you can just addm them to the bridge. I found that having more than 1 bridge doesn’t work.

Add the following lines to /etc/rc.conf:

jail_enable="YES"
jail_parallel_start="YES"
jail_reverse_stop="YES"

if_bridge_load="YES"
if_epair_load="YES"

cloned_interfaces="bridge0 epair0"
ifconfig_bridge0="addm re0 addm epair0a up"
ifconfig_epair0a="up"

Apply changes:

# /etc/netstart

The jail needs to inherit /dev/bpf* from the host in order for networking to work at all. Make a new /etc/devfs.conf ruleset:

[devfsrules_jails=5]
add include $devfsrules_hide_all
add include $devfsrules_unhide_basic
add include $devfsrules_unhide_login
add path 'bpf*' unhide

Restart devfs(8):

# service devfs restart

We’ll name this jail foo and give it the other end of the epair as its network interface. Its IP address will be acquired using DHCP. The reason I’m manually calling dhclient(8) is because adding ifconfig_epair0b="DHCP" in the jail’s /etc/rc.conf doesn’t work. Options are detailed in jail.conf(5).

/etc/jail.conf:

path = "/usr/local/jail/$name";
host.hostname="$name";

exec.clean;
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
allow.mount;
allow.raw_sockets = 1;
mount.devfs;
devfs_ruleset="5";
vnet;
sysvmsg=new;
sysvsem=new;
sysvshm=new;

foo {
	vnet.interface = "epair0b";
	exec.start += "dhclient epair0b";
}

Installation

# mkdir -p /usr/local/jail/foo
# bsdinstall jail /usr/local/jail/foo
...
# service jail start foo

Test to see if the jail has networking:

# jexec foo ping google.com

Delete jail

Deleting jails isn’t as straight forward, so I’m leaving this here as well:

# service jail stop foo
# chflags -R noschg /usr/local/jail/foo
# rm -rf /usr/local/jail/foo

Further reading