qemu-spoof

Seed-driven, per-VM hardware-identity anti-detection for QEMU / Proxmox VE — a drop-in pve-qemu-kvm build. Each VM derives a coherent, unique hardware persona from a per-VM seed, so a fleet of VMs does not share one fingerprint, and with no seed it falls back to stock QEMU (zero behaviour change).

Why seed-driven (not a static fork)

A hard-coded anti-detect fork gives every VM the same firmware/bus identity (same ACPI OEM, same fw_cfg signature, same PCI IDs, same monitor) — which is itself a fleet fingerprint: many VMs with identical "hardware" correlate trivially. qemu-spoof instead derives a coherent persona from a per-VM seed, so each VM looks like a different real machine while staying internally consistent (CPU vendor ↔ chipset ↔ ACPI OEM ↔ board ↔ socket all cohere).

How it works

A small in-tree module (hw/misc/spoof.c, source kept in src/) holds pools of real identities and a pure derivation seed -> splitmix64 -> pool pick. Every anti-detect call site is patched from a hard-coded literal to a getter:

-    memcpy(signature, "KVMKVMKVM\0\0\0", 12);
+    memcpy(signature, spoof_kvm_signature("KVMKVMKVM\0\0\0"), 12);

The getter returns the seed-derived value, or the stock default when no seed is set — so the patch is inert until a VM opts in.

Seed input

-machine <type>,...,spoof-seed=<string>     # preferred (Proxmox: via args)
QEMU_SPOOF_SEED=<string>                     # env fallback (testing)

Same seed → same persona. Mix in a host secret so personas are not guessable from the vmid. Proxmox: add spoof-seed= through the VM args: line.

Layout

pve-qemu/            git submodule -> https://git.proxmox.com/git/pve-qemu.git (pinned)
src/spoof*.{c,h}     the seed-driven identity module (decomposed by aspect)
patches/             quilt patches injected into pve-qemu/debian/patches/series:
                       0002   register the spoof-seed machine property
                       0010+  wire each anti-detect call site to a getter
Makefile             prepare -> build the .deb

Build

git submodule update --init --recursive       # pve-qemu + its qemu submodule
make prepare                                   # inject spoof module + patches + changelog
make deb                                        # dpkg-buildpackage -> pve-qemu/*.deb

Builds on Debian trixie (matches pve-qemu 11.0). Use a clean builder / WSL, never a production node. make deb produces pve-qemu-kvm_*_amd64.deb (+ -dbgsym).

Packaging & delivery

Install the built .deb on a Proxmox VE node in place of the stock package, or serve it from any apt repository (e.g. a Debian package registry).

Surviving Proxmox updates (epoch + per-commit revision)

The Makefile stamps an epoch1:<upstream>+qemu-spoofN, where N is the commit count — so the package permanently outranks stock pve-qemu-kvm (no epoch). An apt upgrade from the Proxmox repo therefore never reverts the spoof; you are the source of truth for this package on your nodes. Pull upstream QEMU fixes deliberately by rebuilding on a newer pve-qemu (the epoch carries forward). Optional belt-and-suspenders apt pin on each node:

Package: pve-qemu-kvm
Pin: origin <your-apt-registry-host>
Pin-Priority: 1001

Companion config (machine options, not code)

A few tells are configuration, not code — set them when provisioning a spoofed VM (alongside the spoof-seed):

  • -machine ...,vmport=off — disable the VMware backdoor port (0x5658)
  • prefer real-id emulated devices over virtio where stealth matters: e1000e NIC, SATA/AHCI disk (their PCI vendor:device are real Intel; virtio's 1af4 is a tell and its id cannot be spoofed without breaking the guest driver)
  • GPU: vfio passthrough with x-pci-vendor-id/... overrides
  • CPU: host,hidden=1 (+ hv enlightenments for Windows) to back the spoof-hv policy

License

Patches and module are derivative of QEMU and licensed under GPL v2 (the QEMU license). See the COPYING file in the QEMU tree.

S
Description
No description provided
Readme 75 KiB
Languages
C 91.1%
Makefile 8.9%