Linux VSOCK: Operate Host-Guest Services Without an IP Network
Use Linux AF_VSOCK with explicit CIDs, ports, transport checks, reconnect behavior, and application-level validation across guests and hosts.
Linux VSOCK is a socket address family for communication between virtual machines and their host environment. It gives guest agents and hypervisor services a channel that does not depend on the guest’s IP address, route table, or virtual network configuration. This can simplify management traffic, but VSOCK is not a universal tunnel, a guarantee of isolation, or an identical transport across hypervisors. The host, guest kernel, hypervisor, virtual hardware, and application all need compatible support.
The address is a pair: a 32-bit Context Identifier (CID) identifies a host or virtual machine, and a 32-bit port identifies a service. Diagnose a connection by confirming both endpoints, the available transport, and the socket type instead of troubleshooting guest DNS or firewall rules that may have no role in the path.
Addressing and socket semantics
Applications create VSOCK sockets with AF_VSOCK. Stream sockets provide an ordered byte stream when supported by the transport, while datagram support and behavior depend on the underlying hypervisor. As with other socket families, applications bind, listen, accept, connect, send, and receive through normal socket calls, but use sockaddr_vm addresses rather than IP/port tuples.
Well-known CIDs include the hypervisor endpoint and host endpoint, while VMADDR_CID_ANY is useful for a server that accepts connections to any local CID. The exact CID assignment and persistence are hypervisor-specific. CIDs can change during live migration or be allocated according to the host’s virtualization model. A hard-coded CID that worked in a lab may not identify the same peer after migration, cloning, nested virtualization, or namespace configuration changes.
VSOCK ports are service identifiers within a CID. Port allocation should be documented as part of the host/guest service contract, including whether the service binds a fixed port, how conflicts are handled, and how a client discovers its destination. Do not assume the port is an IP port or that an IP firewall rule controls it.
Confirm support at every layer
Start by recording the host hypervisor, guest kernel release, virtual machine configuration, and transport device. Check the kernel configuration for VSOCK support where the distribution exposes it, inspect logs for a registered VSOCK transport, and verify that the guest and host both have the relevant driver. A VSOCK device node or /dev/vsock availability can be a useful clue but does not prove that the desired host-to-guest transport is attached and functional.
Read-only checks may include:
uname -r
lsmod | grep -E 'vsock|virtio'
ls -l /dev/vsock /sys/class/vsock 2>/dev/null
cat /proc/sys/net/vsock/ns_mode 2>/dev/null
These interfaces are optional and vary by kernel build. Built-in drivers will not appear in lsmod. The VSOCK network sysctl files, when present, describe namespace behavior for CIDs, not whether a particular application is listening. Confirm the actual host/guest transport in the hypervisor configuration and kernel logs.
Useful transports include virtio-based VSOCK, VMware’s VMCI transport, and Hyper-V VSOCK support, but availability and semantics depend on kernel and hypervisor versions. Avoid treating the transport implementation as invisible: guest/host feature negotiation, migration support, queue sizing, and connection reset behavior can differ.
Test a controlled endpoint
Build a minimal test before integrating a guest agent. A client and server should log the local CID, peer CID, port, socket type, connect/accept result, and reconnect count. Where Ncat is built with VSOCK support, its --vsock mode can exercise a stream endpoint without writing a test program. Validate the exact syntax against the installed Ncat manual; a generic nc binary may not implement VSOCK.
Use a non-privileged test port selected by the service owner. Start a listener on the intended side, connect from the other side, exchange a known payload, and verify the bytes and peer address. Test both directions if the application depends on host-initiated and guest-initiated connections. Do not bind a production control service to VMADDR_CID_ANY until its authorization and peer-discovery model have been reviewed.
For application tests, include disconnect and restart cases. A stream connection that was established before a guest reboot or migration may no longer be valid. The client should detect EOF or transport errors, re-resolve the destination CID if needed, reconnect with bounded backoff, and avoid replaying non-idempotent operations without an application-level transaction identifier.
Namespace and service boundaries
Linux documents VSOCK behavior in network namespaces, including global and local namespace modes for CID allocation and visibility. Namespace behavior is part of the socket deployment model and can affect which endpoints are reachable. Test from the exact service namespace, not only from the host’s initial network namespace. A container that can open an AF_VSOCK socket may still lack a transport path or permission to communicate with the target service.
Systemd socket activation can be used for VSOCK endpoints on versions that support the relevant address type. Verify the installed systemd version and unit syntax before adopting it. The service must consume the passed listening descriptor as designed, and monitoring should distinguish a socket unit being bound from an application successfully processing requests.
An IP network and a VSOCK channel can coexist. Do not infer that VSOCK has replaced network policy, guest routing, or observability. Decide which classes of traffic belong on which channel, document the CID/port mapping, and monitor connection state at the application layer. VSOCK traffic may not appear in ordinary packet captures of eth0; the appropriate diagnostics are socket-level logs, transport counters, hypervisor telemetry, and service health checks.
Failure patterns and diagnosis
Connection refused. The destination transport may be reachable but no process is listening on the requested CID/port, or the endpoint may have closed. Verify the listener in the correct host or guest and confirm the port and socket type.
Address family or protocol unsupported. The userspace headers, kernel configuration, hypervisor device, or transport module may lack support. Check kernel and hypervisor compatibility rather than changing guest IP networking.
Host can connect but guest cannot. Directionality, listener binding, host/guest endpoint selection, or a transport policy can differ. Confirm which side owns the server and whether the CID is correct from the client’s perspective.
Works before migration but not after. Connected streams may disconnect and local CID assignment may change. Treat reconnection and peer identity as application responsibilities; do not preserve a stale CID indefinitely.
Works in the host namespace but not a container. Inspect the VSOCK network-namespace mode and container device/socket permissions. Confirm the application is in the namespace where the intended CID and transport are visible.
Application data is malformed. VSOCK stream sockets are byte streams, not message boundaries. Implement framing, length validation, timeouts, and backpressure just as with TCP. One send() call is not guaranteed to match one recv() call.
Operational acceptance criteria
For a guest-agent deployment, capture the kernel and hypervisor versions, virtual device configuration, selected transport, local and remote CIDs, service port, and socket type. Test cold boot, guest restart, host restart, migration if supported, service restart, and network reconfiguration. A key test is that the service still behaves as intended while the guest’s IP network is unavailable, if independence from that network is a requirement.
Define timeouts, request framing, authentication, authorization, payload limits, idempotency, and reconnection behavior at the application layer. VSOCK transport reachability is not proof that the peer is trusted or that a request is authorized. Keep host and guest logs correlated by operation ID and monotonic timestamps, and record enough context to identify which CID assignment applied during the operation.
The useful mental model is a hypervisor-mediated socket address family, not a hidden IP interface. It has explicit endpoint identifiers, transport-dependent capabilities, and ordinary stream/datagram application semantics. Validate each layer independently, then test the failure and migration paths that matter for the service.
Related:
- Building an Isolated Network Namespace for Testing
- systemd Socket Activation: Designing a Correct Listener Handoff
Sources: