NAT Configuration - churchers/vm-bhyve GitHub Wiki
Unfortunately, internal NAT configuration has been removed as of v1.2. As a shell script, we relied on configuring external systems such as pf and dnsmasq to provide NAT functions. Some users want to use other tools/firewalls, and many users found NAT broken due to existing pf or dnsmasq configuration they had in place. It has come to the point where it's arguably easier and less error-prone to manually configure NAT than to try and enable it via vm-bhyve, then manually install/tweak the generated configuration.
Below are some basic instructions for setting up a NAT host with pf for use with vm-bhyve guests.
Host configuration
In this example I have chosen to use the 192.168.8.x
network for my guests, with 192.168.8.1
as the gateway.
We need to enable gateway functionality, so that the host can relay packets between the public and NAT networks. We also need to turn on the pf service. This is done in /etc/rc.conf
gateway_enable="yes"
pf_enable="yes"
We can now create a NAT rule in /etc/pf.conf
to match packets on our private network and perform NAT. Note that in this example, em0
is my public facing interface on the host.
nat on em0 from {192.168.8.0/24} to any -> (em0)
At this point you can restart the host, or start pf and enable forwarding using sysctl
manually if preferred.
# sysctl net.inet.ip.forwarding=1
# service pf start
vm-bhyve
We now need to create a switch that we can attach the guests to. This switch should be assigned an IP address from our NAT range that can be used as the gateway in our guests. I've called this public
, which is the default switch name used in all vm-bhyve
examples, although you may want to use a name that's meaningful in your environment.
# vm switch create -a 192.168.8.1/24 public <-- if creating a new switch
# vm switch address public 192.168.8.1/24 <-- if you already have a switch you want to use
# vm switch list
NAME TYPE IDENT ADDRESS PRIVATE MTU VLAN PORTS
public standard - 192.168.8.1/24 no - - -
You should now be ready to configure guests to use this virtual switch and start them.
Guest config -
network0_type="virtio-net"
network0_switch="public"
Testing local and external network connectivity in the guest -
root@test:~ # cat /etc/rc.conf
...
ifconfig_vtnet0="192.168.8.2/24"
defaultrouter="192.168.8.1"
root@test:~ # ping 192.168.8.1
PING 192.168.8.1 (192.168.8.1): 56 data bytes
64 bytes from 192.168.8.1: icmp_seq=0 ttl=64 time=0.135 ms
^C
--- 192.168.8.1 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.135/0.135/0.135/0.000 ms
root@test:~ # ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=54 time=12.199 ms
^C
--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 12.199/12.199/12.199/0.000 ms
root@test:~ #
DHCP / dnsmasq
Providing DHCP to the guests can be achieved using dnsmasq
. This will need to be installed from ports. A simple config such as below should be enough, based on the same situation as above with the virtual switch called public
and a 192.168.8.x
network range.
port=0
domain-needed
no-resolv
except-interface=lo0
bind-interfaces
local-service
dhcp-authoritative
interface=vm-public
dhcp-range=192.168.8.10,192.168.8.254