test: add integration test for initdata

This test we will test initdata in the following logic
1. Enable image signature verification via kernel commandline
2. Set Trustee address via initdata
3. Pull an image from a banned registry
4. Check if the pulling fails with log `image security validation
failed` the initdata works.

Note that if initdata does not work, the pod still fails to launch. But
the error information is `[CDH] [ERROR]: Get Resource failed` which
internally means that the KBS URL has not been set correctly.

This test now only runs on qemu-coco-dev+x86_64 and qemu-tdx

Signed-off-by: Xynnn007 <xynnn@linux.alibaba.com>
This commit is contained in:
Xynnn007 2025-04-03 17:28:53 +08:00
parent 91bb6b7c34
commit b1c72c7094
3 changed files with 234 additions and 0 deletions

View File

@ -171,3 +171,39 @@ function create_coco_pod_yaml() {
set_node "${kata_pod}" "$node"
fi
}
# This function creates pod yaml. Parameters
# - $1: image reference
# - $2: annotation `io.katacontainers.config.hypervisor.kernel_params`
# - $3: anootation `io.katacontainers.config.runtime.cc_init_data`
# - $4: node
function create_coco_pod_yaml_with_annotations() {
image=$1
kernel_params_annotation_value=${2:-}
cc_initdata_annotation_value=${3:-}
node=${4:-}
kernel_params_annotation_key="io.katacontainers.config.hypervisor.kernel_params"
cc_initdata_annotation_key="io.katacontainers.config.runtime.cc_init_data"
# Note: this is not local as we use it in the caller test
kata_pod="$(new_pod_config "$image" "kata-${KATA_HYPERVISOR}")"
set_container_command "${kata_pod}" "0" "sleep" "30"
# Set annotations
set_metadata_annotation "${kata_pod}" \
"io.containerd.cri.runtime-handler" \
"kata-${KATA_HYPERVISOR}"
set_metadata_annotation "${kata_pod}" \
"${kernel_params_annotation_key}" \
"${kernel_params_annotation_value}"
set_metadata_annotation "${kata_pod}" \
"${cc_initdata_annotation_key}" \
"${cc_initdata_annotation_value}"
add_allow_all_policy_to_yaml "${kata_pod}"
if [ -n "$node" ]; then
set_node "${kata_pod}" "$node"
fi
}

View File

@ -0,0 +1,197 @@
#!/usr/bin/env bats
# Copyright (c) 2025 Alibaba Cloud
#
# SPDX-License-Identifier: Apache-2.0
#
# This test we will test initdata in the following logic
# 1. Enable image signature verification via kernel commandline
# 2. Set Trustee address via initdata
# 3. Pull an image from a banned registry
# 4. Check if the pulling fails with log `image security validation failed`,
# the initdata works.
#
# Note that if initdata does not work, the pod still fails to launch (hang at
# CreatingContainer status). The error information is
# `[CDH] [ERROR]: Get Resource failed` which internally means that the KBS URL
# has not been set correctly.
#
# TODO: After https://github.com/kata-containers/kata-containers/issues/9266
# is resolved, both KBS URI and policy URI can be set via initdata.
load "${BATS_TEST_DIRNAME}/lib.sh"
load "${BATS_TEST_DIRNAME}/confidential_common.sh"
export KBS="${KBS:-false}"
export KATA_HYPERVISOR="${KATA_HYPERVISOR:-qemu}"
setup() {
if ! is_confidential_runtime_class; then
skip "Test not supported for ${KATA_HYPERVISOR}."
fi
[ "${SNAPSHOTTER:-}" = "nydus" ] || skip "None snapshotter was found but this test requires one"
setup_common || die "setup_common failed"
FAIL_TEST_IMAGE="quay.io/prometheus/busybox:latest"
SECURITY_POLICY_KBS_URI="kbs:///default/security-policy/test"
}
function setup_kbs_image_policy_for_initdata() {
if [ "${KBS}" = "false" ]; then
skip "Test skipped as KBS not setup"
fi
export CURRENT_ARCH=$(uname -m)
if [ "${CURRENT_ARCH}" != "x86_64" ]; then
skip "Test skipped as only x86-64 supports, while current platform is ${CURRENT_ARCH}"
fi
# TODO: Enable for more archs
case "$KATA_HYPERVISOR" in
"qemu-tdx"|"qemu-coco-dev")
;;
*)
skip "Test not supported for ${KATA_HYPERVISOR}."
;;
esac
default_policy="${1:-insecureAcceptAnything}"
policy_json=$(cat << EOF
{
"default": [
{
"type": "${default_policy}"
}
],
"transports": {
"docker": {
"quay.io/prometheus": [
{
"type": "reject"
}
]
}
}
}
EOF
)
if ! is_confidential_hardware; then
kbs_set_allow_all_resources
fi
kbs_set_resource "default" "security-policy" "test" "${policy_json}"
}
@test "Test that creating a container from an rejected image configured by initdata, fails according to policy reject" {
setup_kbs_image_policy_for_initdata
CC_KBS_ADDRESS=$(kbs_k8s_svc_http_addr)
kernel_parameter="agent.image_policy_file=${SECURITY_POLICY_KBS_URI} agent.enable_signature_verification=true"
initdata_annotation=$(gzip -c << EOF | base64 -w0
version = "0.1.0"
algorithm = "sha256"
[data]
"aa.toml" = '''
[token_configs]
[token_configs.coco_as]
# TODO: we should fix this on AA side to set this a default value if not set.
url = "${CC_KBS_ADDRESS}"
[token_configs.kbs]
url = "${CC_KBS_ADDRESS}"
'''
"cdh.toml" = '''
[kbc]
name = "cc_kbc"
url = "${CC_KBS_ADDRESS}"
'''
"policy.rego" = '''
# Copyright (c) 2023 Microsoft Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
package agent_policy
default AddARPNeighborsRequest := true
default AddSwapRequest := true
default CloseStdinRequest := true
default CopyFileRequest := true
default CreateContainerRequest := true
default CreateSandboxRequest := true
default DestroySandboxRequest := true
default ExecProcessRequest := true
default GetMetricsRequest := true
default GetOOMEventRequest := true
default GuestDetailsRequest := true
default ListInterfacesRequest := true
default ListRoutesRequest := true
default MemHotplugByProbeRequest := true
default OnlineCPUMemRequest := true
default PauseContainerRequest := true
default PullImageRequest := true
default ReadStreamRequest := true
default RemoveContainerRequest := true
default RemoveStaleVirtiofsShareMountsRequest := true
default ReseedRandomDevRequest := true
default ResumeContainerRequest := true
default SetGuestDateTimeRequest := true
default SetPolicyRequest := true
default SignalProcessRequest := true
default StartContainerRequest := true
default StartTracingRequest := true
default StatsContainerRequest := true
default StopTracingRequest := true
default TtyWinResizeRequest := true
default UpdateContainerRequest := true
default UpdateEphemeralMountsRequest := true
default UpdateInterfaceRequest := true
default UpdateRoutesRequest := true
default WaitProcessRequest := true
default WriteStreamRequest := true
'''
EOF
)
create_coco_pod_yaml_with_annotations "${FAIL_TEST_IMAGE}" "${kernel_parameter}" "${initdata_annotation}" "${node}"
# For debug sake
echo "Pod ${kata_pod}: $(cat ${kata_pod})"
assert_pod_fail "${kata_pod}"
assert_logs_contain "${node}" kata "${node_start_time}" "image security validation failed"
}
@test "Test that creating a container from an rejected image not configured by initdata, fails according to CDH error" {
setup_kbs_image_policy_for_initdata
kernel_parameter="agent.image_policy_file=${SECURITY_POLICY_KBS_URI} agent.enable_signature_verification=true"
create_coco_pod_yaml_with_annotations "${FAIL_TEST_IMAGE}" "${kernel_parameter}" "" "${node}"
# For debug sake
echo "Pod ${kata_pod}: $(cat ${kata_pod})"
if k8s_create_pod "${kata_pod}" ; then
echo "Expected failure, but pod ${kata_pod} launched successfully."
return 1
fi
assert_logs_contain "${node}" kata "${node_start_time}" "\[CDH\] \[ERROR\]: Get Resource failed"
}
teardown() {
if ! is_confidential_runtime_class; then
skip "Test not supported for ${KATA_HYPERVISOR}."
fi
[ "${SNAPSHOTTER:-}" = "nydus" ] || skip "None snapshotter was found but this test requires one"
teardown_common "${node}" "${node_start_time:-}"
}

View File

@ -37,6 +37,7 @@ else
"k8s-guest-pull-image-encrypted.bats" \
"k8s-guest-pull-image-authenticated.bats" \
"k8s-guest-pull-image-signature.bats" \
"k8s-initdata.bats" \
"k8s-confidential-attestation.bats" \
)