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 `