diff --git a/.pipelines/.vsts-vhd-builder-release.yaml b/.pipelines/.vsts-vhd-builder-release.yaml index 0232751fdff..e24c42c588c 100644 --- a/.pipelines/.vsts-vhd-builder-release.yaml +++ b/.pipelines/.vsts-vhd-builder-release.yaml @@ -128,11 +128,11 @@ parameters: - name: build2204fipscontainerd displayName: Build 2204 FIPS containerd type: boolean - default: false + default: true - name: build2204fipsgen2containerd displayName: Build 2204 FIPS Gen2 containerd type: boolean - default: false + default: true - name: build2204arm64gen2containerd displayName: Build 2204 ARM64 Gen2 containerd type: boolean diff --git a/pkg/agent/datamodel/sig_config.go b/pkg/agent/datamodel/sig_config.go index bc8d3a93ca1..7fc3bec5405 100644 --- a/pkg/agent/datamodel/sig_config.go +++ b/pkg/agent/datamodel/sig_config.go @@ -429,14 +429,14 @@ var ( ResourceGroup: AKSUbuntuResourceGroup, Gallery: AKSUbuntuGalleryName, Definition: "2204fipscontainerd", - Version: "202404.09.0", // TODO(artunduman): Update version when the image is ready + Version: LinuxSIGImageVersion, } SIGUbuntuFipsContainerd2204Gen2ImageConfigTemplate = SigImageConfigTemplate{ ResourceGroup: AKSUbuntuResourceGroup, Gallery: AKSUbuntuGalleryName, Definition: "2204gen2fipscontainerd", - Version: "202404.09.0", // TODO(artunduman): Update version when the image is ready + Version: LinuxSIGImageVersion, } SIGUbuntuArm64Containerd2204Gen2ImageConfigTemplate = SigImageConfigTemplate{ diff --git a/pkg/agent/datamodel/sig_config_test.go b/pkg/agent/datamodel/sig_config_test.go index e2a50774ea1..0143d78092e 100644 --- a/pkg/agent/datamodel/sig_config_test.go +++ b/pkg/agent/datamodel/sig_config_test.go @@ -10,6 +10,8 @@ var _ = Describe("GetMaintainedLinuxSIGImageConfigMap", func() { expected := map[Distro]SigImageConfig{ AKSUbuntuFipsContainerd2004: SIGUbuntuFipsContainerd2004ImageConfigTemplate.WithOptions(), AKSUbuntuFipsContainerd2004Gen2: SIGUbuntuFipsContainerd2004Gen2ImageConfigTemplate.WithOptions(), + AKSUbuntuFipsContainerd2204: SIGUbuntuFipsContainerd2204ImageConfigTemplate.WithOptions(), + AKSUbuntuFipsContainerd2204Gen2: SIGUbuntuFipsContainerd2204Gen2ImageConfigTemplate.WithOptions(), AKSUbuntuArm64Containerd2204Gen2: SIGUbuntuArm64Containerd2204Gen2ImageConfigTemplate.WithOptions(), AKSUbuntuArm64Containerd2404Gen2: SIGUbuntuArm64Containerd2404Gen2ImageConfigTemplate.WithOptions(), AKSUbuntuArm64GB200Containerd2404Gen2: SIGUbuntuArm64GB200Containerd2404Gen2ImageConfigTemplate.WithOptions(), diff --git a/vhdbuilder/packer/fips-helper.sh b/vhdbuilder/packer/fips-helper.sh new file mode 100644 index 00000000000..b3b3b612fd0 --- /dev/null +++ b/vhdbuilder/packer/fips-helper.sh @@ -0,0 +1,149 @@ +#!/bin/bash +# FIPS Helper Functions for VHD Scanning + +# FIPS 140-3 encryption is not automatically supported in Linux VMs. +# Because not all extensions are onboarded to FIPS 140-3 yet, subscriptions must register the Microsoft.Compute/OptInToFips1403Compliance feature. +# After registering the feature, the VM must be created via Azure REST API calls to enable support for FIPS 140-3. +# There is currently no ETA for when FIPS 140-3 encryption is natively supported, but all information can be found here: https://learn.microsoft.com/en-us/azure/virtual-machines/extensions/agent-linux-fips + +# This script contains functions related to FIPS 140-3 compliance for Ubuntu 22.04 + +# Function to ensure FIPS 140-3 compliance feature is registered +ensure_fips_feature_registered() { + echo "Detected Ubuntu 22.04 + FIPS scenario, enabling FIPS 140-3 compliance..." + + # Enable FIPS 140-3 compliance feature if not already enabled + echo "Checking FIPS 140-3 compliance feature registration..." + FIPS_FEATURE_STATE=$(az feature show --namespace Microsoft.Compute --name OptInToFips1403Compliance --query 'properties.state' -o tsv 2>/dev/null || echo "NotRegistered") + + if [ "$FIPS_FEATURE_STATE" != "Registered" ]; then + echo "Registering FIPS 140-3 compliance feature..." + az feature register --namespace Microsoft.Compute --name OptInToFips1403Compliance + local az_register_exit_code=$? + if [ "$az_register_exit_code" -ne 0 ]; then + echo "Error: Failed to register FIPS 140-3 compliance feature (exit code: $az_register_exit_code)" >&2 + return "$az_register_exit_code" + fi + + # Poll until registered (timeout after 5 minutes) + local TIMEOUT=300 + local ELAPSED=0 + while [ "$FIPS_FEATURE_STATE" != "Registered" ] && [ $ELAPSED -lt $TIMEOUT ]; do + sleep 10 + ELAPSED=$((ELAPSED + 10)) + FIPS_FEATURE_STATE=$(az feature show --namespace Microsoft.Compute --name OptInToFips1403Compliance --query 'properties.state' -o tsv) + echo "Feature state: $FIPS_FEATURE_STATE (waited ${ELAPSED}s)" + done + + if [ "$FIPS_FEATURE_STATE" != "Registered" ]; then + echo "Error: FIPS 140-3 feature registration timed out after ${TIMEOUT}s" >&2 + return 1 + fi + + echo "FIPS 140-3 feature registered successfully. Refreshing provider..." + az provider register -n Microsoft.Compute + else + echo "FIPS 140-3 compliance feature already registered" + fi +} + +# Function to build FIPS-enabled VM request body +build_fips_vm_body() { + local location="$1" + local vm_name="$2" + local admin_username="$3" + local admin_password="$4" + local image_id="$5" + local nic_id="$6" + local umsi_resource_id="$7" + local vm_size="$8" + + cat <&2 + return "$az_rest_exit_code" + fi + + # Wait for VM to be ready (timeout after 10 minutes) + echo "Waiting for VM to be ready..." + az vm wait --created --name $SCAN_VM_NAME --resource-group $RESOURCE_GROUP_NAME --timeout 600 + + # Check for errors in the az wait command + local az_wait_exit_code=$? + if [ "$az_wait_exit_code" -ne 0 ]; then + echo "Error: Failed to await VM readiness (exit code: $az_wait_exit_code)" >&2 + return "$az_wait_exit_code" + fi +} diff --git a/vhdbuilder/packer/vhd-scanning.sh b/vhdbuilder/packer/vhd-scanning.sh index 8e455bcff61..8175b297f5f 100755 --- a/vhdbuilder/packer/vhd-scanning.sh +++ b/vhdbuilder/packer/vhd-scanning.sh @@ -74,10 +74,12 @@ function cleanup() { trap cleanup EXIT capture_benchmark "${SCRIPT_NAME}_set_variables_and_create_scan_resource_group" -VM_OPTIONS="--size Standard_D8ds_v5" +VM_SIZE="Standard_D8ds_v5" +VM_OPTIONS="--size $VM_SIZE" # shellcheck disable=SC3010 if [[ "${ARCHITECTURE,,}" == "arm64" ]]; then - VM_OPTIONS="--size Standard_D8pds_v5" + VM_SIZE="Standard_D8pds_v5" + VM_OPTIONS="--size $VM_SIZE" fi if [ "${OS_TYPE}" = "Linux" ] && [ "${ENABLE_TRUSTED_LAUNCH}" = "True" ]; then @@ -85,8 +87,9 @@ if [ "${OS_TYPE}" = "Linux" ] && [ "${ENABLE_TRUSTED_LAUNCH}" = "True" ]; then fi if [ "${OS_TYPE}" = "Linux" ] && grep -q "cvm" <<< "$FEATURE_FLAGS"; then + VM_SIZE="Standard_DC8ads_v5" # We completely re-assign the VM_OPTIONS string here to ensure that no artifacts from earlier conditionals are included - VM_OPTIONS="--size Standard_DC8ads_v5 --security-type ConfidentialVM --enable-secure-boot true --enable-vtpm true --os-disk-security-encryption-type VMGuestStateOnly --specialized true" + VM_OPTIONS="--size $VM_SIZE --security-type ConfidentialVM --enable-secure-boot true --enable-vtpm true --os-disk-security-encryption-type VMGuestStateOnly --specialized true" fi # GB200 specific VM options for scanning (uses standard ARM64 VM for now) @@ -101,15 +104,41 @@ if [ -z "$SCANNING_NIC_ID" ]; then exit 1 fi -az vm create --resource-group $RESOURCE_GROUP_NAME \ - --name $SCAN_VM_NAME \ - --image $VHD_IMAGE \ - --nics $SCANNING_NIC_ID \ - --admin-username $SCAN_VM_ADMIN_USERNAME \ - --admin-password $SCAN_VM_ADMIN_PASSWORD \ - --os-disk-size-gb 50 \ - ${VM_OPTIONS} \ - --assign-identity "${UMSI_RESOURCE_ID}" +# Create VM using appropriate method based on scenario +if [ "${OS_SKU}" = "Ubuntu" ] && [ "${OS_VERSION}" = "22.04" ] && [ "$(printf %s "${ENABLE_FIPS}" | tr '[:upper:]' '[:lower:]')" = "true" ]; then + # Source the FIPS helper functions + FULL_PATH=$(realpath $0) + CDIR=$(dirname $FULL_PATH) + source "$CDIR/fips-helper.sh" + + # Register FIPS feature and create VM using REST API. Exit if any step fails. + ensure_fips_feature_registered || exit $? + create_fips_vm "$VM_SIZE" || exit $? +else + echo "Creating VM using standard az vm create command..." + + # Disable tracing to prevent password from appearing in logs + set +x + # Use the standard VM creation approach for all other scenarios + az vm create --resource-group $RESOURCE_GROUP_NAME \ + --name $SCAN_VM_NAME \ + --image $VHD_IMAGE \ + --nics $SCANNING_NIC_ID \ + --admin-username $SCAN_VM_ADMIN_USERNAME \ + --admin-password $SCAN_VM_ADMIN_PASSWORD \ + --os-disk-size-gb 50 \ + ${VM_OPTIONS} \ + --assign-identity "${UMSI_RESOURCE_ID}" + + # Check for errors in the az vm create command + AZ_VM_CREATE_EXIT_CODE=$? + # Re-enable tracing after sensitive command + set -x + if [ $AZ_VM_CREATE_EXIT_CODE -ne 0 ]; then + echo "Error: Failed to create VM" >&2 + exit 1 + fi +fi capture_benchmark "${SCRIPT_NAME}_create_scan_vm" set +x