Virtual L2 Networks From Scratch

Intro This is the first article in a three part series focused on self hosting publicly facing services. Virtualization stacks like libvirt, Proxmox, or Docker abstract network creation behind single CLI commands. The abstractions are convenient but hide the kernel primitives used to create virtualized networks. Knowing these primitives makes it easier to understand how virtual machines and containers connect to the host’s network. This post will manually construct an isolated Layer 2 network and connect user space processes using native iproute tooling. ...

September 18, 2026 · 2329 words

Self Hosting Publicly Facing Services

Motivation Online discussions around self hosting public services typically fall into two unhelpful groups. Alarmists will warn that exposing any service guarantees unwanted security intrusions and offer no path forward. The other group offers a recipe. It’s suggested that some Proxmox or Podman command will solve the issue, but what the command does isn’t explained. Both approaches leave the reader without a clear understanding of the network boundaries being created or why they provide protection. ...

September 17, 2026 · 547 words

Uh-oh. Is the router down?

This post is the README for my home network and something I can refer to later. It’s the story of how I replaced a underperforming consumer-grade router with a fully virtualized RouterOS instance using QEMU and PCI passthrough for the network. Like any software project, this project is source controlled and rebuildable from scratch. If the router dies, I simply deploy a new router instance. This is the reproducibility you’d expect in a datacenter, not a home office. ...

November 19, 2025 · 2794 words

Virtual Router Lab on macOS with QEMU

UTM and Multipass are great apps for virtualization on macOS. But I wanted a lighter-weight approach by invoking QEMU directly. Which meant I needed to understand how QEMU’s networking options interact with the vmnet virtualization API on macOS. This becomes especially important when dealing with VM-to-VM connections, network isolation, and bridging on macOS. In this post, I’ll walk through creating a simple QEMU-based networking lab. Set up RouterOS and Alpine Linux VMs using QEMU on macOS Connect VMs with Apple’s Hypervisor vmnet networking APIs Use unified logging to troubleshoot QEMU network issues on macOS Lab Setup Overview The network diagram shows the network topology used in this lab. Both VMs run on on the same macOS host and connected to virtual network interfaces using QEMU’s support for Apple’s vmnet virtualization API. ...

May 14, 2025 · 2097 words

Tips for working with qemu images

QEMU uses files to emulate storage devices, and the features available depend on how those files are created. While QEMU can emulate disks from Parallels and VirtualBox, I’m going to focus on the formats most commonly used in automation and scripting, raw and qcow2. The default format is raw and raw offers the fewest features. It’s just plain storage. The other format qcow2 supports compression, snapshots, and copy-on-write in addition to storage. ...

April 6, 2025 · 1358 words

Unattended Ubuntu Installs - Virtual Machines to Bare-Metal

In a previous post, I discussed using cloud-init and Multipass as a method of provisioning virtual machines on a local computer with a cloud-like API. Today I am going to dive deeper with Ubuntu and how their autoinstall API can simplify on-premise host provisioning. autoinstall is a tool that allows for unattended installations of Ubuntu, ensuring consistency, reporducibility, and providing automation across a fleet of hosts. In this post I’ll walk through an example of using autoinstall to configure networking, local storage, and demonstrate shell command execution during provisioning. ...

March 3, 2025 · 2082 words