BHyVe & jails DHCP/NAT configuration

19-12-2024

Table of Contents

Setup

This is how I configured dhcp and nat for my jails and bhyve vm’s on FreeBSD.

I’m assuming that jailer is used for handling jails, it’s a nice little utility and just writes and parses /usr/local/jails or wherever you prefer having your jails. The reason for this is assumption is that jailer wants to create a bridge0 interface when auto configuring dhcp, so lets just let it do that.

Then when we use vm-bhyve we are suggested by its manual to use dnsmasq but theres no need for this as we already have dhcpd configured for our jails and can piggyback off that by attaching to bridge0.

Initial system configuration

pkg install dhcpd
pkg install vm-bhyve
git clone https://github.com/illuria/jailer

DHCP Configuration

Jailer will create something like this for you when you init dhcp

# cat /usr/local/etc/dhcpd.conf
subnet 10.0.0.0 netmask 255.255.255.0 {
range 10.0.0.2 10.0.0.254;
option subnet-mask 255.255.255.0;
option routers 10.0.0.1;
}

This configuration allows our jails to obtain an IP address from the DHCP server, which in this case is set to 10.0.0.1.

vm-bhyve switch Creation

To create a new vm-bhyve switch, run the following command: vm switch create -t manual -b bridge0 NAT

This will create a new VM switch called NAT. The -t manual flag tells vm-bhyve that we know what we’re doing and the -b bridge0 flag let’s use choose our own existing bridge instead of having a new one created.

pf Configuration

echo 'net.inet.ip.forwarding=1' >> /etc/sysctl.conf
service sysctl restart

This enables IP forwarding on our system.

Edit the /etc/pf.conf file:

# Allow traffic from any IP address to our dhcp range
nat on $default_interface from 10.0.0.0/24 to any -> ($default_interface)

set skip on bridge0
pass in quick on 10.0.0.0/24 to any

Make sure the nat on line isn’t after your defaults block in; pass out. reload pf with pfctl -f /etc/pf.conf

tl;dr

pkg install vm-bhyve dhcpd
sysrc gateway_enable="YES"
sysrc pf_enable="YES"
sysrc vm_enable="YES"
echo 'net.inet.ip.forwarding=1' >> /etc/sysctl.conf
service sysctl restart
echo "nat on $default_interface from {10.0.0.0/24} to any ->
default_interface=$(route get default | grep interface | cut -w -f 3)
($default_interface)" >> /etc/pf.conf
echo "set skip on bridge0" >> /etc/pf.conf
echo "pass in quick on 10.0.0.0/24 to any" >> /etc/pf.conf
pfctl -f /etc/pf.conf
git clone https://github.com/illuria/jailer
jailer init
jailer init bridge
jailer init dhcp
cd /usr/local/vm
vm init
vm switch create -t manual -b bridge0 NAT
echo 'network0_type="virtio-net"' >> /usr/local/vm/guest/guest.conf
echo 'network0_switch="NAT"' >> /usr/local/vm/guest/guest.conf