Overview
Hatch sets up a full Linux networking stack on the host before Firecracker starts. Each networked VM gets its own TAP device connected to a shared bridge, a pre-allocated IP address served via DHCP, and cloud-init configuration injected directly into the rootfs.All networking setup happens on the host before the VM boots. The guest sees a standard Ethernet interface with DHCP — no manual configuration required.
Network Components
Bridge (fcbr0)
Layer 2 virtual switch shared across all VMs, gets gateway IP 172.16.0.1
TAP Device
One per VM (
fctap-<vmid>), plugged into bridge as a port, other end held by Firecrackerdnsmasq
DHCP server listening on bridge, serves deterministic IP allocations
Network Setup Flow
When a VM is created withenable_network: true, the following steps occur:
Ensure bridge exists
Create Linux bridge
fcbr0 (if not already present) and assign it the gateway IP from HATCH_BRIDGE_CIDR (default: 172.16.0.1/24)Allocate IP and MAC
The IP allocator picks the next free IP from the bridge subnet (starting at .2, wrapping at .254). A random MAC address is generated with locally-administered bit set.
Create TAP device
Create a TAP interface named
fctap-<first8chars-of-vmid> and plug it into the bridgeRegister DHCP reservation
Write MAC → IP mapping to dnsmasq’s hosts file and signal it to reload with SIGHUP
Inject cloud-init seed
Loop-mount the VM’s rootfs and write network-config to
/var/lib/cloud/seed/nocloud/DHCP Flow
The DHCP process is deterministic — the IP is pre-decided on the host before the VM boots:dnsmasq startup configuration
dnsmasq startup configuration
NAT and Internet Access
VMs reach the internet via NAT (masquerading) through the host’s real NIC:SSH Port Forwarding
Each networked VM gets a dedicated host port in the rangeHATCH_SSH_PORT_MIN – HATCH_SSH_PORT_MAX (default: 16000–17000). This port is forwarded to the guest’s SSH daemon on port 22 using iptables DNAT.
SSH Connection Path
Wake-on-SSH
The SSH Gateway listens on all active SSH ports. When a connection arrives:- Look up VM by SSH port
- If VM is snapshotted, restore it (client sees slow handshake, ~2-5 seconds)
- Once running, create bidirectional TCP pipe to
guest_ip:22
cloud-init Network Configuration
Hatch uses the NoCloud datasource by writing seed files directly into the rootfs at/var/lib/cloud/seed/nocloud/. This avoids the need for a separate cidata ISO/vfat drive and works with minimal kernels that lack vfat/iso9660 support.
TAP Device Lifecycle
TAP devices persist on the host even after Firecracker exits. Hatch cleans them up explicitly on VM deletion and performs full reconciliation on startup.
Cleanup on VM Delete
Startup Reconciliation
On daemon startup, Hatch removes allfctap-* devices:
Network Resource Allocation
IP Allocator
TheIPAllocator maintains an in-memory map of allocated IPs and cycles through the subnet:
- Range:
.2to.254(.1is the gateway,.0and.255reserved) - Algorithm: Round-robin with skip-if-in-use
- Thread-safe: Protected by
sync.Mutex
SSH Port Allocator
The Manager maintains a map ofport → vm_id to prevent collisions:
Troubleshooting
VM not getting IP from DHCP
VM not getting IP from DHCP
- Check dnsmasq logs:
cat /data/dhcp/dnsmasq.log - Verify DHCP reservation:
cat /data/dhcp/hostsshould contain<mac>,<ip> - Check bridge is up:
ip link show fcbr0 - Verify TAP is plugged into bridge:
ip link show fctap-<vmid> | grep master
SSH connection refused
SSH connection refused
- Check iptables DNAT rule exists:
iptables -t nat -L PREROUTING -n -v | grep <ssh_port> - Verify guest sshd is running:
ssh -p <ssh_port> user@hostand check cloud-init logs in guest - Check FORWARD chain allows traffic:
iptables -L FORWARD -n -v | grep <guest_ip>
No internet access from VM
No internet access from VM
- Check NAT rule:
iptables -t nat -L POSTROUTING -n -v | grep 172.16.0.0/24 - Verify FORWARD rules are inserted (not appended):
iptables -L FORWARD -n --line-numbers - Check guest has default route:
ip routein guest should showdefault via 172.16.0.1