All posts

KubeVirt, VSOCK, and eBPF: who does what?

A beginner’s guide to virtual machines, host–guest communication, and where eBPF can enforce isolation.

KubeVirt manages virtual machines. VSOCK lets a host and a guest communicate. eBPF can add checks inside the Linux kernel. These tools solve different problems; none replaces the others.

The interesting question is what happens when a VM needs a management channel, but the person inside it has administrator access.

First, what is a virtual machine?

  • The host is the machine running the virtualization software.
  • A guest is an operating system running inside a virtual machine (VM).
  • The kernel is the core of an operating system. It manages memory, processes, and access to devices.
  • A VM gets virtual CPUs, memory, and devices, and runs its own kernel. An ordinary Linux container instead shares the host's kernel.

On Linux, two pieces commonly work together:

  • KVM lets the Linux kernel use the CPU's hardware virtualization features to run guest code.
  • QEMU provides the virtual machine's device model and works with KVM for accelerated execution.

Being root (the administrator account) inside the guest does not automatically make someone root on the host. But the guest still interacts with software on the host through its virtual devices. Those interfaces are part of the security boundary.

Where does KubeVirt fit?

KubeVirt adds VM management to Kubernetes. Kubernetes is the system coordinating workloads across machines; KubeVirt teaches it about virtual machines as well as containers.

  • A VirtualMachine describes a VM and its desired lifecycle.
  • A VirtualMachineInstance (VMI) represents an instance of that VM.
  • KubeVirt runs QEMU in a launcher Pod, Kubernetes' unit for running one or more containers, and coordinates the VM through Kubernetes resources and controllers.

KubeVirt is the management layer, not a replacement for QEMU or KVM. The guest still has its own kernel even though its QEMU process runs in a Pod.

Why use VSOCK instead of an IP address?

A host might need to ask a program inside a guest to report status or perform an operation. An IP connection can do this, but it depends on the guest's network configuration.

VSOCK is a socket interface for communication between a VM and its host, independent of the guest's IP network. A socket is an endpoint that a program uses to send and receive data.

The address looks different from TCP, the reliable network transport used by many applications:

  • TCP commonly uses an IP address + port.
  • VSOCK uses a context ID (CID) + port.
  • The CID identifies the host or guest; the port identifies a service there.
  • Host CID 2 is a standard Linux VSOCK address, not a deployment-specific setting.

For example, a host could connect to an illustrative guest at CID 42, port 9000. The guest could connect to a host service at CID 2 and that service's port. These are VSOCK addresses, not TCP destinations.

On a typical QEMU/KVM setup, virtio-vsock is the guest-facing virtual device, and vhost-vsock handles its host-side transport in the kernel. Virtio is a family of virtual devices designed for guests that know they are virtualized.

┌──────────────────────────────┐
│ Host program                 │
└──────────────▲───────────────┘
               │ VSOCK connection
┌──────────────▼───────────────┐
│ Host kernel: vhost-vsock     │
└──────────────▲───────────────┘
               │ virtual device
┌──────────────▼───────────────┐
│ Guest kernel: virtio-vsock   │
└──────────────▲───────────────┘
               │ socket
┌──────────────▼───────────────┐
│ Guest program                │
└──────────────────────────────┘

The connection carries data in both directions. It does not need to pass through the guest's Ethernet interface.

KubeVirt can attach this device using autoattachVSOCK: true, subject to the feature's configuration requirements. That enables a communication path; it does not, by itself, define which applications should be allowed to use it.

Does removing the network card isolate the guest?

It removes one path, not every path. A guest without a virtual network card can still communicate over VSOCK if that device is attached.

Likewise, a firewall protecting an IP interface does not automatically protect a separate VSOCK transport. The right question is: which communication paths exist, and where is each one controlled?

There is also a difference between:

  • Connectivity: can this program reach that service?
  • Authentication: can the service verify who is connecting?
  • Authorization: is that identity allowed to perform this operation?

A CID is a transport address, not a complete application identity. An application protocol can use TLS (Transport Layer Security) certificates to authenticate endpoints and encrypt the connection, with separate rules to authorize operations. VSOCK alone does not provide these TLS properties. Authentication does not prove that a root-controlled guest program is behaving honestly.

What does eBPF actually do?

eBPF lets Linux run small, checked programs at specific places in the kernel. Those attachment points are called hooks.

  • The kernel's verifier checks a program before loading it, including restrictions on memory access and execution.
  • A hook supplies context: perhaps a network packet, a file operation, or a socket operation.
  • What the program can do depends on the hook. Some hooks observe events; others can allow or deny an operation.

The verifier checks program safety, not whether a security policy is logically correct.

Most importantly, eBPF is not a universal firewall. A program cannot filter traffic that never reaches its hook.

  • XDP attaches early in network-device packet processing.
  • TC hooks operate in the network traffic-control path.
  • Ordinary XDP/TC filters on a VM's network interfaces do not see its separate virtio-vsock traffic.

Can eBPF still help with VSOCK?

Yes, through BPF LSM. LSM stands for Linux Security Modules: hooks used to enforce security decisions inside the kernel. BPF LSM lets privileged host software attach eBPF programs to supported security hooks.

Consider a connection-oriented service:

  1. socket() creates an endpoint.
  2. bind() assigns its local address and port.
  3. listen() makes it available for incoming connections.
  4. accept() hands an incoming connection to the application.

A host policy at socket_listen can reject a host program's attempt to start an unapproved VSOCK listener. Conceptually:

When a host program calls listen():
  preserve any earlier security denial
  if this is a VSOCK socket on a denied port:
    return "operation not permitted"
  otherwise:
    allow this security check to pass

This is pseudocode, not a deployable eBPF program. Actual deployment needs a compatible kernel, BPF LSM enabled, and a privileged loader.

The policy lives on the host. Guest root cannot simply edit a guest configuration file to remove it. By contrast, a restriction applied only to one guest process does not constrain every other service that guest root can launch.

Why filter listeners rather than connect or accept?

The location and timing of the hook matter:

  • Host socket_connect: checks a host program initiating a connection. It is not a check on an incoming guest request. A blanket denial here could block the host-to-guest direction you wanted to preserve.
  • Host socket_accept: runs when a host application accepts a connection. In Linux's virtio-vsock receive path, the kernel has already created and queued the connection and sent its handshake response. This is too late to prevent that initial work.
  • Host socket_listen: can prevent the unapproved listener from being created in the first place.

Listener denial can leave host-initiated connections working: the host connects to a guest listener, then both sides exchange data over that connection. Controlling who initiates a connection is different from allowing data to travel in only one direction.

These details refer to the linked Linux 6.18 source. Check the actual kernel and backend before applying the same reasoning elsewhere.

What does listener filtering leave unsolved?

  • Existing listeners: attaching a policy does not close sockets already listening. Startup ordering and handling existing listeners are separate requirements.
  • Per-guest permissions: allowing a host port is not the same as deciding which guest or user may access it.
  • Kernel attack surface: the host still processes virtual-device traffic. Denying listeners does not eliminate transport bugs or denial-of-service risks.
  • Policy lifetime: decide what happens if the loader exits or the policy disappears. A security-critical service should not silently start without its required protection.
  • Other interfaces: shared filesystems, disks, and other virtual devices need their own controls.

KubeVirt's VSOCK device-attachment setting is not a directional firewall. Listener filtering is one possible host-enforced layer, not a claim that the whole VM is secure.

The takeaway

  • KubeVirt: manage the VM lifecycle through Kubernetes.
  • VSOCK: carry host–guest messages without depending on guest IP networking.
  • BPF LSM: enforce selected host-side security decisions, such as whether a VSOCK service may start listening.
  • Application authentication and authorization: decide who can do what over the channel.

Start by drawing the communication path. Then choose a control that actually runs on that path, outside the component you do not trust.

Public references

Back to the blog