# qemu-spoof — inject the seed-driven spoof module + anti-detect patches into # pve-qemu and build the pve-qemu-kvm .deb. # # make prepare # init submodules, drop in the module, queue patches, bump changelog # make deb # build the .deb (runs pve-qemu's own dpkg-buildpackage) # make clean # # Build on Debian trixie (matches pve-qemu 11.0). Never on a production node. # Override PVE to build against a pve-qemu checkout kept outside this tree: # make PVE=/path/to/pve-qemu deb PVE ?= pve-qemu QSRC := $(PVE)/qemu PATCHDIR := $(PVE)/debian/patches SERIES := $(PATCHDIR)/series # package revision = qemu-spoof commit count: unique + monotonic + orderable per # content change, so a rebuilt/improved package gets a new version (no 409 on the # immutable registry) and apt always picks the latest. SPOOF_REV ?= $(shell git rev-list --count HEAD 2>/dev/null || echo 1) TAG := qemu-spoof # Epoch: makes our package version permanently OUTRANK any stock pve-qemu-kvm # (which has no epoch), so a Proxmox repo update never reverts the spoof. We pull # upstream fixes deliberately by rebuilding on a newer pve-qemu and re-publishing # (the epoch carries forward). Set EPOCH= to disable. EPOCH ?= 1 .PHONY: all prepare deb clean distclean submodule all: deb submodule: @if [ ! -f "$(QSRC)/configure" ]; then \ git submodule update --init --recursive; \ fi cd $(QSRC) && meson subprojects download # Idempotent: safe to re-run. pve-qemu copies the qemu/ working tree (cp -a) into # its build dir, so the module files we drop in here are compiled; the call-site # wiring is applied on top via debian/patches/series (quilt). prepare: submodule @echo ">> install spoof module headers + sources into the qemu tree" @for h in src/spoof*.h; do install -D -m644 "$$h" "$(QSRC)/include/hw/misc/$$(basename $$h)"; done @for c in src/spoof*.c; do install -D -m644 "$$c" "$(QSRC)/hw/misc/$$(basename $$c)"; done @echo ">> register sources in hw/misc/meson.build" @for c in src/spoof*.c; do b=$$(basename "$$c"); \ grep -q "$$b" $(QSRC)/hw/misc/meson.build || \ echo "system_ss.add(files('$$b'))" >> $(QSRC)/hw/misc/meson.build; \ echo " + $$b"; done @echo ">> queue anti-detect patches into the series" @for p in patches/0*.patch; do \ [ -e "$$p" ] || continue; \ b=$$(basename $$p); \ cp -f $$p $(PATCHDIR)/$$b; \ grep -qxF "$$b" $(SERIES) || echo "$$b" >> $(SERIES); \ echo " + $$b"; \ done @echo ">> bump changelog with epoch $(EPOCH) so it permanently outranks stock pve-qemu-kvm" @cd $(PVE) && { head -1 debian/changelog | grep -q "$(TAG)" || { \ cur=$$(dpkg-parsechangelog -S Version); \ dch -v "$(EPOCH):$${cur}+$(TAG)$(SPOOF_REV)" "qemu-spoof: seed-driven per-VM hardware identity"; }; } @cd $(PVE) && head -1 debian/changelog @echo ">> prepared. run 'make deb'." deb: prepare $(MAKE) -C $(PVE) deb @echo ">> built:"; ls -1 $(PVE)/*.deb 2>/dev/null || ls -1 *.deb 2>/dev/null || true clean: -$(MAKE) -C $(PVE) clean 2>/dev/null || true rm -f *.deb *.buildinfo *.changes # Drop the injected files + series entries so the submodule is pristine again. distclean: clean -cd $(QSRC) && git checkout -- hw/misc/meson.build 2>/dev/null || true -rm -f $(QSRC)/hw/misc/spoof*.c $(QSRC)/include/hw/misc/spoof*.h -cd $(PVE) && git checkout -- debian/patches/series debian/changelog 2>/dev/null || true -rm -f $(PATCHDIR)/0*qemu-spoof* $(PATCHDIR)/9*antidetect*