Was dein Kunde sieht, wenn deine VM bootet

Du verkaufst virtuelle Maschinen unter deinem eigenen Namen. Ein Kunde schaltet eine ein, und das Erste auf dem Bildschirm ist das Logo von jemand anderem.

Das ist eine Standard-VM unter Proxmox. Nichts ist kaputt, und Proxmox machen nichts falsch: Es ist ihr Produkt und ihr Name, sie haben die Firmware und die Oberfläche geschrieben, in der er erscheint, und sie dürfen ihn dort hinsetzen, so wie ein Serverhersteller sein Abzeichen vorn auf das Gehäuse setzt. Es ist nur eben nicht deins.

Das Logo ist erst der Anfang. So meldet sich ein UEFI-Gast mit der aktuellen Firmware von Proxmox, pve-edk2-firmware 4.2026.08-1, aus dem Gast heraus mit dmidecode gelesen:

Wo der Gast nachsiehtWas er liestWessen Name
Bootbildschirmdas Logo von ProxmoxProxmox
Firmware-Hersteller (SMBIOS-Typ 0)Proxmox distribution of EDK IIProxmox
Firmware-Version4.2026.08-1die Paketversion von Proxmox
Systemhersteller (Typ 1)QEMUQEMU
Produktname (Typ 1)Standard PC (Q35 + ICH9, 2009)QEMU
Gehäusehersteller (Typ 3)QEMUQEMU
Mainboard (Typ 2)gar nicht vorhandenniemandes
Web-Verwaltungsoberflächedas Logo von Proxmox, oben linksProxmox

Beim Bootlogo hört es auch nicht an der Firmware auf. UEFI-Firmware gibt das Bild, das sie gezeichnet hat, über eine ACPI-Tabelle namens BGRT, die Boot Graphics Resource Table, an das Betriebssystem weiter. Die Tabelle existiert, um zu sagen „an image was drawn on the screen during boot“1, und das Betriebssystem zeichnet es dann auf seinem eigenen Bootbildschirm noch einmal. Das Fisher-Price OS (Windows) setzt es über seinen Kreisel, und Microsoft nennt die BGRT „the standard interface that Windows uses to access the logo“2. Das Standard-Theme von Plymouth bei Fedora macht unter Linux dasselbe3. Ein Gast auf der Firmware von Proxmox zeigt das Logo von Proxmox also zweimal, bevor sich überhaupt jemand angemeldet hat.

Nichts davon ist schwer zu ändern. Es geändert zu lassen schon. Das nächste apt full-upgrade stellt still die Hälfte davon wieder her, und die Hälfte, die es nicht wiederherstellt, ist die, die dir Sorgen machen sollte. Um die geht es in diesem Beitrag vor allem.

Wo jedes Stück Branding in den Boot kommtEinschaltenQEMU bautSMBIOS und ACPIaus der KonfigFirmwareOVMF zeichnetsein Logo,SeaBIOS einen SplashÜbergabeSMBIOS-Tabellen,ACPI mit BGRTund MSDMOS-Bootbildschirmzeichnet dasFirmware-Logoaus der BGRT neuLaufender Gastliest die Strings,die Aktivierung liestden MSDM-SchlüsselVM-KonfigPaketdateiVM-KonfigPaketdateiVM-Konfigliegt in /etc/pve, übersteht jedes Upgradeliegt unter /usr/share, apt ersetzt sie
Branding kommt an fünf Stellen in den Bootvorgang. Drei davon stammen aus der eigenen Konfiguration der VM und überstehen alles, was apt tut. Zwei kommen aus Dateien, die einem Proxmox-Paket gehören, und die holt sich ein Upgrade zurück.

Die MSDM-Tabelle in dieser Übergabe ist überhaupt kein Branding. Sie trägt einen Lizenzschlüssel, und wie man einen in eine VM bringt, hat einen eigenen Beitrag: Eine OEM-Lizenz in eine Proxmox-VM bringen.

Alles unter /usr/share gehört apt

Eine Regel entscheidet jede Wahl weiter unten. Eine Datei, die ein Paket installiert hat, ist die Datei des Pakets. Ändere sie an Ort und Stelle, und das nächste Upgrade dieses Pakets überschreibt deine Änderung ohne ein Wort, denn aus Sicht von dpkg legt es nur seine eigene Datei dorthin zurück, wo es sie gelassen hat.

Jedes Stück Branding muss also irgendwo leben, das apt nicht gehört. Ein Proxmox-Knoten hat drei solche Orte, und jeder kostet etwas anderes:

Wo es lebtWie es dorthin kommtÜbersteht ein UpgradeWas es dich kostet
Die VM-Konfiguration in /etc/pvesmbios1, und args für alles andereJa, Konfiguration fasst kein Paket anargs darf nur root setzen, und es erscheint nicht in der GUI
Eine Datei, die dpkg in Ruhe lassen solldpkg-divertJa, die Kopie des Pakets landet stattdessen unter einem .distrib-NamenUpgrades erreichen die Datei nicht mehr, und das zählt, wenn die Datei Firmware ist
Dein eigenes Verzeichnis, außerhalb des Paketbaums/usr/local, aus args referenziertJa, kein Paket besitzt esDu musst es selbst auf jeden Knoten bringen

Debians eigene Beschreibung einer Umleitung ist die klarste: „a way of forcing dpkg not to install a file into its location, but to a diverted location“4. Das deckt die Weboberfläche ab. Für die Firmware ist es eine von zwei Möglichkeiten, und die gefährlichere.

Das Gehäuse ist eine Handvoll Strings und eine Rechteprüfung

SMBIOS ist die Tabelle, mit der eine Maschine sich selbst beschreibt: wer sie gebaut hat, welches Modell sie ist, ihre Seriennummer, was Mainboard und Gehäuse sind5. dmidecode liest sie, jedes Inventarisierungswerkzeug, das du je auf ein Netz losgelassen hast, liest sie, die Systeminformation des Fisher-Price OS (Windows) liest sie, und die meisten Lizenzprüfungen, die entscheiden, ob eine Software auf einer bestimmten Maschine überhaupt läuft, lesen sie auch. Bei einer VM schreibt QEMU sie. Daher QEMU und Standard PC in der Tabelle oben.

Typ 1 über smbios1

Proxmox legt eine einzige SMBIOS-Struktur in der VM-Konfiguration offen: Typ 1, System Information, als smbios16. Sie nimmt manufacturer, product, version, serial, sku, family und uuid.

Der Haken steckt in qemu-server, nicht in der Doku. Jedes Feld außer uuid muss auf ein Base64-Muster passen, [A-Za-z0-9+\/]+={0,2}, ein einfacher Wert mit einem Leerzeichen darin wird also glatt abgelehnt. Echte Strings werden Base64-kodiert und mit base64=1 markiert, und qemu-server dekodiert sie wieder, bevor es die QEMU-Befehlszeile baut7. Der SMBIOS-Editor der GUI macht das bei jedem Speichern, mit dem Kommentar „smbios values can be arbitrary, so encode and mark config as such“8. Auf der Kommandozeile ist es deine Aufgabe:

b() { printf %s "$1" | base64 -w0; }
qm set 9000 --smbios1 "uuid=$(qm config 9000 | sed -n 's/.*uuid=\([0-9a-f-]*\).*/\1/p'),base64=1,\
manufacturer=$(b 'Example Cloud Ltd'),product=$(b 'EC Compute Instance'),\
version=$(b '2026.10'),family=$(b 'General Purpose'),sku=$(b 'ec-gp-4c16g')"

Beachte, dass die uuid wieder mit hineinkommt. Sie ist die Maschinenidentität des Gasts, und was du an --smbios1 übergibst, wird als ganze Option gespeichert, also lies sie vorher aus und behalte sie.

Brande die Vorlage, nicht jede einzelne VM. Ein Klon unter Proxmox bekommt eine frisch erzeugte UUID und behält jedes andere smbios1-Feld, jeder Klon kommt also mit eigener Identität und deinen Strings heraus9, mit einer Ausnahme, siehe unten.

Typen 0, 2, 3 und 11 über args

smbios1 endet bei Typ 1. Firmware-Hersteller, Mainboard, Gehäuse und die OEM-Strings laufen alle über args, die Zeile, die Proxmox direkt an QEMU weiterreicht und die seine eigene Dokumentation „for experts only“ nennt6. Die QEMU-Option -smbios nimmt die Felder für jeden Typ10:

args: -smbios 'type=0,vendor=Example Cloud Ltd,version=EC-FW 1.0,date=10/04/2026,uefi=on' -smbios 'type=2,manufacturer=Example Cloud Ltd,product=EC Virtual Board,version=1.0' -smbios 'type=3,manufacturer=Example Cloud Ltd,version=1.0,asset=EC-ASSET-123,sku=ec-gp' -smbios 'type=11,value=example-cloud:instance=123'

Mit diesen Zeilen auf QEMU gebootet, liest dmidecode im Gast:

StrukturFeldStandardGebrandet
Typ 0VendorProxmox distribution of EDK IIExample Cloud Ltd
Typ 0Version4.2026.08-1EC-FW 1.0
Typ 1ManufacturerQEMUExample Cloud Ltd
Typ 1Product NameStandard PC (Q35 + ICH9, 2009)EC Compute Instance
Typ 1Familynicht angegebenGeneral Purpose
Typ 2ManufacturerStruktur fehltExample Cloud Ltd
Typ 2Product NameStruktur fehltEC Virtual Board
Typ 3ManufacturerQEMUExample Cloud Ltd
Typ 3Asset Tagnicht angegebenEC-ASSET-123
Typ 11String 1Struktur fehltexample-cloud:instance=123

Unterwegs sind vier Fallen aufgetaucht. Alle vier sind still.

Wer Typ 0 liefert, verliert „UEFI is supported“. OVMF schreibt seinen eigenen Typ 0 nur, wenn QEMU keinen geliefert hat; die Schleife, die durch die Tabellen von QEMU läuft, setzt NeedSmbiosType0 = FALSE, sobald sie auf einen Typ 0 trifft11. Dein Herstellerstring ersetzt den von Proxmox, und genau darum geht es. Aber der Typ 0 von QEMU ersetzt auch die Firmware-Eigenschaften von OVMF, und ohne uefi=on verschwindet die Zeile „UEFI is supported“ aus dmidecode. Hol sie mit uefi=on zurück. Für UEFI-Gäste gibt es für den Herstellerstring ohnehin ein besseres Zuhause, in der Firmware selbst, weiter unten.

Der Gehäusetyp lässt sich nicht setzen. Der Typ 3 von QEMU nimmt manufacturer, version, serial, asset und sku, und sonst nichts10. Er bleibt Other.

Zwei Definitionen eines Typs werden zusammengeführt, und die spätere gewinnt. qemu-server setzt sein -smbios type=1 früh in die Befehlszeile und deine args ganz ans Ende12, ein zweites -smbios type=1,manufacturer=… in args wirft das erste also nicht weg: QEMU hat sie Feld für Feld zusammengeführt, der Hersteller kam aus args, und die UUID blieb, wo smbios1 sie hingesetzt hatte. Das zählt für die vierte Falle.

Die beiden Hälften haben verschiedene Besitzer. qemu-server prüft Rechte Option für Option. smbios1 steht bei den Hardware-Optionen und braucht VM.Config.HWType, während args in den Auffangzweig ganz unten fällt, der sagt „only root can set“13. Mainboard, Gehäuse, Firmware-Hersteller und OEM-Strings gehören dir allein. Typ 1 nicht. Jeder, dem du Hardware-Rechte gegeben hast, kann ihn umschreiben, und bei einem gehosteten Produkt kann das sehr wohl der Kunde sein. Wenn der Herstellerstring zählt, setz ihn auch in args. Die spätere Definition gewinnt.

Die Seriennummer steht schon in der Konfiguration

Das meiste, was in Typ 1 gehört, steht schon in der VM-Konfiguration. Der Name gibt eine gute Seriennummer ab, weil qemu-server dort nur einen DNS-Namen akzeptiert14: kurz, druckbar, nie ein Komma darin, und das eine an der VM, das ein Kunde wiedererkennt.

Feld in Typ 1Genommen ausFür eine VM mit 4 Kernen und 16 GiB namens web-01, getaggt production;web
Serial Numbernameweb-01
SKU Numbercores × sockets, und memoryec-4c16g
Familyder erste Eintrag in tagsproduction
UUIDdie smbios1-UUID, die sie schon hatunverändert
Manufacturer, Productdeine eigenen festen StringsExample Cloud Ltd, EC Compute Instance

Zwei Dinge bleiben draußen. Der Knoten ändert sich bei jeder Migration, und vmgenid soll sich ändern: Seine ganze Aufgabe ist, dem Gast zu sagen, dass er aus einem Snapshot wiederhergestellt oder aus einer Vorlage gebaut wurde15. Keins von beiden ist eine Identität.

#!/bin/bash
# /usr/local/sbin/ec-smbios VMID: rebuild smbios1 from the VM's own config.
set -euo pipefail
id=$1
cfg=$(qm config "$id" --current)
get() { sed -n "s/^$1: //p" <<<"$cfg"; }
b() { printf %s "$1" | base64 -w0; }

name=$(get name)
[ -n "$name" ] || { echo "VM $id has no name to use as a serial" >&2; exit 1; }
cores=$(get cores); sockets=$(get sockets); vcpu=$(( ${cores:-1} * ${sockets:-1} ))
mem=$(get memory); mem=${mem#current=}; mem=${mem%%,*}; mem=${mem:-512}
(( mem % 1024 )) && size="${mem}m" || size="$(( mem / 1024 ))g"
tag=$(get tags); tag=${tag%%;*}
uuid=$(get smbios1 | grep -o 'uuid=[0-9a-fA-F-]*' | cut -d= -f2 || true)
uuid=${uuid:-$(cat /proc/sys/kernel/random/uuid)}

s="uuid=$uuid,base64=1,manufacturer=$(b 'Example Cloud Ltd'),product=$(b 'EC Compute Instance')"
s+=",serial=$(b "$name"),sku=$(b "ec-${vcpu}c${size}")"
[ -n "$tag" ] && s+=",family=$(b "$tag")"
qm set "$id" --smbios1 "$s"

Die Vorgaben sind die von qemu-server selbst, ein Kern, ein Sockel und 512 MiB16, eine Konfiguration, die sie weglässt, bekommt also trotzdem eine wahre SKU. Gegen die Konfiguration aus der Tabelle laufen gelassen, mit einem Skript anstelle von qm, das sie auslieferte, ging die geschriebene Zeile so dekodiert an QEMU, wie qemu-server sie dekodiert, und dmidecode im Gast las web-01, ec-4c16g, production und die UUID zurück, die er schon hatte. Eine VM ohne Namen wird abgelehnt, statt eine leere Seriennummer zu bekommen.

Das naheliegende Zuhause dafür ist ein Hookscript. Es ist das falsche. qemu-server führt den pre-start-Hook innerhalb der Konfigurationssperre aus, die es zum Starten der VM genommen hat, und baut die QEMU-Befehlszeile aus der Konfiguration, die es vor dem Hook geladen hat17. Ein Hook, der die Seriennummer umschreibt, ändert den nächsten Start, nicht diesen.

Lass es also aus deiner Provisionierung laufen, an den vier Punkten, an denen sich seine Eingaben ändern: Anlegen, Klonen, Umbenennen und Größenänderung. Beim Klonen beißt es. Ein Klon behält jedes smbios1-Feld außer der UUID9, lass den Schritt also aus, und jede VM, die aus web-template gebaut wurde, meldet den Namen der Vorlage als Seriennummer.

Das Bootlogo lebt an zwei verschiedenen Orten

Welches Logo ein Gast zeigt, hängt von seiner Firmware ab. Die beiden Firmwares, die Proxmox ausliefert, holen es von völlig verschiedenen Stellen:

SeaBIOS (bios: seabios, die Vorgabe)OVMF (bios: ovmf, UEFI)
Woher das Logo kommtein JPEG, das QEMU beim Booten übergibteine Bitmap, die in die Firmware kompiliert ist
Die Datei von Proxmox/usr/share/qemu-server/bootsplash.jpg, 640×480Logo.bmp, 400×120, 8 Bit, eingebaut in OVMF_CODE_4M*.fd
Besitzendes Paketqemu-serverpve-edk2-firmware-ovmf
Pro VM ändernargs: -boot splash=…args, das die VM auf andere Firmware zeigt
Ändern, ohne etwas neu zu bauenjanein
Erreicht das Gast-OS über die BGRTneinja

SeaBIOS: ein JPEG auf der Befehlszeile

qemu-server setzt bei jeder VM, die es startet, dieselbe -boot-Option, menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg18. Die Dokumentation von QEMU sagt, das Bild werde gezeigt „when option splash=sp_name is given and menu=on, If firmware/BIOS supports them. Currently Seabios for X86 system support it“10. OVMF nimmt daraus nichts außer splash-time, das es als Timeout für das Bootmenü verwendet, und in OvmfPkg gibt es nirgends einen Verweis auf die Splash-Datei19.

Ersetzen ist eine Zeile in der VM-Konfiguration:

args: -boot splash=/etc/pve/branding/splash.jpg

Ein zweites -boot kämpft nicht mit dem ersten. QEMU führt es genauso zusammen wie -smbios, der spätere Wert gewinnt, und mit zwei angegebenen Splash-Dateien zeigte der Screenshot die zweite. /etc/pve ist das richtige Zuhause für die Datei, weil es das Cluster-Dateisystem ist und jeder Knoten denselben Splash sieht, und seine Grenze von 1 MiB pro Datei ist weit weg von einem JPEG mit 640×48020.

Das Bild selbst muss drei Bedingungen erfüllen, und wer eine davon falsch macht, verliert das Logo oder seine Farben:

BedingungWarumWas sonst passiert
JPEG oder 24-Bit-BMPQEMU prüft die Datei, bevor die VM startetsplash file … format not recognized; must be JPEG or 24 bit BMP
Baseline-JPEG, Chroma 4:2:0der Decoder von SeaBIOS kann nichts anderes21ERR_NOT_SEQUENTIAL_DCT oder ERR_NOT_YCBCR_221111, und ein leerer Bildschirm
640×480, wie das von ProxmoxSeaBIOS fragt das VGA-BIOS nach einem Modus mit genau der Größe des Bildskein passender Modus, kein Splash

Die meisten Bildwerkzeuge schreiben standardmäßig Baseline mit 4:2:0, der übliche Weg, das Logo zu verlieren, ist also eine dieser „Für Web speichern“-Optionen, die still progressive Kodierung einschaltet. Das sieht in jedem Bildbetrachter, den du hast, genau gleich aus, und SeaBIOS zeichnet gar nichts.

Die Farbfalle

Die hier hat einen Nachmittag gekostet. Dasselbe JPEG, von zwei Builds von SeaBIOS 1.17.0 gezeichnet, kommt in zwei verschiedenen Farben heraus:

Ein Example-Cloud-Splash dreimal: das Quell-JPEG mit einer blauen Logo-Kachel, SeaBIOS so, wie Proxmox es ausliefert, mit demselben Blau, und ein SeaBIOS-Build mit 32 Bit pro Pixel, bei dem das Blau zu Gold geworden ist

Es steckt in jpeg.c von SeaBIOS. Der Schreiber für 24 Bit pro Pixel hat einen Little-Endian-Zweig, der Blau in das erste Byte jedes Pixels setzt, und der Schreiber für 32 Bit pro Pixel, PIC_32, hat keinen solchen Zweig und schreibt dort stattdessen Rot21. Auf einem Little-Endian-Framebuffer vertauscht das Rot und Blau. Blau kommt als Gold heraus, und Orange käme als Blau heraus.

Welcher Schreiber läuft, hängt vom Videomodus ab, den das VGA-BIOS anbietet:

FirmwareVBE-Modus für 640×480Bit pro PixelFarben
Das vorgebaute SeaBIOS 1.17.0 von QEMU upstream, wie pve-qemu-kvm 11.0.3-4 es ausliefert0x11116richtig, auf 65.536 quantisiert
Fedora 44s eigener Build seabios 1.17.0-100x14232Rot und Blau vertauscht

Die Modusnummern stammen aus der eigenen Tabelle von SeaBIOS22, und die Proxmox-Zeile wurde gegen genau die Blobs im Paket geprüft: Byte für Byte identisch mit dem vorgebauten rel-1.17.0-0-gb52ca86e094d von QEMU. Unter Proxmox stimmen deine Farben also, aber es gibt nur 65.536 davon, und ein feiner Verlauf bekommt Streifen. Und falls dein Logo irgendwann auf einem anderen Hypervisor in falschen Farben erscheint: Es ist nicht dein JPEG.

Das UEFI-Logo ist in die Firmware kompiliert

UEFI-Gäste sind die schwierigere Hälfte, und auf einem modernen Proxmox sind sie die meisten Gäste.

Es gibt keine Splash-Option zum Überschreiben. Das Logo ist eine Bitmap im Firmware-Image, und der Build von Proxmox setzt es mit einer Zeile in debian/rules dorthin:

debian/setup-build-stamp:
	cp -a debian/Logo.bmp MdeModulePkg/Logo/Logo.bmp

Das kopiert ihr Logo.bmp mit 400×120 und 8 Bit über das von TianoCore, bevor edk2 gebaut wird23. Dieselbe Datei setzt den Firmware-Hersteller als Konstante zur Build-Zeit, PcdFirmwareVendor=L"Proxmox distribution of EDK II", und daher kommt der Typ-0-Hersteller in der ersten Tabelle23.

Neues Logo, neue Firmware. Der Weg zu einer, die sich genau wie die von Proxmox verhält, ist, sie genau so zu bauen wie Proxmox: ihr Baum an dem Tag, der zum ausgelieferten Paket passt, ihre Patches, ihre Flags, und eine Bitmap ausgetauscht. pve-edk2-firmware 4.2026.08-1 pinnt edk2 auf 2970e56, und das ist der Upstream-Tag edk2-stable20260823.

git clone https://git.proxmox.com/git/pve-edk2-firmware.git
cd pve-edk2-firmware
git checkout f37039e52d228a7844a90aa2aaf1e161ebd04fcd   # 4.2026.08-1
git submodule update --init --recursive
cd edk2
QUILT_PATCHES=../debian/patches quilt push -a
cp /path/to/your/Logo.bmp MdeModulePkg/Logo/Logo.bmp
. ./edksetup.sh && make -C BaseTools

F="-DNETWORK_HTTP_BOOT_ENABLE=TRUE -DNETWORK_IP6_ENABLE=TRUE -DNETWORK_TLS_ENABLE
   -DSECURE_BOOT_ENABLE=TRUE -DPVSCSI_ENABLE=TRUE -DTPM2_ENABLE=TRUE
   --pcd PcdUninstallMemAttrProtocol=TRUE -DFD_SIZE_4MB"
P=(--pcd "PcdFirmwareVendor=LExample Cloud Ltd\\0"
   --pcd "PcdFirmwareVersionString=L4.2026.08-1+ec1\\0")

build -a IA32 -a X64 -t GCC -p OvmfPkg/OvmfPkgIa32X64.dsc $F "${P[@]}" -b RELEASE
cp Build/Ovmf3264/RELEASE_GCC/FV/OVMF_CODE.fd OVMF_CODE_4M.fd
rm -rf Build/Ovmf3264
build -a IA32 -a X64 -t GCC -p OvmfPkg/OvmfPkgIa32X64.dsc $F -DSMM_REQUIRE=TRUE "${P[@]}" -b RELEASE
cp Build/Ovmf3264/RELEASE_GCC/FV/OVMF_CODE.fd OVMF_CODE_4M.secboot.fd

Die Flags sind aus debian/rules übernommen, so wie es an diesem Commit steht. Achte auf den Herstellerstring: Ihr Makefile schreibt ihn in doppelten Anführungszeichen, die Shell von make entfernt sie, und edk2 bekommt ihn nackt. So wird er hier auch übergeben, und ihn ein zweites Mal zu quoten ist ein Build-Fehler. Lass die Bitmap bei 400×120 und 8 Bit wie ihre, dann verschiebt sich sonst nichts auf dem Bootbildschirm.

Du brauchst beide Images. qemu-server bootet jede Q35-VM mit einer 4M-EFI-Disk auf OVMF_CODE_4M.secboot.fd, dem Build mit verpflichtendem SMM, und nimmt das einfache OVMF_CODE_4M.fd nur für i440fx24. Auf einem aktuellen Proxmox läuft fast jeder UEFI-Gast mit dem Secboot-Image.

So gebaut, mit nichts gegenüber dem Baum von Proxmox geändert als der Bitmap und zwei Strings, bootet das SMM-Image so:

Der Bootbildschirm eines Gasts, gezeichnet vom neu gebauten OVMF-Image, mit einem Example-Cloud-Logo, wo sonst das von Proxmox wäre

Und die Sicht des Gasts auf seine eigene Firmware ändert sich mit, ohne eine einzige -smbios-Option auf der Befehlszeile:

Im Gast gelesen4.2026.08-1 von ProxmoxAus demselben Baum neu gebaut
Firmware-HerstellerProxmox distribution of EDK IIExample Cloud Ltd
Firmware-Version4.2026.08-14.2026.08-1+ec1
„UEFI is supported“aufgeführtaufgeführt
ACPI-TabellenBGRT, WSMT und der Restderselbe Satz

Damit ist der Hersteller zur Build-Zeit die bessere Antwort für UEFI-Gäste. Es ist der eigene Typ 0 von OVMF, das UEFI-Bit bleibt also stehen, ohne dass irgendwer an uefi=on denken muss. Der Weg über args für Typ 0 ist für SeaBIOS-Gäste, und für alle, die gar keine Firmware neu bauen.

Zwei Wege, einer VM die neue Firmware zu geben

qemu-server kodiert fest, wo es nach Firmware sucht: OVMF.pm hält eine Tabelle von Pfaden unter /usr/share/pve-edk2-firmware/, nach Maschinentyp und Secure-Boot-Optionen geordnet, und es gibt nirgends in der VM-Konfiguration, der GUI oder der API eine Option, die eine andere Datei wählt24. Zwei Wege bleiben.

Gebrandetes OVMF bauen, und die zwei Wege in eine VMBaum von Proxmoxpve-edk2-firmware 4.2026.08-1Dein BrandingLogo.bmp + HerstellerstringGleicher Build, gleiche FlagsOVMF_CODE_4M.fd + .secboot.fdA: umleiten auf jedem Knotenjede UEFI-VM bekommt es,keine Änderung an VM-KonfigsB: pro VM über argsVM für VM aktiviert,Dateien von Proxmox unberührtapt full-upgradeNeue Firmware von Proxmox kommt, deine bleibt altPost-Invoke-HookVersionen weichen ab, also vor dem nächsten Start neu bauen
Ein Build, zwei Wege hinein. So oder so installiert das nächste Upgrade die neue Firmware von Proxmox neben deine und lässt deine, wie sie war. Darum gibt es den Hook ganz unten.

Weg A: auf jedem Knoten umleiten. Sag dpkg, dass die beiden Code-Images von Proxmox jetzt woanders hingehören, und setz deine an ihre Stelle:

D=/usr/share/pve-edk2-firmware
for f in OVMF_CODE_4M.fd OVMF_CODE_4M.secboot.fd; do
  dpkg-divert --package example-branding --add --rename --divert "$D/$f.distrib" "$D/$f"
  install -m 0644 "/root/branding/$f" "$D/$f"
done

Ab dem nächsten Start bootet jede UEFI-VM auf dem Knoten deine Firmware. Keine Änderung an irgendeiner VM-Konfiguration.

Weg B: ausgewählte VMs darauf zeigen lassen. Behalte die Images in deinem eigenen Verzeichnis und überschreibe die Firmware VM für VM. Seit dem Umstieg auf -blockdev hängt qemu-server das Code-Image als Blockknoten namens pflash0 an und nennt ihn in -machine24, und QEMU führt ein zweites -machine genauso zusammen wie -boot, args kann also einen eigenen Knoten hinzufügen und pflash0 stattdessen darauf zeigen lassen:

args: -blockdev driver=raw,node-name=brandcode,read-only=on,file.driver=file,file.filename=/usr/local/share/example-branding/OVMF_CODE_4M.secboot.fd -machine pflash0=brandcode

Das wurde auf dem langen Weg getestet. Die Secboot-Firmware von Proxmox wurde genau so als pflash0 angehängt, wie qemu-server es macht, mit SMM an, dann kam diese args-Zeile dahinter, und der Gast bootete das gebrandete Image mit Logo und Herstellerstring. Daher stammt der Screenshot oben.

Weg A, umleitenWeg B, args pro VM
Welche VMs es bekommenjede UEFI-VM auf dem Knotennur VMs, bei denen du es setzt
Die Dateien von Proxmoxnach .distrib verschobenunberührt
VM-Konfigurationunveränderteine args-Zeile, nur root
Maschinentyp muss passenerledigt, beide Images sind umgeleitetdeine Aufgabe: Secboot-Image für Q35
Rückgängig machendpkg-divert --remove --renamedie Zeile löschen
MigrationZielknoten muss auch umgeleitet seinZielknoten muss die Datei haben

Das Code-Image ist etwa 3,5 MB groß, bei einer Grenze von 1 MiB pro Datei in pmxcfs20. Deshalb kann es nicht in /etc/pve liegen, und egal welchen Weg du nimmst, es muss auf jeden Knoten. Migrierst du eine VM auf einen Knoten ohne es, bekommst du je nach Weg eins von zwei Ergebnissen: unter Weg A wieder die Firmware und das Logo von Proxmox, oder unter Weg B eine VM, die gar nicht startet, weil QEMU eine Datei nicht öffnen kann, die nicht da ist.

Das Upgrade, das dich zurücklässt

Eine Umleitung ist das richtige Werkzeug für ein Logo. Firmware ist etwas anderes.

Eine Umleitung bedeutet, dass die Upgrades von Proxmox die Datei nicht mehr erreichen. Genau das hast du verlangt. Genau das hält auch Sicherheitskorrekturen von edk2 von deinen Gästen fern: Das Changelog von Proxmox für 4.2026.08-1 beginnt mit „Besides many bug and security fixes“ und führt dann eine Korrektur für CVE-2024-13745 auf25, und ein gebrandeter Build aus dem Release davor hat nichts davon. Nichts sagt es dir.

Das wurde getestet, nicht angenommen. In einem Debian-trixie-Container mit dem Repository von Proxmox kam pve-edk2-firmware-ovmf 4.2025.05-3 hinein, beide Code-Images wurden umgeleitet, und das Paket wurde auf 4.2026.08-1 aktualisiert:

Nach dem UpgradeErgebnis
dpkg-query -W pve-edk2-firmware-ovmf4.2026.08-1
Das neue Image von Proxmoxals OVMF_CODE_4M.fd.distrib installiert, Hash geändert
Das gebrandete Imageunverändert, immer noch aus 4.2025.05-3 gebaut
Irgendetwas dazu auf der Konsolenichts, bis zum Hook unten

Also kommt ein Hook dazu. apt führt nach jedem Lauf von dpkg eine Liste von DPkg::Post-Invoke-Befehlen aus26. Halte fest, aus welcher Proxmox-Version du gebaut hast, und vergleiche nach jedem Lauf:

cat > /usr/local/sbin/example-branding-check <<'EOF'
#!/bin/sh
built=$(cat /usr/local/share/example-branding/ovmf.built-from 2>/dev/null)
now=$(dpkg-query -W -f '${Version}' pve-edk2-firmware-ovmf 2>/dev/null)
[ "$built" = "$now" ] && exit 0
echo "W: branded OVMF was built from pve-edk2-firmware-ovmf $built, Proxmox now ships $now." >&2
echo "W: guests still boot the old firmware. Rebuild before the next VM restart." >&2
exit 0
EOF
chmod +x /usr/local/sbin/example-branding-check
echo 'DPkg::Post-Invoke { "/usr/local/sbin/example-branding-check"; };' \
  > /etc/apt/apt.conf.d/80example-branding

Bei genau diesem Upgrade gab er aus:

W: branded OVMF was built from pve-edk2-firmware-ovmf 4.2025.05-3, Proxmox now ships 4.2026.08-1.
W: guests still boot the old firmware. Rebuild before the next VM restart.

Er endet absichtlich mit 0. apt bricht ab, wenn ein Post-Invoke-Befehl fehlschlägt26, und eine Branding-Prüfung ist kein Grund, einen Knoten halb aktualisiert stehen zu lassen. Eine laute Warnung reicht.

Noch etwas. Neustarts. Ein Gast bekommt neue Firmware erst, wenn sein QEMU-Prozess neu startet, ein Neubau bedeutet also ein Stoppen und Starten aus Proxmox heraus statt eines Neustarts im Gast, und genau so erreichen auch die eigenen Firmware-Updates von Proxmox eine laufende VM. Die brauchen nur nicht, dass du vorher an einen Neubau denkst.

Oder lass die Firmware von Proxmox in Ruhe

Jeder Logo-Weg bisher ändert die Firmware, und der letzte Abschnitt ist die Rechnung dafür. Es gibt einen, der das nicht tut, und er wurde für diesen Beitrag als Prototyp gebaut.

Ein PCI-Gerät in QEMU kann ein Option-ROM tragen, jede Datei, die du mit romfile= angibst27, und OVMF führt den EFI-Treiber aus, den es dort findet. Der Build von Proxmox führt ihn aus, ob er signiert ist oder nicht: OVMF setzt PcdOptionRomImageVerificationPolicy auf 0x00, immer ausführen28. OVMF zeichnet sein eigenes Logo spät in der Auswahl des Bootgeräts29 und baut die BGRT erst bei ReadyToBoot, dem Moment, bevor es an einen Bootloader übergibt. Und der BGRT-Treiber von edk2 nimmt über EDKII_BOOT_LOGO2_PROTOCOL ein Ersatzbild an und baut die Tabelle bei ReadyToBoot neu, wann immer sich das Bild geändert hat30.

Mehr braucht es nicht. Der Treiber wartet bei TPL_NOTIFY auf ReadyToBoot, was vor dem eigenen Handler des BGRT-Treibers bei TPL_CALLBACK läuft, löscht den Bildschirm, zeichnet sein Logo und übergibt dasselbe Bild. Gebaut ist es eine Datei von 8 KB, angehängt mit einer Zeile:

args: -device pci-testdev,romfile=/etc/pve/branding/brandrom.rom

Mit 8 KB liegt sie weit unter der Grenze von 1 MiB in pmxcfs20, anders als ein Firmware-Image mit 3,5 MB kann sie also in /etc/pve leben und der VM auf jeden Knoten folgen.

Getestet wurde sie gegen die eigene Firmware von Proxmox, direkt aus pve-edk2-firmware-ovmf 4.2026.08-1: OVMF_CODE_4M.secboot.fd mit den vorab eingetragenen Schlüsseln von Microsoft in OVMF_VARS_4M.ms.fd, auf Q35 mit SMM, und gebootet über den signierten Shim von Fedora, sodass Secure Boot an war und durchgesetzt wurde:

Aus dem Gast gelesenOhne das ROMMit dem ROM
Variable SecureBoot11
Auf dem Bildschirmdas Logo von Proxmoxdas von Proxmox für etwa 250 ms, dann deins
BGRT-Bild, 400×120 bei 440,340das von Proxmox, SHA-256 be5afe4b…das des ROMs, SHA-256 6c494576…
Geänderte Firmware-Dateienkeinekeine

Das Bild, das ein Gast mit angehängtem Option-ROM aus seiner BGRT-Tabelle zurückgelesen hat: ein Example-Cloud-Logo mit der Beschriftung drawn by an option ROM

Auf die letzte Zeile kommt es an. Die Firmware von Proxmox ist unberührt, ihr nächstes Sicherheits-Release erreicht deine Gäste also mit dem nächsten Neustart, und nichts aus dem vorigen Abschnitt gilt.

Umsonst ist es nicht:

KostenWarum
Das Logo von Proxmox ist etwa eine Viertelsekunde zu sehenOVMF zeichnet es, bevor irgendein Option-ROM-Treiber den Bildschirm bekommt; nur ein Neubau vermeidet das
Der Gast sieht ein PCI-Gerät mehr, ohne Treiberdas ROM muss auf einem Gerät mitfahren, und pci-testdev ist das Nichtstuer-Gerät von QEMU
Typ 0 sagt immer noch Proxmoxder Herstellerstring ist einkompiliert; setz ihn über args mit uefi=on, wie oben
Nur rootes ist eine args-Zeile

Und der Befund darunter will deutlich gesagt sein. Ein unsignierter Treiber lief in der Firmware eines Gasts mit eingetragenen Microsoft-Schlüsseln und durchgesetztem Secure Boot, weil das OVMF von Proxmox Option-ROMs nicht prüft. Hier ist das nützlich. Es bedeutet aber auch, dass Secure Boot auf dieser Firmware Bootloader prüft, nicht das, was die Hardware-Konfiguration der VM anhängt, und weil nur root args schreibt, ist das eine Frage danach, wer auf deinen Knoten root hat.

Es ist ein Prototyp. Es lief auf QEMU 10.2.2 mit der Firmware von Proxmox, noch nicht auf einem Proxmox-Knoten, und was folgt, ist Quellcode, kein Produkt:

github.com/damo2929/RebrandPCIRom: der Option-ROM-Treiber, der Logo-Konverter und der Container-Build.

Die Weboberfläche sind zwei Pakete

Das Logo oben links in der Weboberfläche ist nicht in pve-manager. Workspace.js fragt nach einer Komponente proxmoxLogoSvg mit dem Präfix pwt, und die lebt in proxmox-widget-toolkit, das sich Backup Server und Mail Gateway teilen31. Nur die Tab-Icons sind in pve-manager:

WasDateiPaket
Header-Logo, gezeichnet mit 200×35/usr/share/javascript/proxmox-widget-toolkit/images/proxmox_logo.svgproxmox-widget-toolkit
Icon im Browser-Tab/usr/share/pve-manager/images/favicon.icopve-manager
Icon mit 128×128, auch das Touch-Icon/usr/share/pve-manager/images/logo-128.pngpve-manager

Alle drei sind einfache Dateien, das ist also ein Fall für dpkg-divert, und hier gelten die Kosten aus dem letzten Abschnitt überhaupt nicht, denn ein Logo hat keine Sicherheitskorrekturen, die es verpassen kann, und niemandes Gast ist unsicherer, weil ein Knoten noch das Favicon vom letzten Monat ausliefert.

divert() {
  dpkg-divert --package example-branding --add --rename --divert "$1.distrib" "$1"
  install -m 0644 "$2" "$1"
}
divert /usr/share/javascript/proxmox-widget-toolkit/images/proxmox_logo.svg /root/branding/logo.svg
divert /usr/share/pve-manager/images/favicon.ico   /root/branding/favicon.ico
divert /usr/share/pve-manager/images/logo-128.png  /root/branding/logo-128.png

Im selben Container getestet, gegen echte Pakete:

SchrittErgebnis
Umleitung auf proxmox-widget-toolkit 5.2.9, eigenes SVG installiertdas SVG von Proxmox umbenannt in proxmox_logo.svg.distrib
Upgrade auf 5.2.10eigenes SVG noch an seinem Platz, die Kopie von Proxmox aus 5.2.10 in .distrib
dpkg --verify proxmox-widget-toolkitkeine Beschwerden, dpkg weiß von der Umleitung
apt-get install --reinstall proxmox-widget-toolkiteigenes SVG noch an seinem Platz
dpkg-divert --remove --renamedas Original von Proxmox zurück, Byte für Byte

Zwei Dinge bleiben bei Proxmox. Das Header-Bild wird in einem festen Kasten von 200×35 gezeichnet, zeichne dein SVG also in dieser Form, sonst wird es gequetscht. Und der alt-Text sagt Proxmox, und das Bild verlinkt auf https://www.proxmox.com, beides in die JavaScript-Komponente geschrieben statt in eine Datei, die du umleiten kannst31. Das zu ändern heißt, ein minifiziertes Bundle zu patchen, das bei jedem Upgrade bricht. Für einen Alt-Text lohnt sich das nicht.

Was Lizenz und Marke von Proxmox von dir verlangen

Proxmox VE steht unter der AGPL Version 332, und Abschnitt 13 dieser Lizenz ist die Netzwerkklausel: „if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network … an opportunity to receive the Corresponding Source of your version“33. Zählt das Austauschen von drei Bildern als Änderung des Programms? Das ist eine Frage für einen Anwalt. Die billige Antwort ist, deine Bilder und das Umleitungsskript irgendwo öffentlich abzulegen und von der Anmeldeseite darauf zu verlinken. Kostet nix und klärt die Frage.

Die Markenseite ist klarer. Das Media-Kit von Proxmox sagt „Don’t alter the logo or incorporate the logo or symbol into your logo“34. Ersetze ihres also vollständig durch dein eigenes, nie durch eine umgefärbte oder überarbeitete Version davon, und halte Proxmox aus dem Namen deines Produkts heraus.

Dein Name darauf heißt deine Wartung

Eine VM zu branden ist billig. Eine Handvoll SMBIOS-Strings, ein JPEG, eine Bitmap und drei Bilder in einer Weboberfläche: die Arbeit eines Nachmittags, das meiste davon damit verbracht, herauszufinden, wo die Dinge liegen.

Es zu halten ist die eigentliche Arbeit. Es ist auch der Teil, der ausgelassen wird.

Die SMBIOS-Strings und der Splash kümmern sich um sich selbst, weil sie in Konfiguration leben, die kein Paket je anfasst, und das Logo der Weboberfläche kümmert sich um sich selbst, weil dpkg davon weiß. Die Firmware nicht. An dem Tag, an dem du dein Logo in ein Firmware-Image setzt, hast du ein Stück vom Release-Prozess eines anderen übernommen. Proxmox bauen, testen und liefern neue Firmware mit Sicherheitskorrekturen, die ihre Kunden mit dem nächsten Upgrade bekommen, und deine bekommen sie, wenn du dazu kommst, neu zu bauen.

Dieser Tausch ist in Ordnung, wenn man ihn wissentlich macht. Ein Hoster, dessen Gäste Firmware booten, die zwei Releases zurückliegt, weil das Logo wichtiger war als das Changelog, hat kein Produkt gebaut. Er hat einen Aufkleber gebaut.

Wenn dein Name auf dem Bootbildschirm steht, ist die Firmware dahinter deine, um sie aktuell zu halten, egal wer sie geschrieben hat. Niemand wird es prüfen. Genau deshalb muss es gemacht werden.


  1. UEFI Forum, ACPI Specification 6.6, §5.2.23 Boot Graphics Resource Table — „The Boot Graphics Resource Table (BGRT) is an optional table that provides a mechanism to indicate that an image was drawn on the screen during boot“. Archivierte Kopie; die Live-Seite antwortet automatisierten Anfragen mit 403. ↩︎

  2. Microsoft Learn, Boot screen components — „This is the standard interface that Windows uses to access the logo.“ ↩︎

  3. Fedora Project, Changes/FlickerFreeBoot — „a new plymouth theme which incorporates the firmware’s bootsplash image“; Fedoras plymouth.spec macht bgrt zum Standard-Theme. ↩︎

  4. Debian, dpkg-divert(1), trixie — „File diversions are a way of forcing dpkg(1) not to install a file into its location, but to a diverted location.“ ↩︎

  5. DMTF, DSP0134 System Management BIOS Reference Specification 3.10.0 — Typ 1 System Information, Typ 2 Mainboard, Typ 3 „the system’s mechanical enclosure(s)“, Typ 11 „free-form strings defined by the OEM“. ↩︎

  6. Proxmox VE, qm.conf(5) — smbios1: „Specify SMBIOS type 1 fields“; args: „Arbitrary arguments passed to kvm … this option is for experts only.“ ↩︎ ↩︎

  7. qemu-server, src/PVE/QemuServer.pm, das Format von smbios1 und der Aufbau der Befehlszeile — jedes Feld außer uuid hat das Muster [A-Za-z0-9+\/]+={0,2}; die Werte werden dekodiert, wenn base64 gesetzt ist. ↩︎

  8. pve-manager, www/manager6/Parser.js, printQemuSmbios1 — „smbios values can be arbitrary, so encode and mark config as such“. ↩︎

  9. qemu-server, src/PVE/API2/Qemu.pm, Klonen — „auto generate a new uuid“, die anderen smbios1-Felder bleiben erhalten. ↩︎ ↩︎

  10. QEMU, System Emulation, Invocation — -smbios-Felder pro Typ; -acpitable „For file=, take whole ACPI table from the specified files, including all ACPI headers“; -boot „Currently Seabios for X86 system support it.“ ↩︎ ↩︎ ↩︎

  11. edk2-stable202608, OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.c — OVMF fügt seinen eigenen Typ 0 nur hinzu, wenn NeedSmbiosType0 nach dem Durchlauf durch die Tabellen von QEMU noch gesetzt ist. ↩︎

  12. qemu-server, src/PVE/QemuServer.pm, eigene Argumente — args werden aufgeteilt und ans Ende der Befehlszeile gehängt. ↩︎

  13. qemu-server, src/PVE/API2/Qemu.pm, Rechteprüfung der Konfiguration — smbios1 ist eine Hardware-Option und braucht VM.Config.HWType; der Auffangzweig „catches args, lock, etc.“ und bricht mit „only root can set“ ab. ↩︎

  14. qemu-server, src/PVE/QemuServer.pm, die Option name — format => 'dns-name'. ↩︎

  15. qemu-server, src/PVE/QemuServer.pm, vmgenid — „notify the guest operating system when the virtual machine is executed with a different configuration (e.g. snapshot execution or creation from a template)“. ↩︎

  16. qemu-server, src/PVE/QemuServer/Memory.pm — Speicher default => 512; cores und sockets haben in QemuServer.pm die Vorgabe 1. ↩︎

  17. qemu-server, src/PVE/QemuServer.pm, vm_start — lock_config in Zeile 5457, exec_hookscript($conf, $vmid, 'pre-start', 1) in 5581 und config_to_command in 5634 mit demselben $conf, dazwischen nicht neu geladen. ↩︎

  18. qemu-server, src/PVE/QemuServer.pm, -boot — menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg. ↩︎

  19. edk2-stable202608, OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c — OVMF liest etc/boot-menu-wait, den Wert von splash-time, und sonst nichts aus -boot. ↩︎

  20. pve-cluster, src/pmxcfs/memdb.h — #define MEMDB_MAX_FILE_SIZE (1024 * 1024) // 1 MiB. ↩︎ ↩︎ ↩︎

  21. SeaBIOS, src/jpeg.c — PIC schreibt auf Little-Endian Blau zuerst, PIC_32 in Zeile 946 schreibt Rot zuerst, ohne Endian-Zweig; ERR_NOT_SEQUENTIAL_DCT und ERR_NOT_YCBCR_221111 sind die einzigen abgelehnten Formate. ↩︎ ↩︎

  22. SeaBIOS, vgasrc/svgamodes.c — Modus 0x111 ist 640×480 mit 16 Bit, 0x142 ist 640×480 mit 32. ↩︎

  23. pve-edk2-firmware, debian/rules bei 4.2026.08-1 — cp -a debian/Logo.bmp MdeModulePkg/Logo/Logo.bmp, der String PcdFirmwareVendor und die Build-Flags für OVMF. ↩︎ ↩︎ ↩︎

  24. qemu-server, src/PVE/QemuServer/OVMF.pm — die fest kodierte Firmware-Tabelle unter /usr/share/pve-edk2-firmware/, die Wahl von SMM und der Blockknoten pflash0. ↩︎ ↩︎ ↩︎

  25. pve-edk2-firmware, debian/changelog — 4.2026.08-1: „Besides many bug and security fixes … fix CVE-2024-13745“. ↩︎

  26. Debian, apt.conf(5), trixie — „Pre-Invoke, Post-Invoke: This is a list of shell commands to run before/after invoking dpkg(1) … should any fail APT will abort.“ ↩︎ ↩︎

  27. QEMU v11.0.3, hw/pci/pci.c — DEFINE_PROP_STRING("romfile", PCIDevice, romfile), eine Eigenschaft, die jedes PCI-Gerät hat. ↩︎

  28. edk2-stable202608, OvmfPkg/OvmfPkgIa32X64.dsc — gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00, die Plattformdatei, die Proxmox baut. ↩︎

  29. edk2-stable202608, OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c — BootLogoEnableLogo (), aufgerufen aus PlatformBootManagerAfterConsole. ↩︎

  30. edk2-stable202608, BootGraphicsResourceTableDxe.c — SetBootLogo2 in Zeile 239 kopiert das Bild; der ReadyToBoot-Handler in 417 deinstalliert die Tabelle und installiert sie neu, „If BGRT data change happens“. ↩︎

  31. proxmox-widget-toolkit, src/Logo.js — proxmoxLogoSvg, 200×35, alt: 'Proxmox', verlinkt auf proxmox.com; verwendet aus pve-manager Workspace.js mit prefix: 'pwt'. ↩︎ ↩︎

  32. Proxmox VE wiki, FAQ — „Proxmox VE code is licensed under the GNU Affero General Public License, version 3.“ ↩︎

  33. GNU Affero General Public License v3, §13 Remote Network Interaction — im Text oben vollständig zitiert. ↩︎

  34. Proxmox, Media kit — „Don’t alter the logo or incorporate the logo or symbol into your logo.“ ↩︎