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]
My installation is totally standard. You can how to install openbsd on https://www.openbsd.org.
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.
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
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
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
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
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
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).