FreeBSD VNET Jails

tags: bsd · tutorials

This article is also mirrored on the FreeBSD Wiki.

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.

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

if_bridge_load="YES"
if_epair_load="YES"

cloned_interfaces="bridge0"
ifconfig_bridge0="addm re0 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.rules 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

In /etc/jail.conf, we’ll name the jail foo and give it the other end of the epair we’ll create 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):

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
...
# ifconfig epair0 create
# ifconfig bridge0 addm epair0a
# ifconfig epair0a up
# service jail onestart foo

Test to see if the jail has networking:

# jexec foo ping google.com

On jail shutdown, destroy the epair:

# service jail onestop foo
# ifconfig epair0a destroy

Delete jail

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

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

Further reading