Create UEFI Secure Boot enabled Photon OS ISOs for physical hardware. Handles MOK enrollment, custom GRUB stub, RPM signing, and kickstart installation. Use when building bootable ISOs for laptops/servers with Secure Boot enabled.
This skill covers creating Secure Boot enabled ISOs for Photon OS that work on consumer laptops and servers with UEFI Secure Boot enabled. The tool creates modified ISOs using:
shim_lock)Original Photon OS ISOs fail on Secure Boot enabled hardware because:
shim_lock that rejects custom/unsigned kernelsOur solution:
shim_lock, sign with MOK-mok variant RPM packages for installed system# Build Secure Boot ISO (simplest - does everything)
./PhotonOS-HABv4Emulation-ISOCreator -b
# Build for specific release
./PhotonOS-HABv4Emulation-ISOCreator --release 6.0 --build-iso
# Build with RPM signing (compliance: NIST 800-53, FedRAMP, EU CRA)
./PhotonOS-HABv4Emulation-ISOCreator --build-iso --rpm-signing
# Build with eFuse USB verification
./PhotonOS-HABv4Emulation-ISOCreator --build-iso --efuse-usb --create-efuse-usb=/dev/sdX -y
# Diagnose existing ISO
./PhotonOS-HABv4Emulation-ISOCreator -D /path/to/iso
| Option | Description |
|--------|-------------|
| -b, --build-iso | Build Secure Boot ISO |
| -r, --release=VERSION | Photon OS version: 4.0, 5.0, 6.0 (default: 5.0) |
| -D, --diagnose=ISO | Diagnose existing ISO |
| -E, --efuse-usb | Enable eFuse USB verification |
| -u, --create-efuse-usb=DEV | Create eFuse USB dongle |
| -R, --rpm-signing | Enable GPG signing of MOK RPMs |
| -d, --drivers[=DIR] | Include driver RPMs from directory (default: drivers/RPM) |
| -c, --clean | Clean all artifacts |
| -v, --verbose | Verbose output |
| -y, --yes | Auto-confirm destructive operations |
UEFI Firmware (Microsoft UEFI CA in db)
↓ verifies Microsoft signature
BOOTX64.EFI (SUSE shim, SBAT=shim,4)
↓ verifies against MokList
grub.efi (Custom GRUB stub, MOK-signed, NO shim_lock)
↓ loads grub.cfg with themed menu (5 sec timeout)
│
└─→ "Install" → launches interactive installer
│
↓ Package Selection Screen (modified build_install_options_all.json)
│
├─→ "1. Photon MOK Secure Boot" → packages_mok.json
│ → Installs: linux-mok, grub2-efi-image-mok, shim-signed-mok
│
├─→ "2. Photon Minimal" → packages_minimal.json (original)
│ → Installs: linux, grub2-efi-image, shim-signed
│
└─→ "3-5. Developer/OSTree/RT" → respective package files
UEFI Firmware → shim-signed-mok (SUSE shim + MokManager)
→ grub2-efi-image-mok (Custom GRUB stub, MOK-signed)
→ linux-mok (vmlinuz, MOK-signed)
✓ Works on physical hardware with Secure Boot
VMware's GRUB includes the shim_lock verifier module which calls shim's Verify() for kernel loading. While MOK-signed kernels should be accepted (certificate in MokList), we build a custom stub without shim_lock to ensure compatibility and provide predictable behavior.
The custom stub:
shim_lock (no unpredictable kernel verification)probe, gfxmenu, png, jpeg, tgaThe tool includes an integrated RPM patcher that creates MOK-signed variant packages:
| Original Package | MOK Package | Contents |
|-----------------|-------------|----------|
| shim-signed | shim-signed-mok | SUSE shim (Microsoft-signed) + MokManager |
| grub2-efi-image | grub2-efi-image-mok | Custom GRUB stub (MOK-signed, no shim_lock) |
| linux / linux-esx | linux-mok | MOK-signed vmlinuz + boot files |
The patcher discovers packages by file paths, not version numbers:
grub2-efi-image: provides /boot/efi/EFI/BOOT/grubx64.efilinux: provides /boot/vmlinuz-*shim-signed: provides /boot/efi/EFI/BOOT/bootx64.efiGenerated specs include:
Provides: (same capability as original)Conflicts: (prevents installing both)shim-signed-mokThe ISO uses a fully interactive installer with MOK packages added to the package selection menu. This is Option C from the architecture decision record (see ADR-001 in DROID_SKILL_GUIDE.md).
build_install_options_all.json: Adds "Photon MOK Secure Boot" as first optionpackages_mok.json: Contains MOK-signed packages (dynamically generated)The tool modifies the initrd to:
packages_mok.json in /installer/ (dynamically generated in v1.9.18+):{
"packages": [
"bash-completion", "bc", "bridge-utils", "...",
"grub2-efi-image-mok", // Replaces grub2-efi-image
"linux-mok", // Replaces linux/linux-esx
"shim-signed-mok", // Replaces shim-signed
"initramfs", "lvm2", "less", "sudo", "..."
]
}
Note: Since v1.9.18, packages_mok.json is dynamically generated:
minimal meta-package is expanded to its direct dependenciesgrub2-efi-image is replaced with grub2-efi-image-mokbuild_install_options_all.json to add MOK option first:{
"mok": {
"title": "1. Photon MOK Secure Boot",
"packagelist_file": "packages_mok.json",
"visible": true
},
"minimal": {
"title": "2. Photon Minimal",
...
}
}
linuxselector.py to recognize linux-mok kernel:linux_flavors = {"linux-mok":"MOK Secure Boot", "linux":"Generic", ...}
Previous versions (v1.5.0) used kickstart files with "ui": true. This failed because:
ui: true misconception: Only controls progress bars, not the configuration wizardThe interactive approach (Option C):
build_install_options_all.json mechanismThe tool automatically builds kernels from Photon OS sources with Secure Boot configuration:
| Release | Kernel Source | Config Location |
|---------|--------------|-----------------|
| 4.0 | /root/4.0/stage/SOURCES/linux-*.tar.xz | /root/4.0/SPECS/linux/ (legacy) |
| 5.0 | /root/5.0/stage/SOURCES/linux-6.1.*.tar.xz | /root/5.0/SPECS/linux/ (legacy) |
| 6.0+ | /root/6.0/stage/SOURCES/linux-*.tar.xz | /root/common/SPECS/linux/vX.Y/ (auto-detect highest) |
Auto-detection (v1.9.28+): For release 6.0 and future releases, the tool automatically scans /root/common/SPECS/linux/ for version directories (v6.1, v6.12, etc.) and selects the highest version. This ensures Photon 6.0 uses kernel 6.12.x instead of 6.1.x.
SOURCES/{photon_dir}/kernel-build/linux-{version}/config-esx_{arch} preferred for VMs)CONFIG_MODULE_SIG=yCONFIG_MODULE_SIG_ALL=yCONFIG_MODULE_SIG_SHA512=yCONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY=y{keys_dir}/vmlinuz-mokThe --rpm-signing option enables GPG signing for compliance:
RPM-GPG-KEY-habv4)rpmsignrpm -qa gpg-pubkey* --qf '%{NAME}-%{VERSION}-%{RELEASE}\t%{SUMMARY}\n'
rpm -qa *-mok* --qf '%{NAME}\t%{SIGPGP:pgpsig}\n'
The --drivers option allows including additional driver firmware RPMs in the ISO:
# Use default drivers directory (drivers/RPM/)
./PhotonOS-HABv4Emulation-ISOCreator -b --drivers
# Use custom drivers directory
./PhotonOS-HABv4Emulation-ISOCreator -b --drivers=/path/to/custom/drivers
.rpm filespackages_mok.json| Pattern | Kernel Modules | Description |
|---------|---------------|-------------|
| iwlwifi | iwlwifi, iwlmvm, cfg80211, mac80211 | Intel Wi-Fi 6/6E/7 |
| rtw88 | rtw88, cfg80211, mac80211 | Realtek Wi-Fi (RTW88) |
| rtw89 | rtw89, cfg80211, mac80211 | Realtek Wi-Fi (RTW89) |
| brcmfmac | brcmfmac, brcmutil, cfg80211 | Broadcom Wi-Fi |
| ath11k | ath11k, cfg80211, mac80211 | Qualcomm/Atheros Wi-Fi 6 |
| e1000e | e1000e | Intel Ethernet |
| igb | igb | Intel Gigabit Ethernet |
| igc | igc | Intel I225/I226 Ethernet |
| nvidia | DRM support | NVIDIA GPU (firmware only) |
The drivers/RPM/ directory includes:
wireless-regdb-2024.01.23-1.ph5.noarch.rpm: WiFi regulatory database from kernel.orgiw-6.9-1.ph5.x86_64.rpm: nl80211 wireless configuration utility from kernel.orglinux-firmware-iwlwifi-ax211-20260128-1.ph5.noarch.rpm: Intel Wi-Fi 6E AX211 firmware (PCI IDs: 8086:51f0, 8086:51f1)Note: wireless-regdb and iw are built from upstream sources because they're not available in Photon OS 5.0 repos.
Spec files and build script are included:
# Rebuild wireless-regdb and iw from upstream sources
./drivers/build-wireless-packages.sh
drivers/RPM/--driversWhen built with -E, boot requires an eFuse USB dongle (label: EFUSE_SIM):
GRUB Stub
↓
Search for USB with LABEL=EFUSE_SIM
↓
Check for /efuse_sim/srk_fuse.bin
├─→ Valid: Show boot menu
└─→ Invalid: "BOOT BLOCKED" (only Retry/Reboot)
Hot-plug detection (v1.9.20+): If eFuse USB is plugged in after GRUB starts,
selecting "Retry" uses chainloader to reload GRUB and rescan USB devices.
This fixes the issue where configfile reload didn't detect newly inserted USB.
USB (FAT32, LABEL=EFUSE_SIM)
└── efuse_sim/
├── srk_fuse.bin # SRK hash (32 bytes)
├── sec_config.bin # Security mode
└── efuse_config.json # Configuration
dd if=photon-5.0-secureboot.iso of=/dev/sdX bs=4M status=progress
sync
/ENROLL_THIS_KEY_IN_MOKMANAGER.cer| Error | Cause | Fix |
|-------|-------|-----|
| "bad shim signature" | Selected Photon Minimal on hardware | Select "Photon MOK Secure Boot" |
| Laptop security dialog (not blue MokManager) | CSM enabled | Disable CSM in BIOS |
| Enrollment doesn't persist | Wrong MokManager | Rebuild ISO |
| "Policy Violation" | GRUB SBAT issue | Use latest version |
| grub> prompt | Config not found | Rebuild ISO |
| BOOT BLOCKED | eFuse USB missing | Insert eFuse USB or rebuild without -E |
| eFuse USB not detected | Missing GRUB modules | Rebuild ISO (v1.9.17+ adds search_label, usb, usbms) |
| eFuse USB plugged after boot not detected | GRUB caches USB devices | Rebuild ISO (v1.9.34+ uses chainloader for USB rescan) |
| ZeroDivisionError in linuxselector | linux-mok not recognized | Rebuild ISO (v1.6.0+ fixes this) |
| Installed system fails | Standard packages installed | Reinstall with "Photon MOK Secure Boot" |
| "search.c: no such device" | GRUB searching for ISO path | Rebuild ISO (v1.7.0+ fixes embedded config) |
| Installation takes 2000+ seconds | USB autosuspend | Rebuild ISO (v1.7.0+ adds kernel param) |
| "grub.efi Not Found" | SUSE shim looks for grub.efi | Rebuild ISO (v1.7.0+ installs both names) |
| "rpm transaction failed" (Error 1525) | MOK conflicts or scriptlet failure | Rebuild ISO (v1.9.18+) / Check /var/log/installer.log (v1.9.26+) |
| Black screen after "Secure Boot is enabled" | Missing USB drivers in initrd | Rebuild ISO (v1.8.0+ includes USB drivers) |
| "Loading of unsigned module is rejected" | Module signatures stripped by RPM | Rebuild ISO (v1.9.4+ preserves signatures) |
| Installer GPG verification fails | HABv4 key not in initrd | Rebuild ISO (v1.9.14+ installs multi-key) |
Black screen after "UEFI Secure Boot is enabled" message (Installed System):
linux-mok RPM, ensuring USB drivers are built-in--add-drivers "usbcore usb-common xhci_hcd xhci_pci ehci_hcd ehci_pci uhci_hcd usb_storage"linux-mok RPM build fails with depmod "No such file or directory":
6.1.159-7.ph5-esx) but custom modules directory has different version (e.g., 6.1.159-esx)MOK packages missing from ISO / "grub2-efi-image-mok package not found" during install:
Laptop shows gray/red security dialog instead of blue MokManager:
MOK enrollment appears to succeed but doesn't persist:
\MokManager.efi (root)Installed system gets "bad shim signature":
Installed system boots to emergency mode with "Loading of unsigned module is rejected":
brp-strip strips ELF binaries during package build, which removes PKCS#7 signatures from kernel modules%define __strip /bin/true to linux-mok.spec to preserve module signaturestail -c 50 /lib/modules/*/kernel/drivers/block/loop.ko | hexdump -C - signed modules show "~Module signature appended~" at endISO Root/
├── ENROLL_THIS_KEY_IN_MOKMANAGER.cer # MOK certificate
├── MokManager.efi # SUSE MokManager
├── EFI/BOOT/
│ ├── BOOTX64.EFI # SUSE shim
│ ├── grub.efi # Custom GRUB stub
│ ├── grubx64.efi # Same as grub.efi
│ ├── grubx64_real.efi # VMware GRUB (for standard path)
│ └── MokManager.efi # Backup
├── boot/grub2/
│ ├── efiboot.img # EFI System Partition
│ └── grub.cfg # Boot menu
├── RPMS/x86_64/ # Original + MOK RPMs
└── isolinux/ # BIOS boot (legacy)
├── vmlinuz # MOK-signed kernel
└── initrd.img
/root/hab_keys/
├── MOK.key / MOK.crt / MOK.der # Machine Owner Key
├── kernel_module_signing.pem # Kernel module signing key
├── shim-suse.efi # SUSE shim (embedded)
├── MokManager-suse.efi # SUSE MokManager (embedded)
├── grub-photon-stub.efi # Custom GRUB stub (MOK-signed)
├── vmlinuz-mok # MOK-signed kernel
└── RPM-GPG-KEY-habv4 # GPG public key (if --rpm-signing)
Essential modules in custom GRUB stub:
probe - UUID detection for photon.media=UUID=$photondiskgfxmenu - Themed menuspng, jpeg, tga - Background imagesgfxterm_background - Graphics backgroundsearch, configfile, linux, initrd - Core bootchain, fat, iso9660, part_gpt - Filesystem/chainloadSUSE shim components are embedded in data/:
shim-suse.efi.gz - SUSE shim (Microsoft-signed, SBAT=shim,4)MokManager-suse.efi.gz - SUSE MokManagerExtracted automatically during build. No internet required.
The tool applies several patches to the photon-os-installer in the initrd:
The installer assumes progress_bar exists in exit_gracefully(). Fix:
self.progress_bar = None in __init__()exit_gracefully() and _execute_modules()Submitted upstream as PR #39.
The LinuxSelector class has hardcoded kernel flavors. Without this patch, selecting packages with linux-mok causes ZeroDivisionError (no menu items created).
Fix: Add "linux-mok": "MOK Secure Boot" to linux_flavors dictionary.
Build an ISO:
User: Build a Secure Boot ISO for Photon OS 5.0
[I'll run the build command and report results]
Diagnose issues:
User: My ISO gets "bad shim signature" on my laptop
[I'll explain the cause and provide step-by-step fix]
Modify the tool:
User: Add support for custom GRUB themes
[I'll analyze the code, propose changes, implement and test]
Understand the code:
User: How does the RPM patcher work?
[I'll explain the architecture with code references]
See docs/DROID_SKILL_GUIDE.md for complete developer guide.
The tool implements several security measures:
;|&$\"'and..` are rejectedmkdtemp() instead of predictable /tmp/prefix_PID patterns[PRIVATE_KEY] in verbose output# Check certificate status
./PhotonOS-HABv4Emulation-ISOCreator -C
# Warn if certificates expire within 60 days
./PhotonOS-HABv4Emulation-ISOCreator -C --cert-warn=60
# Generate 4096-bit keys valid for 1 year
./PhotonOS-HABv4Emulation-ISOCreator -K 4096 -m 365 -g
| Category | Status | Notes | |----------|--------|-------| | Command injection | Mitigated | Path validation, but still uses system() | | Download integrity | Not implemented | Ventoy/ISO downloads not checksum verified | | Key storage | Plain text | Keys stored unencrypted on filesystem | | HSM support | Not implemented | No PKCS#11/HSM integration | | Certificate expiration | Implemented | -C flag checks, -W sets warning threshold | | Configurable key sizes | Implemented | -K flag (2048/3072/4096) |
For production deployments in regulated environments, consider:
npx skills add dcasota/photonos-secureboot-iso下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer