# BHyVe & jails DHCP/NAT configuration

19-12-2024

<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->
**Table of Contents**

- [BHyVe & jails DHCP/NAT configuration](#bhyve--jails-dhcpnat-configuration)
    - [Setup](#setup)
    - [Initial system configuration](#initial-system-configuration)
        - [DHCP Configuration](#dhcp-configuration)
        - [vm-bhyve switch Creation](#vm-bhyve-switch-creation)
        - [pf Configuration](#pf-configuration)
- [tl;dr](#tldr)

<!-- markdown-toc end -->

## Setup

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

I'm assuming that [jailer](https://github.com/illuria/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
```
