Network Configuration Options for vphone-cli Virtual Machines

vphone-cli supports three distinct network modes for virtual machines—NAT (default), bridged, and off (none)—each realized through Apple's Virtualization.framework using specific attachment classes.

vphone-cli is a command-line interface for managing virtual machines on macOS using Apple's native Virtualization.framework. The network configuration is defined in VPhoneVirtualMachineManifest.NetworkConfig and materialized by VPhoneNetworking.makeNetworkDevice, allowing precise control over how guest operating systems access network resources.

How Network Configuration Works in vphone-cli

The networking stack in vphone-cli relies on two primary components. The manifest structure in sources/vphone-cli/VPhoneVirtualMachineManifest.swift (lines 52-55) declares the configuration options, while the core networking logic in sources/VPhoneCore/VPhoneNetworking.swift (lines 96-116) validates these settings and constructs the actual virtual network device.

When a VM starts, the networkConfig property from the manifest is passed to VPhoneNetworking.makeNetworkDevice, which returns an optional VZNetworkDeviceConfiguration. This design allows the system to return nil for isolated VMs while attaching VZVirtioNetworkDeviceConfiguration instances for connected modes.

Available Network Modes

vphone-cli implements three operational network modes, each corresponding to a specific Virtualization.framework attachment class.

NAT Mode (Default)

NAT mode is the default configuration where the VM receives a NAT-backed virtual NIC. Outbound traffic is automatically translated to the host's IP address, while inbound connections require explicit port forwarding or tunneling.

In sources/VPhoneCore/VPhoneNetworking.swift (lines 101-104), this mode attaches a VZNATNetworkDeviceAttachment to a VZVirtioNetworkDeviceConfiguration. The MAC address is auto-generated if not specified in the manifest.

Bridged Mode

Bridged mode connects the virtual machine directly to a physical host interface (Ethernet or Wi-Fi), causing the guest to appear as a distinct host on the local network with its own IP address.

This configuration uses VZBridgedNetworkDeviceAttachment (lines 113-115 in VPhoneNetworking.swift). The optional bridgeInterface field specifies which host interface to use; if omitted, resolveBridgeInterface (lines 52-66) automatically selects the first available bridgeable interface discovered via VZBridgedNetworkInterface.networkInterfaces (lines 44-45). This discovery requires the com.apple.vm.networking entitlement.

Off (None) Mode

Off mode (exposed as none in the CLI) creates a completely isolated VM with no network connectivity. In this configuration, makeNetworkDevice returns nil (lines 97-98), and no network device is attached to the virtual machine configuration.

Configuring the Network via Command Line

The CLI parsing logic in sources/vphone-cli/VPhoneVMCLI.swift (lines 138-163) handles network configuration through two primary flags:

  • -n, --network <mode> — Accepts nat, bridged, or none (mapped to off internally)
  • --bridge-interface <iface> — Required when using --network bridged; validates the specified interface name against available bridgeable interfaces

During VM creation in sources/vphone-cli/VPhoneVirtualMachine.swift (lines 188-191), these parsed options are applied to the manifest's networkConfig before the virtualization session begins.


# Create a VM with default NAT networking

vphone-cli vm create --name MyVM --cpu 2 --memory 2048

# Bridge to the first available interface

vphone-cli vm create --name MyVM --network bridged

# Bridge to a specific host interface (e.g., en0)

vphone-cli vm create --name MyVM --network bridged --bridge-interface en0

# Create an isolated VM with no network device

vphone-cli vm create --name MyVM --network none

Programmatic Network Configuration

Developers can configure networking programmatically using the VPhoneVirtualMachineManifest.NetworkConfig struct.

import VPhoneCore

// NAT configuration (default behavior)
let natManifest = VPhoneVirtualMachineManifest(
    cpuCount: 4,
    memorySize: 4_294_967_296,  // 4 GiB
    networkConfig: .default      // Implicitly uses NAT mode
)

// Bridged configuration with specific interface
let bridgedConfig = VPhoneVirtualMachineManifest.NetworkConfig(
    mode: .bridged,
    macAddress: "",             // Auto-assigned
    bridgeInterface: "en0"      // Target host interface
)
let bridgedManifest = VPhoneVirtualMachineManifest(
    cpuCount: 2,
    memorySize: 2_147_483_648,
    networkConfig: bridgedConfig
)

// Isolated configuration (no network)
let isolatedConfig = VPhoneVirtualMachineManifest.NetworkConfig(
    mode: .off,
    macAddress: ""
)
let isolatedManifest = VPhoneVirtualMachineManifest(
    cpuCount: 2,
    memorySize: 1_073_741_824,
    networkConfig: isolatedConfig
)

Network Configuration Limitations

A host-only networking mode is explicitly not supported in vphone-cli. Apple’s Virtualization.framework does not provide a host-only attachment type, and attempting to configure this mode triggers a fatal error in sources/VPhoneCore/VPhoneNetworking.swift (lines 78-79).

Additionally, bridged mode requires the com.apple.vm.networking entitlement and appropriate user permissions to access the host's network interfaces.

Summary

  • NAT mode (default) provides outbound internet access through address translation using VZNATNetworkDeviceAttachment
  • Bridged mode exposes the VM as a physical host on the LAN via VZBridgedNetworkDeviceAttachment, with automatic or manual interface selection
  • Off/None mode completely isolates the VM by returning nil from the network device factory
  • Configuration is controlled via --network and --bridge-interface CLI flags or programmatically through VPhoneVirtualMachineManifest.NetworkConfig
  • Host-only networking is unsupported due to framework limitations

Frequently Asked Questions

How do I set up a static IP address for my vphone-cli VM?

vphone-cli does not manage IP assignment within the guest. For static IPs, configure the guest operating system's network settings internally. In bridged mode, configure the static IP to match your LAN's subnet; in NAT mode, use the subnet assigned by the Virtualization.framework DHCP server (typically 192.168.64.0/24).

Why does bridged mode fail with a network interface error?

Bridged mode requires the com.apple.vm.networking entitlement and explicit user approval for network access. The error typically occurs when the specified --bridge-interface does not exist in VZBridgedNetworkInterface.networkInterfaces (lines 44-45 in VPhoneNetworking.swift). Verify the interface name using ifconfig and ensure you have granted network permissions to the vphone-cli binary.

Can I change the network mode of an existing VM?

According to the source architecture in VPhoneVirtualMachineManifest.swift and VPhoneVirtualMachine.swift, network configuration is part of the manifest applied during VM creation (lines 188-191). To change modes, you must recreate the VM with the desired networkConfig or modify the manifest file before starting the VM.

Is there a way to enable port forwarding in NAT mode?

The provided source code in VPhoneNetworking.swift uses standard VZNATNetworkDeviceAttachment without custom port forwarding rules. Advanced NAT configuration would require extending the makeNetworkDevice function to utilize Virtualization.framework's port forwarding APIs, which are not currently implemented in the analyzed codebase.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →