# OpenBSD, vmd, openvpn and packet filter
The need: I need to test some custome release of OpenBSD, FreeBSD and VoidLinux.
The answer: OpenBSD has its own hypervisor, vmd, already used by many people around the world, even for production ready services (e.g. openbsd.amsterdam). I need to deploy quickly lot of virtual machine on my laptop to test custom builds and some interconnected services (simulate internal network). Why OpenBSD? Because I removed FreeBSD on my laptop for more than 1 year now, and use only OpenBSD-current on it.
Okay, here a small schema:
__________
| |
| laptop |
| [192.168.1.X/24] [public_ip]
| ______/ | _____ ________ _________/ ________
| | | | ( ) ( ) | | ( )
| | iwm0 |----( local )---( internet )---| openvpn |---( internet )
| |______| | (_____) (________) | server | (________)
| /|\ | |_________|
| __|___ |
| | | |
| | tun0 |---[10.X.Y.Z/24]
| |______| |
| |__
| _________ |
| | | |
| | vether0 |---[172.16.1.1/24]
| |_________| |
| ____|____ |
| | | |
| | bridge0 | |
| |_________| |________________
| ____|_ ____ ____ |
| | | | | | | |
| | tap0 |---| vm | ... | vm | |
| |______| |____| |____| |
|_________\____________________|
[172.16.1.X/24]
# Install OpenBSD
My installation is totally standard. You can how to install openbsd on https://www.openbsd.org.
# Configure OpenVPN
You can read my past article (https://medium.com/@niamtokik/vpn-solution-on-openbsd-hiding-openvpn-with-sslh-12d7cededfca) on this subject. Sorry about medium.com, I need to extract it and create something more... Free and usable.
# Enable services
We will enable all required services at first and start them later.
rcctl enable openvpn # if its not already the case
rcctl enable vmd
rcctl enable dhcpd
# Network Interface Configuration
# Packet Filter Configuration
First thing, I like to create a small organized tree:
mkdir -p /etc/pf.d/tables
mkdir -p /etc/pf.d/anchors
chmod -R 700 /etc/pf.d
I don't want to modify all default configuration on OpenBSD, so, I
will just add an anchor in /etc/pf.conf.
echo "anchor vmd" >> /etc/pf.conf
Ensure your configuration is working and reload it
pfctl -nf /etc/pf.conf && pfctl -f /etc/pf.conf
We can now check if our anchor is ready to use:
pfctl -a vmd -sr
# Configure network interface
I like vether interface, I use them a lot! I think it is not necessary to use them everywhere, but, when you like something you know...
touch /etc/hostname.vether0
echo "inet 172.16.1.1/24" >> /etc/hostname.vether0
echo "up" >> /etc/hostname.vether0
sh /etc/netstart vether0
ifconfig vether0
Now our bridge interface.
touch /etc/hostname.bridge0
echo "add vether0" >> /etc/hostname.bridge0
echo "up" >> /etc/hostname.bridge0
sh /etc/netstart bridge0
ifconfig bridge0
We will use also some forwarding, we need to configure sysctl
sysctl net.inet.ip.forwarding=1
sysctl net.inet6.ip6.forwarding=1
echo "net.inet.ip.forwarding=1" >> /etc/sysctl.conf
echo "net.inet6.ip6.forwarding=1" >> /etc/sysctl.conf
# Configure dhcpd
Well this is pretty straighforward. I use a public DNS service, but you can use yours with unbound.
subnet 172.16.1.1 netmask 255.255.255.0 {
range 172.16.1.32 172.16.1.64;
option routers 172.16.1.1;
options domain-name-servers 1.1.1.1;
}
We can now start dhcpd.
rcctl start dhcpd
# Configure vmd
I like to store everything I need for my vm at the same place:
mkdir -p /home/vmm/disk
mkdir -p /home/vmm/iso
I can now create my virtual disk:
vmctl create -s 10G /home/vmm/disk/openbsd65.qcow2
We need now to edit /etc/vm.conf
vm "openbsd65" {
memory 1G
disk "/home/vmm/disk/openbsd65.qcow2"
interface { switch "uplink" }
cdrom "/home/vmm/iso/openbsd65.iso"
}
switch "uplink" {
interface bridge0
}
seems pretty nice! we can start vmd.
rcctl start vmd
and see if my vm is up and running.
vmctl show
and... attach to the console!
vmctl console openbsd65
# Now the trick
Okay, when I am working somewhere, I like to be connected to my VPN, but sometime, the connection is not usable, so, I switch to the classical way... But, with this configuration, I have some issue with the NAT configuration. I will add only a simple anchor in my packet filter to control it automatically.
When I start my OpenVPN and want to use it for my VM:
echo 'pass out from 172.16.1.0/24 to any nat-to (tun0)' | pfctl -a vmd -f -
When my tunnel is down:
echo 'pass out from 172.16.1.0/24 to any nat-to (iwm0)' | pfctl -a vmd -f -
Nice right? you can also add these function in OpenVPN configuration
(see --up and --down flags).