Skip to content

Instantly share code, notes, and snippets.

@niamtokik
Last active May 10, 2020 13:54
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niamtokik/7bbf042b57af67b6ffe5d6692d875a4f to your computer and use it in GitHub Desktop.
Save niamtokik/7bbf042b57af67b6ffe5d6692d875a4f to your computer and use it in GitHub Desktop.
OpenBSD Laptop with vmd, pf and openvpn

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment