diff --git a/Config.psm1 b/Config.psm1
index 8317b51..547e32f 100644
--- a/Config.psm1
+++ b/Config.psm1
@@ -115,12 +115,16 @@ function Get-AvailableConfigOptions {
@{"Name" = "install_qemu_ga"; "GroupName" = "custom";"DefaultValue" = "False";
"Description" = "Installs QEMU guest agent services from the Fedora VirtIO website.
Defaults to 'False' (no installation will be performed).
- If set to 'True', the following MSI installer will be downloaded and installed:
+ If set to 'True', by default, the following MSI installer will be downloaded and installed:
* for x86: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-qemu-ga/qemu-ga-win-100.0.0.0-3.el7ev/qemu-ga-x86.msi
* for x64: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-qemu-ga/qemu-ga-win-100.0.0.0-3.el7ev/qemu-ga-x64.msi
The value can be changed to a custom URL, to allow other QEMU guest agent versions to be installed.
Note: QEMU guest agent requires VirtIO drivers to be present on the image.
"},
+ @{"Name" = "url"; "GroupName" = "virtio_qemu_guest_agent";
+ "Description" = "Custom URL for QEMU Guest Agent MSI installer. Must be used together with 'checksum' parameter for SHA256 verification."},
+ @{"Name" = "checksum"; "GroupName" = "virtio_qemu_guest_agent";
+ "Description" = "SHA256 checksum of the QEMU Guest Agent MSI installer. Must be used together with 'url' parameter."},
@{"Name" = "drivers_path"; "GroupName" = "drivers";
"Description" = "The location where additional drivers that are needed for the image are located."},
@{"Name" = "install_updates"; "GroupName" = "updates"; "DefaultValue" = $false; "AsBoolean" = $true;
diff --git a/Examples/windows-image-config-example.ini b/Examples/windows-image-config-example.ini
index e0a7aa4..64d7f9a 100644
--- a/Examples/windows-image-config-example.ini
+++ b/Examples/windows-image-config-example.ini
@@ -142,6 +142,19 @@ drivers_path=""
# The value can be changed to a custom URL, to allow other QEMU guest agent versions to be installed.
# Note: QEMU guest agent requires VirtIO drivers to be present on the image.
install_qemu_ga=False
+
+[virtio_qemu_guest_agent]
+# Custom URL for QEMU Guest Agent MSI installer.
+# Must be used together with 'checksum' parameter for SHA256 verification.
+# Example: url=https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-qemu-ga/qemu-ga-win-VERSION/qemu-ga-x64.msi
+url=
+# SHA256 checksum of the QEMU Guest Agent MSI installer.
+# Must be used together with 'url' parameter.
+# To get the checksum on Windows: Get-FileHash -Path "qemu-ga-x64.msi" -Algorithm SHA256
+# To get the checksum on Linux/macOS: sha256sum qemu-ga-x64.msi
+checksum=
+
+[custom]
# Set a custom timezone for the Windows image.
time_zone=""
# Set custom ntp servers(space separated) for the Windows image
diff --git a/README.md b/README.md
index 56dd7ea..7803b52 100644
--- a/README.md
+++ b/README.md
@@ -94,6 +94,62 @@ the resulting VHDX is shrinked to a minimum size and converted to the required f
You can find a PowerShell example to generate a raw OpenStack Ironic image that also works on KVM
in `Examples/create-windows-online-cloud-image.ps1`
+## QEMU Guest Agent Configuration
+
+### Overview
+
+The QEMU Guest Agent installation supports optional SHA256 checksum verification for enhanced security, while maintaining full backward compatibility.
+
+### Configuration Options
+
+#### 1. Default Installation (Simple)
+
+```ini
+[custom]
+install_qemu_ga=True
+```
+
+Uses the default version from the VirtIO archive.
+
+#### 2. Custom URL (Legacy)
+
+```ini
+[custom]
+install_qemu_ga=https://example.com/custom-qemu-ga.msi
+```
+
+#### 3. Secure Installation with Checksum (Recommended)
+
+```ini
+[custom]
+install_qemu_ga=True
+
+[virtio_qemu_guest_agent]
+url=https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-qemu-ga/qemu-ga-win-VERSION/qemu-ga-x64.msi
+checksum=
+```
+
+**Important**: Both `url` and `checksum` must be specified together to enable checksum verification.
+
+### Getting the SHA256 Checksum
+
+**Windows (PowerShell)**:
+```powershell
+Get-FileHash -Path "qemu-ga-x64.msi" -Algorithm SHA256
+```
+
+**Linux/macOS**:
+```bash
+sha256sum qemu-ga-x64.msi
+```
+
+### Benefits of Checksum Verification
+
+- **Security**: Verifies downloaded file integrity
+- **Control**: Know exactly which version will be installed
+- **Protection**: Prevents man-in-the-middle attacks
+- **Compliance**: Facilitates security audits
+
## Frequently Asked Questions (FAQ)
### The image generation never stops
diff --git a/WinImageBuilder.psm1 b/WinImageBuilder.psm1
index adb7cca..de97190 100755
--- a/WinImageBuilder.psm1
+++ b/WinImageBuilder.psm1
@@ -570,24 +570,53 @@ function Download-QemuGuestAgent {
[Parameter(Mandatory=$true)]
[string]$ResourcesDir,
[Parameter(Mandatory=$true)]
- [string]$OsArch
+ [string]$OsArch,
+ [Parameter(Mandatory=$false)]
+ [string]$CustomUrl,
+ [Parameter(Mandatory=$false)]
+ [string]$Checksum
)
- $QemuGuestAgentUrl = $QemuGuestAgentConfig
- if ($QemuGuestAgentConfig -eq 'True') {
- $arch = "x86"
- if ($OsArch -eq "AMD64") {
- $arch = "x64"
+ $useCustomConfig = $false
+
+ # Priority 1: Check if custom URL and checksum are provided (highest priority)
+ if ($CustomUrl -and $Checksum) {
+ $useCustomConfig = $true
+ Write-Log "Using custom QEMU Guest Agent configuration with checksum verification"
+ Write-Log "Downloading QEMU guest agent installer from ${CustomUrl} ..."
+ $dst = Join-Path $ResourcesDir "qemu-ga.msi"
+ Execute-Retry {
+ (New-Object System.Net.WebClient).DownloadFile($CustomUrl, $dst)
+ }
+
+ # Verify SHA256 checksum
+ Write-Log "Verifying SHA256 checksum..."
+ $fileHash = (Get-FileHash -Path $dst -Algorithm SHA256).Hash
+ if ($fileHash -ne $Checksum) {
+ throw "SHA256 checksum verification failed. Expected: $Checksum, Got: $fileHash"
+ }
+ Write-Log "SHA256 checksum verification successful"
+ }
+
+ # Priority 2: Use legacy behavior (backward compatibility)
+ if (!$useCustomConfig) {
+ $QemuGuestAgentUrl = $QemuGuestAgentConfig
+ if ($QemuGuestAgentConfig -eq 'True') {
+ $arch = "x86"
+ if ($OsArch -eq "AMD64") {
+ $arch = "x64"
+ }
+ $QemuGuestAgentUrl = "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads" + `
+ "/archive-qemu-ga/qemu-ga-win-100.0.0.0-3.el7ev/qemu-ga-{0}.msi" -f $arch
}
- $QemuGuestAgentUrl = "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads" + `
- "/archive-qemu-ga/qemu-ga-win-100.0.0.0-3.el7ev/qemu-ga-{0}.msi" -f $arch
- }
- Write-Log "Downloading QEMU guest agent installer from ${QemuGuestAgentUrl} ..."
- $dst = Join-Path $ResourcesDir "qemu-ga.msi"
- Execute-Retry {
- (New-Object System.Net.WebClient).DownloadFile($QemuGuestAgentUrl, $dst)
+ Write-Log "Downloading QEMU guest agent installer from ${QemuGuestAgentUrl} ..."
+ $dst = Join-Path $ResourcesDir "qemu-ga.msi"
+ Execute-Retry {
+ (New-Object System.Net.WebClient).DownloadFile($QemuGuestAgentUrl, $dst)
+ }
}
+
Write-Log "QEMU guest agent installer path is: $dst"
}
@@ -1712,7 +1741,8 @@ function New-WindowsCloudImage {
}
if ($windowsImageConfig.install_qemu_ga -and $windowsImageConfig.install_qemu_ga -ne 'False') {
Download-QemuGuestAgent -QemuGuestAgentConfig $windowsImageConfig.install_qemu_ga `
- -ResourcesDir $resourcesDir -OsArch ([string]$image.ImageArchitecture)
+ -ResourcesDir $resourcesDir -OsArch ([string]$image.ImageArchitecture) `
+ -CustomUrl $windowsImageConfig.url -Checksum $windowsImageConfig.checksum
}
Download-CloudbaseInit -resourcesDir $resourcesDir -osArch ([string]$image.ImageArchitecture) `
-BetaRelease:$windowsImageConfig.beta_release -MsiPath $windowsImageConfig.msi_path `
@@ -1893,7 +1923,8 @@ function New-WindowsFromGoldenImage {
}
if ($windowsImageConfig.install_qemu_ga -and $windowsImageConfig.install_qemu_ga -ne 'False') {
Download-QemuGuestAgent -QemuGuestAgentConfig $windowsImageConfig.install_qemu_ga `
- -ResourcesDir $resourcesDir -OsArch $imageInfo.imageArchitecture
+ -ResourcesDir $resourcesDir -OsArch $imageInfo.imageArchitecture `
+ -CustomUrl $windowsImageConfig.url -Checksum $windowsImageConfig.checksum
}
Download-CloudbaseInit -resourcesDir $resourcesDir -osArch $imageInfo.imageArchitecture `
-BetaRelease:$windowsImageConfig.beta_release -MsiPath $windowsImageConfig.msi_path `