-
-
Notifications
You must be signed in to change notification settings - Fork 762
Description
Feature Request: Bridged Networking Support (--network bridged)
Summary
Add support for bridged networking as an alternative to the current NAT-only networking. This would allow VMs to get their own IP address directly on the LAN via DHCP, bypassing the host's routing table entirely.
Problem
Lume currently hardcodes VZNATNetworkDeviceAttachment() as the only networking mode. NAT networking relies on the host's vmnet NAT daemon and routing table to provide connectivity to the VM. This creates a critical reliability problem when anything on the host modifies the routing table — most commonly a VPN client.
Real-world scenario: VPN breaks VM networking
- User starts a Lume VM — networking works fine via NAT (vmnet)
- User connects to a VPN (e.g. NordVPN, Cisco AnyConnect, OpenVPN) on the host
- VPN client overwrites the host's routing table to route traffic through the VPN tunnel
- VM immediately loses all network connectivity — the vmnet NAT gateway is no longer reachable through the modified routes
- User disconnects VPN — VM networking does NOT recover. The vmnet NAT daemon doesn't automatically restore its routing entries
- Only fix: reboot the host, or manually restart vmnet daemons (
sudo pfctl -F all && sudo killall -HUP vmnet-natd && sudo killall -HUP bootpd)
This is particularly painful for users running always-on VMs (e.g. development servers, AI agent sandboxes, CI runners) on machines that also need occasional VPN access.
Why NAT-only is limiting
- VPN incompatibility: As described above, any VPN that modifies routing breaks VM networking, often irreversibly until reboot
- No split tunneling: Many corporate VPN clients (NordVPN macOS, Cisco AnyConnect) don't support split tunneling, making it impossible to exclude vmnet traffic
- No direct LAN access: Other devices on the network can't reach the VM directly (e.g. for testing network services, IoT development)
- Port forwarding complexity: Exposing VM services to the LAN requires manual port forwarding on the host
Proposed Solution
Add a --network option to lume run (and lume create) that supports:
# Current behavior (default)
lume run my-vm --network nat
# New: bridged networking
lume run my-vm --network bridged
# New: bridged to a specific interface
lume run my-vm --network bridged:en0How Virtualization.framework supports this
Apple's Virtualization.framework already provides everything needed:
1. VZBridgedNetworkDeviceAttachment — the bridged equivalent of VZNATNetworkDeviceAttachment
// Current code (libs/lume/src/Virtualization/VMVirtualizationService.swift:134-143)
static func createNetworkDeviceConfiguration(macAddress: String) throws
-> VZNetworkDeviceConfiguration
{
let network = VZVirtioNetworkDeviceConfiguration()
guard let vzMacAddress = VZMACAddress(string: macAddress) else {
throw VMConfigError.invalidMachineIdentifier
}
network.attachment = VZNATNetworkDeviceAttachment() // ← hardcoded NAT
network.macAddress = vzMacAddress
return network
}The change to support bridged:
static func createNetworkDeviceConfiguration(
macAddress: String,
networkMode: NetworkMode = .nat
) throws -> VZNetworkDeviceConfiguration {
let network = VZVirtioNetworkDeviceConfiguration()
guard let vzMacAddress = VZMACAddress(string: macAddress) else {
throw VMConfigError.invalidMachineIdentifier
}
switch networkMode {
case .nat:
network.attachment = VZNATNetworkDeviceAttachment()
case .bridged(let interfaceName):
guard let interface = VZBridgedNetworkInterface.networkInterfaces.first(where: {
interfaceName.map { name in $0.identifier == name } ?? true
}) else {
throw VMConfigError.noBridgeInterfaceFound
}
network.attachment = VZBridgedNetworkDeviceAttachment(interface: interface)
}
network.macAddress = vzMacAddress
return network
}2. VZBridgedNetworkInterface.networkInterfaces — discover available host interfaces
This static property returns all bridgeable network interfaces on the host. Could be exposed via:
lume config network interfaces # List available interfaces for bridging3. Entitlement requirement: com.apple.vm.networking
This is the main effort. Bridged networking requires the com.apple.vm.networking entitlement, which is a restricted entitlement that must be:
- Requested from Apple (via Apple Developer representative or DTS TSI)
- Authorized via a provisioning profile
- Code-signed into the binary
The current entitlements file (libs/lume/resources/lume.entitlements) only has:
<key>com.apple.security.virtualization</key>
<true/>It would need:
<key>com.apple.security.virtualization</key>
<true/>
<key>com.apple.vm.networking</key>
<true/>Important notes about this entitlement:
- NAT and host-only networking do NOT require this entitlement (current behavior is fine)
- Only bridged mode requires it
- It cannot be prototyped without the entitlement (unlike vmnet's bridged mode which works as root) —
VZVirtualMachineConfiguration.validate()will fail - Apple's process: request via Apple Developer representative (docs)
- Other tools like UTM have obtained this entitlement for their App Store distribution
4. VM config persistence
Store the network mode in the VM config (VMConfig), so it persists across restarts:
{
"networkMode": "nat", // or "bridged" or "bridged:en0"
"macAddress": "..."
}Suggested Implementation Plan
- Add
NetworkModeenum —nat|bridged(interface: String?) - Add
--networkCLI option toRun.swiftandCreate.swift - Modify
createNetworkDeviceConfiguration()inVMVirtualizationService.swiftto accept network mode - Add
lume config network interfacessubcommand to list bridgeable interfaces - Persist network mode in
VMConfig/VMConfig.swift - Request
com.apple.vm.networkingentitlement from Apple - Update entitlements file and signing configuration
- Add documentation for the
--networkflag and bridged networking setup
Steps 1-5 are straightforward code changes. Step 6 is the main blocker and should be initiated early since Apple's process takes time.
Relevant Source Files
| File | What to change |
|---|---|
libs/lume/src/Virtualization/VMVirtualizationService.swift |
createNetworkDeviceConfiguration() — add bridged attachment support |
libs/lume/src/Commands/Run.swift |
Add --network option |
libs/lume/src/Commands/Create.swift |
Add --network option |
libs/lume/src/FileSystem/VMConfig.swift |
Add networkMode field |
libs/lume/resources/lume.entitlements |
Add com.apple.vm.networking |
libs/lume/src/VM/VM.swift |
Pass network mode through to virtualization service |