Déployer des conteneurs confidentiels dans un cluster Azure Red Hat OpenShift (ARO) (Préversion)
Cet article décrit les étapes requises pour déployer des conteneurs confidentiels dans un cluster ARO. Ce processus implique deux parties principales et plusieurs étapes :
Tout d’abord, déployez des conteneurs en sandbox OpenShift, en procédant comme suit :
Installez l’opérateur de conteneurs en sandbox OpenShift.
Créez le secret des pods homologues.
Créez le ConfigMap des pods homologues.
Créez le secret Azure.
Une fois les conteneurs en sandbox OpenShift déployés, déployez des conteneurs confidentiels. Cela implique les étapes suivantes :
Installez l’opérateur du client approuvé.
Créez l’itinéraire du client approuvé.
Activez la porte de fonctionnalité des conteneurs confidentiels.
Mettez à jour le ConfigMap des pods homologues.
Créez la ressource personnalisée KataConfig.
Créez le secret d’authentification du client approuvé.
Créez le ConfigMap du client approuvé.
Configurer le client approuvé.
Créez la ressource personnalisée KbsConfig.
Vérifiez le processus d’attestation.
Avant de commencer
Avant de commencer le processus de déploiement, assurez-vous que les conditions préalables suivantes sont remplies :
Cluster ARO existant (version 4.15 ou ultérieure) avec au moins un nœud Worker
Accès au cluster avec le rôle
cluster-admin
Interface CLI OpenShift installée
Important
Pour chaque pod d’une application, il existe un mappage un-à-un avec une machine virtuelle confidentielle (CVM) correspondante. Cela signifie que chaque nouveau pod nécessite une CVM distincte, ce qui garantit l’isolation entre les pods.
Partie 1 : Déployer des conteneurs en sandbox OpenShift
Installer l’opérateur de conteneurs en sandbox OpenShift
Vous pouvez installer l’opérateur de conteneurs en sandbox OpenShift via l’interface CLI ou la console Web OpenShift.
Créez un fichier manifeste
osc-namespace.yaml
:apiVersion: v1 kind: Namespace metadata: name: openshift-sandboxed-containers-operator
Créez l’espace de noms en exécutant la commande suivante :
$ oc apply -f osc-namespace.yaml
Créez un fichier manifeste
osc-operatorgroup.yaml
:apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: sandboxed-containers-operator-group namespace: openshift-sandboxed-containers-operator spec: targetNamespaces: - openshift-sandboxed-containers-operator
Créez le groupe opérateur en exécutant la commande suivante
$ oc apply -f osc-operatorgroup.yaml
Créez un fichier manifeste
osc-subscription.yaml
:apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: sandboxed-containers-operator namespace: openshift-sandboxed-containers-operator spec: channel: stable installPlanApproval: Automatic name: sandboxed-containers-operator source: redhat-operators sourceNamespace: openshift-marketplace startingCSV: sandboxed-containers-operator.v1.7.0
Créez l’abonnement en exécutant la commande suivante :
$ oc apply -f osc-subscription.yaml
Vérifiez que l’Opérateur est correctement installé en exécutant la commande suivante :
$ oc get csv -n openshift-sandboxed-containers-operator
Remarque
Cette commande peut durer plusieurs minutes.
Effectuez le suivi du processus en exécutant la commande suivante :
$ watch oc get csv -n openshift-sandboxed-containers-operator
Exemple de sortie
NAME DISPLAY VERSION REPLACES PHASE openshift-sandboxed-containers openshift-sandboxed-containers-operator 1.7.0 1.6.0 Succeeded
Créer le secret des pods homologues
Vous devez créer le secret des pods homologues pour les conteneurs en sandbox OpenShift. Le secret stocke les informations d’identification pour créer l’image de la machine virtuelle pod et les instances de pods homologues.
Par défaut, l’opérateur de conteneurs en sandbox OpenShift crée le secret selon les informations d’identification utilisées pour créer le cluster. Toutefois, vous pouvez créer manuellement un secret qui utilise des informations d’identification différentes.
Récupérez votre ID d’abonnement Azure en exécutant la commande :
$ AZURE_SUBSCRIPTION_ID=$(az account list --query "[?isDefault].id" \ -o tsv) && echo "AZURE_SUBSCRIPTION_ID: \"$AZURE_SUBSCRIPTION_ID\""
Générez le contenu du contrôle d’accès en fonction du rôle (RBAC) en exécutant la commande suivante :
$ az ad sp create-for-rbac --role Contributor --scopes /subscriptions/$AZURE_SUBSCRIPTION_ID \ --query "{ client_id: appId, client_secret: password, tenant_id: tenant }"
Exemple de sortie
{ "client_id": `AZURE_CLIENT_ID`, "client_secret": `AZURE_CLIENT_SECRET`, "tenant_id": `AZURE_TENANT_ID` }
Enregistrez la sortie RBAC à utiliser dans l’objet secret.
Créez un fichier manifeste peer-pods-secret.yaml selon l’exemple suivant :
apiVersion: v1 kind: Secret metadata: name: peer-pods-secret namespace: openshift-sandboxed-containers-operator type: Opaque stringData: AZURE_CLIENT_ID: "<azure_client_id>" AZURE_CLIENT_SECRET: "<azure_client_secret>" AZURE_TENANT_ID: "<azure_tenant_id>" AZURE_SUBSCRIPTION_ID: "<azure_subscription_id>"
- Spécifiez
AZURE_CLIENT_ID value
. - Spécifiez
AZURE_CLIENT_SECRET value
. - Spécifiez
AZURE_TENANT_ID value
. - Spécifiez
AZURE_SUBSCRIPTION_ID value
.
- Spécifiez
Créez le cluster en exécutant la commande suivante :
$ oc apply -f peer-pods-secret.yaml
Créer le ConfigMap des pods homologues
Obtenez les valeurs suivantes dans Azure :
Récupérez et enregistrez le groupe de ressources Azure :
$ AZURE_RESOURCE_GROUP=$(oc get infrastructure/cluster -o jsonpath='{.status.platformStatus.azure.resourceGroupName}') && echo "AZURE_RESOURCE_GROUP: \"$AZURE_RESOURCE_GROUP\""
Récupérez et enregistrez le nom du réseau virtuel Azure :
$ AZURE_VNET_NAME=$(az network vnet list --resource-group ${AZURE_RESOURCE_GROUP} --query "[].{Name:name}" --output tsv)
Cette valeur est utilisée pour récupérer l’ID de sous-réseau Azure.
Récupérez et enregistrez l’ID de sous-réseau Azure :
$ AZURE_SUBNET_ID=$(az network vnet subnet list --resource-group ${AZURE_RESOURCE_GROUP} --vnet-name $AZURE_VNET_NAME --query "[].{Id:id} | [? contains(Id, 'worker')]" --output tsv) && echo "AZURE_SUBNET_ID: \"$AZURE_SUBNET_ID\""
Récupérez et enregistrez l’ID de groupe de sécurité réseau (NSG) Azure :
$ AZURE_NSG_ID=$(az network nsg list --resource-group ${AZURE_RESOURCE_GROUP} --query "[].{Id:id}" --output tsv) && echo "AZURE_NSG_ID: \"$AZURE_NSG_ID\""
Récupérez et enregistrez la région Azure :
$ AZURE_REGION=$(az group show --resource-group ${AZURE_RESOURCE_GROUP} --query "{Location:location}" --output tsv) && echo "AZURE_REGION: \"$AZURE_REGION\""
Créez un fichier manifeste peer-pods-cm.yaml selon l’exemple suivant :
apiVersion: v1 kind: ConfigMap metadata: name: peer-pods-cm namespace: openshift-sandboxed-containers-operator data: CLOUD_PROVIDER: "azure" VXLAN_PORT: "9000" AZURE_INSTANCE_SIZE: "Standard_B2als_v2" AZURE_INSTANCE_SIZES: "Standard_B2als_v2,Standard_D2as_v5,Standard_D4as_v5,Standard_D2ads_v5" AZURE_SUBNET_ID: "<azure_subnet_id>" AZURE_NSG_ID: "<azure_nsg_id>" PROXY_TIMEOUT: "5m" AZURE_IMAGE_ID: "<azure_image_id>" AZURE_REGION: "<azure_region>" AZURE_RESOURCE_GROUP: "<azure_resource_group>" DISABLECVM: "true"
AZURE_INSTANCE_SIZE
est la valeur par défaut si la taille d’instance n’est pas définie dans la charge de travail.AZURE_INSTANCE_SIZES
répertorie toutes les tailles d’instance que vous pouvez spécifier lors de la création du pod. Cela vous permet de définir des tailles d’instance plus petites pour les charges de travail nécessitant moins de mémoire et de processeurs ou des tailles d’instance plus grandes pour des charges de travail plus volumineuses.- Spécifiez la valeur
AZURE_SUBNET_ID
que vous avez récupérée. - Spécifiez la valeur
AZURE_NSG_ID
que vous avez récupérée. AZURE_IMAGE_ID
est facultatif. Par défaut, cette valeur est remplie quand vous exécutez la ressource personnalisée KataConfig à l’aide d’un ID d’image Azure basé sur vos informations d’identification de cluster. Si vous créez votre propre image Azure, spécifiez l’ID d’image approprié.- Spécifiez la valeur
AZURE_REGION
que vous avez récupérée. - Spécifiez la valeur
AZURE_RESOURCE_GROUP
que vous avez récupérée.
Créez le ConfigMap en exécutant la commande suivante :
$ oc apply -f peer-pods-cm.yaml
Créer le secret Azure
Vous devez créer un secret de clé SSH qu’Azure utilise pour créer des machines virtuelles.
Générez une paire de clés SSH en exécutant la commande suivante :
$ ssh-keygen -f ./id_rsa -N ""
Créez l’objet secret en exécutant la commande suivante :
$ oc create secret generic ssh-key-secret \ -n openshift-sandboxed-containers-operator \ --from-file=id_rsa.pub=./id_rsa.pub
Supprimez les clés SSH que vous avez créées :
$ shred --remove id_rsa.pub id_rsa
Partie 2 : Déployer des conteneurs confidentiels
Installer l’Opérateur du client approuvé
Créez un fichier manifeste trustee-namespace.yaml :
apiVersion: v1 kind: Namespace metadata: name: trustee-operator-system
Créez l’espace de noms trustee-operator-system en exécutant la commande suivante :
$ oc apply -f trustee-namespace.yaml
Créez un fichier manifeste trustee-operatorgroup.yaml :
apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: trustee-operator-group namespace: trustee-operator-system spec: targetNamespaces: - trustee-operator-system
Créez le groupe Opérateur en exécutant la commande suivante :
$ oc apply -f trustee-operatorgroup.yaml
Créez un fichier manifeste trustee-subscription.yaml :
apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: trustee-operator namespace: trustee-operator-system spec: channel: stable installPlanApproval: Automatic name: trustee-operator source: redhat-operators sourceNamespace: openshift-marketplace startingCSV: trustee-operator.v0.1.0
Créez l’abonnement en exécutant la commande suivante :
$ oc apply -f trustee-subscription.yaml
Vérifiez que l’Opérateur est correctement installé en exécutant la commande suivante :
$ oc get csv -n trustee-operator-system
Cette commande peut durer plusieurs minutes.
Effectuez le suivi du processus en exécutant la commande suivante :
$ watch oc get csv -n trustee-operator-system
Exemple de sortie
NAME DISPLAY PHASE trustee-operator.v0.1.0 Trustee Operator 0.1.0 Succeeded
Créer l’itinéraire du client approuvé
Créez un itinéraire sécurisé avec une terminaison TLS en périphérie pour le client approuvé. Le trafic d’entrée externe atteint les pods routeurs en mode HTTPS et transmet aux pods du client approuvé en mode HTTP.
Créez un itinéraire en périphérie en exécutant la commande suivante :
$ oc create route edge --service=kbs-service --port kbs-port \ -n trustee-operator-system
Remarque
Actuellement, seul un itinéraire disposant d’un certificat signé par une autorité de certification valide est pris en charge. Vous ne pouvez pas utiliser d’itinéraire avec un certificat auto-signé.
Créez la variable TRUSTEE_HOST en exécutant la commande suivante :
$ TRUSTEE_HOST=$(oc get route -n trustee-operator-system kbs-service \ -o jsonpath={.spec.host})
Vérifiez l’itinéraire en exécutant la commande suivante :
$ echo $TRUSTEE_HOST
Exemple de sortie
kbs-service-trustee-operator-system.apps.memvjias.eastus.aroapp.io
Enregistrez cette valeur pour le ConfigMap des pods homologues.
Activer la porte de fonctionnalité des conteneurs confidentiels
Créez un fichier manifeste
cc-feature-gate.yaml
:apiVersion: v1 kind: ConfigMap metadata: name: osc-feature-gates namespace: openshift-sandboxed-containers-operator data: confidential: "true"
Créez le ConfigMap en exécutant la commande suivante :
$ oc apply -f cc-feature-gate.yaml
Mettre à jour le ConfigMap des pods homologues
Obtenez les valeurs suivantes de votre instance Azure :
i. Récupérez et enregistrez le groupe de ressources Azure :
$ AZURE_RESOURCE_GROUP=$(oc get infrastructure/cluster -o jsonpath='{.status.platformStatus.azure.resourceGroupName}') && echo "AZURE_RESOURCE_GROUP: \"$AZURE_RESOURCE_GROUP\""
ii. Récupérez et enregistrez le nom du réseau virtuel Azure :
$ AZURE_VNET_NAME=$(az network vnet list --resource-group ${AZURE_RESOURCE_GROUP} --query "[].{Name:name}" --output tsv)
Cette valeur est utilisée pour récupérer l’ID de sous-réseau Azure.
iii. Récupérez et enregistrez l’ID de sous-réseau Azure :
$ AZURE_SUBNET_ID=$(az network vnet subnet list --resource-group ${AZURE_RESOURCE_GROUP} --vnet-name $AZURE_VNET_NAME --query "[].{Id:id} | [? contains(Id, 'worker')]" --output tsv) && echo "AZURE_SUBNET_ID: \"$AZURE_SUBNET_ID\""
iv. Récupérez et enregistrez l’ID de groupe de sécurité réseau (NSG) Azure :
$ AZURE_NSG_ID=$(az network nsg list --resource-group ${AZURE_RESOURCE_GROUP} --query "[].{Id:id}" --output tsv) && echo "AZURE_NSG_ID: \"$AZURE_NSG_ID\""
v. Récupérez et enregistrez la région Azure :
$ AZURE_REGION=$(az group show --resource-group ${AZURE_RESOURCE_GROUP} --query "{Location:location}" --output tsv) && echo "AZURE_REGION: \"$AZURE_REGION\""
Créez un fichier manifeste
peer-pods-cm.yaml
selon l’exemple suivant :apiVersion: v1 kind: ConfigMap metadata: name: peer-pods-cm namespace: openshift-sandboxed-containers-operator data: CLOUD_PROVIDER: "azure" VXLAN_PORT: "9000" AZURE_INSTANCE_SIZE: "Standard_DC2as_v5" AZURE_INSTANCE_SIZES: "Standard_DC2as_v5,Standard_DC4as_v5,Standard_DC8as_v5" AZURE_SUBNET_ID: "<azure_subnet_id>" AZURE_NSG_ID: "<azure_nsg_id>" PROXY_TIMEOUT: "5m" AZURE_IMAGE_ID: "<azure_image_id>" AZURE_REGION: "<azure_region>" AZURE_RESOURCE_GROUP: "<azure_resource_group>" DISABLECVM: "false" AA_KBC_PARAMS: "cc_kbc::https://${TRUSTEE_HOST}"
AZURE_INSTANCE_SIZE
est la valeur par défaut si la taille d’instance n’est pas définie dans la charge de travail. Pour TDX, spécifiez« Standard_EC4eds_v5 ».AZURE_INSTANCE_SIZES
répertorie toutes les tailles d’instance que vous pouvez spécifier lors de la création du pod. Cela vous permet de définir des tailles d’instance plus petites pour les charges de travail nécessitant moins de mémoire et de processeurs ou des tailles d’instance plus grandes pour des charges de travail plus volumineuses. For TDX, spécifiez « Standard_EC4eds_v5, Standard_EC8eds_v5, Standard_EC16eds_v5 ».- Spécifiez la valeur
AZURE_SUBNET_ID
que vous avez récupérée. - Spécifiez la valeur
AZURE_NSG_ID
que vous avez récupérée. AZURE_IMAGE_ID
(Facultatif) : par défaut, cette valeur est remplie quand vous exécutez la ressource personnalisée KataConfig à l’aide d’un ID d’image Azure basé sur vos informations d’identification de cluster. Si vous créez votre propre image Azure, spécifiez l’ID d’image approprié.- Spécifiez la valeur
AZURE_REGION
que vous avez récupérée. - Spécifiez la valeur
AZURE_RESOURCE_GROUP
que vous avez récupérée. AA_KBC_PARAMS
spécifie le nom d’hôte de l’itinéraire du client approuvé.
Créez le ConfigMap en exécutant la commande suivante :
$ oc apply -f peer-pods-cm.yaml
Redémarrez le démon
peerpodconfig-ctrl-caa-daemon
en exécutant la commande suivante :$ oc set env ds/peerpodconfig-ctrl-caa-daemon \ -n openshift-sandboxed-containers-operator REBOOT="$(date)"
Créer la ressource personnalisée KataConfig
Créez un fichier manifeste
example-kataconfig.yaml
selon l’exemple suivant :apiVersion: kataconfiguration.openshift.io/v1 kind: KataConfig metadata: name: example-kataconfig spec: enablePeerPods: true logLevel: info # kataConfigPoolSelector: # matchLabels: # <label_key>: '<label_value>'
Facultatif : si vous avez appliqué des étiquettes de nœud pour installer kata-remote sur des nœuds spécifiques, spécifiez la clé et la valeur, par exemple, cc: 'true'.
Créez la ressource personnalisée KataConfig en exécutant la commande suivante :
$ oc apply -f example-kataconfig.yaml
La nouvelle ressource personnalisée KataConfig est créée et installe kata-remote comme classe de runtime sur les nœuds Worker.
Remarque
Attendez que l’installation de kata-remote se termine et que les nœuds Worker redémarrent avant de vérifier l’installation.
Surveillez la progression de l'installation en exécutant les commandes suivantes :
$ watch "oc describe kataconfig | sed -n /^Status:/,/^Events/p"
Quand l’état de tous les Workers sous kataNodes passe à Installé et que la condition InProgress passe à False sans spécifier de raison, le kata-remote est installé sur le cluster.
Vérifiez le jeu de démons en exécutant la commande suivante :
$ oc get -n openshift-sandboxed-containers-operator ds/peerpodconfig-ctrl-caa-daemon
Vérifiez les classes de runtime en exécutant la commande suivante :
$ oc get runtimeclass
Exemple de sortie
NAME HANDLER AGE kata-remote kata-remote 152m
Créer le secret d’authentification du client approuvé
Créez une clé privée en exécutant la commande suivante :
$ openssl genpkey -algorithm ed25519 > privateKey
Créez une clé publique en exécutant la commande suivante :
$ openssl pkey -in privateKey -pubout -out publicKey
Créez un secret en exécutant la commande suivante :
$ oc create secret generic kbs-auth-public-key --from-file=publicKey -n trustee-operator-system
Vérifiez le secret en exécutant la commande suivante :
$ oc get secret -n trustee-operator-system
Créer le ConfigMap du client approuvé
Créez un fichier manifeste
kbs-config-cm.yaml
:apiVersion: v1 kind: ConfigMap metadata: name: kbs-config-cm namespace: trustee-operator-system data: kbs-config.json: | { "insecure_http" : true, "sockets": ["0.0.0.0:8080"], "auth_public_key": "/etc/auth-secret/publicKey", "attestation_token_config": { "attestation_token_type": "CoCo" }, "repository_config": { "type": "LocalFs", "dir_path": "/opt/confidential-containers/kbs/repository" }, "as_config": { "work_dir": "/opt/confidential-containers/attestation-service", "policy_engine": "opa", "attestation_token_broker": "Simple", "attestation_token_config": { "duration_min": 5 }, "rvps_config": { "store_type": "LocalJson", "store_config": { "file_path": "/opt/confidential-containers/rvps/reference-values/reference-values.json" } } }, "policy_engine_config": { "policy_path": "/opt/confidential-containers/opa/policy.rego" } }
Créez le ConfigMap en exécutant la commande suivante :
$ oc apply -f kbs-config-cm.yaml
Configurer le client approuvé
Configurez les paramètres de client approuvé suivants :
Configurer les valeurs de référence
Vous pouvez configurer des valeurs de référence pour le RVPS (Reference Value Provider Service) en spécifiant les synthèses approuvées de votre plateforme matérielle.
Le client collecte les mesures du logiciel en cours d’exécution, du matériel et du microprogramme de l’environnement d’exécution de confiance (TEE) et envoie un devis avec les revendications au serveur d’attestation. Ces mesures doivent correspondre aux synthèses approuvées référencées auprès du client approuvé. Ce processus garantit que la machine virtuelle confidentielle (CVM) exécute la pile logicielle attendue et n’a pas été falsifiée.
Créez un fichier manifeste
rvps-configmap.yaml
:apiVersion: v1 kind: ConfigMap metadata: name: rvps-reference-values namespace: trustee-operator-system data: reference-values.json: | [ ]
Pour
reference-values.json
, spécifiez les synthèses approuvées de votre plateforme matérielle si nécessaire. Sinon, laissez-le vide.Créez le ConfigMap RVPS en exécutant la commande suivante :
$ oc apply -f rvps-configmap.yaml
Créer votre propre stratégie d’attestation
Vous pouvez remplacer la stratégie d’attestation par défaut en créant votre propre stratégie d’attestation.
Créez un fichier manifeste attestation-policy.yaml selon l’exemple suivant :
apiVersion: v1 kind: ConfigMap metadata: name: attestation-policy namespace: trustee-operator-system data: default.rego: | package policy import future.keywords.every default allow = false allow { every k, v in input { judge_field(k, v) } } judge_field(input_key, input_value) { has_key(data.reference, input_key) reference_value := data.reference[input_key] match_value(reference_value, input_value) } judge_field(input_key, input_value) { not has_key(data.reference, input_key) } match_value(reference_value, input_value) { not is_array(reference_value) input_value == reference_value } match_value(reference_value, input_value) { is_array(reference_value) array_include(reference_value, input_value) } array_include(reference_value_array, input_value) { reference_value_array == [] } array_include(reference_value_array, input_value) { reference_value_array != [] some i reference_value_array[i] == input_value } has_key(m, k) { _ = m[k] }
Pour
package policy
, la stratégie d’attestation respecte la spécification d’Open Policy Agent. Dans cet exemple, la stratégie d’attestation compare les revendications fournies dans le rapport d’attestation aux valeurs de référence inscrites dans la base de données RVPS. Le processus d’attestation réussit uniquement si toutes les valeurs correspondent.Créez le ConfigMap de stratégie d’attestation en exécutant la commande suivante :
$ oc apply -f attestation-policy.yaml
Service caching du certificat d’approvisionnement de TDX
Si votre TEE est Intel Trust Domain Extensions (TDX), vous devez configurer le service caching du certificat d’approvisionnement (PCCS). Le PCCS récupère les certificats PCK (Provisioning Certification Key) et les met en cache dans une base de données locale.
Créez un fichier manifeste tdx-config.yaml :
apiVersion: v1 kind: ConfigMap metadata: name: tdx-config namespace: trustee-operator-system data: sgx_default_qcnl.conf: | \ { "collateral_service": "https://api.trustedservices.intel.com/sgx/certification/v4/", "pccs_url": "<pccs_url>" }
Pour
pccs_url
, spécifiez l’URL PCCS, par exemple, https://localhost:8081/sgx/certification/v4/.Créez le ConfigMap TDX en exécutant la commande suivante :
$ oc apply -f tdx-config.yaml
Créer un secret pour la vérification de la signature d’image conteneur
Si vous utilisez la vérification de signature d’image conteneur, vous devez créer un secret qui contient la clé de signature d’image conteneur publique. L’opérateur de client approuvé utilise le secret pour vérifier la signature, ce qui garantit que seules les images conteneur approuvées et authentifiées sont déployées dans votre environnement.
Créez un secret pour la vérification de la signature d’image conteneur en exécutant la commande suivante :
$ oc apply secret generic <type> \ --from-file=<tag>=./<public_key_file> \ -n trustee-operator-system
- Spécifiez le type de secret KBS, par exemple,
img-sig
. - Spécifiez l’étiquette de secret, par exemple
pub-key
, et la clé de signature d’image conteneur publique.
- Spécifiez le type de secret KBS, par exemple,
Enregistrez la valeur
<type>
. Vous devez ajouter cette valeur à la clé spec.kbsSecretResources lorsque vous créez la ressource personnalisée KbsConfig.
Créer la stratégie de vérification de signature d’image conteneur
Vous devez créer la stratégie de vérification de signature d’image conteneur, car la vérification de signature est toujours activée.
Important
Si cette stratégie est manquante, les pods ne démarrent pas. Si vous n’utilisez pas la vérification de signature d’image conteneur, vous créez la stratégie sans vérification de signature.
Créez un fichier security-policy-config.json selon les exemples suivants :
Sans vérification de signature :
{ "default": [ { "type": "insecureAcceptAnything" }], "transports": {} }
Avec vérification de signature :
{ "default": [ { "type": "insecureAcceptAnything" ], "transports": { "<transport>": { "<registry>/<image>": [ { "type": "sigstoreSigned", "keyPath": "kbs:///default/<type>/<tag>" } ] } } }
- Spécifiez le référentiel d’images pour le transport, par exemple, « docker ».
- Spécifiez le registre de conteneurs et l’image, par exemple, « quay.io/mon-image ».
- Spécifiez le type et l’étiquette du secret de vérification de signature d’image conteneur que vous avez créé, par exemple, « img-sig/pub-key ».
Créez la stratégie de sécurité en exécutant la commande suivante :
$ oc apply secret generic security-policy \ --from-file=osc=./<security-policy-config.json> \ -n trustee-operator-system
Ne modifiez pas le type de secret (security-policy) ou la clé (osc).
Le secret security-policy est spécifié dans la clé
spec.kbsSecretResources
de la ressource personnalisée KbsConfig.
Créer la ressource personnalisée KbsConfig
Vous devez créer la ressource personnalisée KbsConfig pour lancer le client approuvé.
Créez un fichier manifeste
kbsconfig-cr.yaml
:apiVersion: confidentialcontainers.org/v1alpha1 kind: KbsConfig metadata: labels: app.kubernetes.io/name: kbsconfig app.kubernetes.io/instance: kbsconfig app.kubernetes.io/part-of: trustee-operator app.kubernetes.io/managed-by: kustomize app.kubernetes.io/created-by: trustee-operator name: kbsconfig namespace: trustee-operator-system spec: kbsConfigMapName: kbs-config-cm kbsAuthSecretName: kbs-auth-public-key kbsDeploymentType: AllInOneDeployment kbsRvpsRefValuesConfigMapName: rvps-reference-values kbsSecretResources: ["kbsres1", "security-policy", "<type>"] kbsResourcePolicyConfigMapName: resource-policy # tdxConfigSpec: # kbsTdxConfigMapName: tdx-config # kbsAttestationPolicyConfigMapName: attestation-policy # kbsServiceType: <service_type>
- Facultatif : spécifiez la valeur
type
du secret de vérification de signature d’image conteneur si vous avez créé le secret, par exemple,img-sig
. Si vous n’avez pas créé le secret, définissez la valeurkbsSecretResources
sur["kbsres1", "security-policy"]
. - Supprimez les marques de commentaire de
tdxConfigSpec.kbsTdxConfigMapName: tdx-config
pour Intel Trust Domain Extensions. - Supprimez les marques de commentaire de
kbsAttestationPolicyConfigMapName: attestation-policy
si vous créez une stratégie d’attestation personnalisée. - Supprimez les marques de commentaire de
kbsServiceType: <service_type>
si vous créez un type de service, autre que le service ClusterIP par défaut, pour exposer des applications au sein du trafic externe du cluster. Vous pouvez spécifierNodePort
,LoadBalancer
, ouExternalName
.
- Facultatif : spécifiez la valeur
Créez la ressource personnalisée KbsConfig en exécutant la commande suivante :
$ oc apply -f kbsconfig-cr.yaml
Vérifier la configuration du client approuvé
Vérifiez la configuration du client approuvé en vérifiant les pods et les journaux du client approuvé.
Définissez le projet par défaut en exécutant la commande suivante :
$ oc project trustee-operator-system
Vérifiez les pods en exécutant la commande suivante :
$ oc get pods -n trustee-operator-system
Exemple de sortie
NAME READY STATUS RESTARTS AGE trustee-deployment-8585f98449-9bbgl 1/1 Running 0 22m trustee-operator-controller-manager-5fbd44cd97-55dlh 2/2 Running 0 59m
Définissez la variable d’environnement POD_NAME en exécutant la commande suivante :
$ POD_NAME=$(oc get pods -l app=kbs -o jsonpath='{.items[0].metadata.name}' -n trustee-operator-system)
Vérifiez les journaux du pod en exécutant la commande suivante :
$ oc logs -n trustee-operator-system $POD_NAME
Exemple de sortie
[2024-05-30T13:44:24Z INFO kbs] Using config file /etc/kbs-config/kbs-config.json [2024-05-30T13:44:24Z WARN attestation_service::rvps] No RVPS address provided and will launch a built-in rvps [2024-05-30T13:44:24Z INFO attestation_service::token::simple] No Token Signer key in config file, create an ephemeral key and without CA pubkey cert [2024-05-30T13:44:24Z INFO api_server] Starting HTTPS server at [0.0.0.0:8080] [2024-05-30T13:44:24Z INFO actix_server::builder] starting 12 workers [2024-05-30T13:44:24Z INFO actix_server::server] Tokio runtime found; starting in existing Tokio runtime
Vérifier le processus d’attestation
Vous pouvez vérifier le processus d’attestation en créant un pod de test et en récupérant son secret.
Important : cette procédure est un exemple qui permet de vérifier que l’attestation fonctionne. N’écrivez pas de données sensibles en E/S standard, car les données peuvent être capturées à l’aide d’un vidage de mémoire. Seules les données écrites en mémoire sont chiffrées.
Par défaut, une stratégie côté agent intégrée à l’image de la machine virtuelle de pod désactive les API d’exécution et d’enregistrement d’un pod de conteneurs confidentiels. Cette stratégie garantit que les données sensibles ne sont pas écrites en E/S standard.
Dans un scénario de test, vous pouvez remplacer la restriction au moment du runtime en ajoutant une annotation de stratégie au pod. En préversion technologique, les annotations de stratégie du runtime ne sont pas vérifiées par une attestation distante.
Créez un fichier manifeste verification-pod.yaml :
apiVersion: v1 kind: Pod metadata: name: ocp-cc-pod labels: app: ocp-cc-pod annotations: io.katacontainers.config.agent.policy: cGFja2FnZSBhZ2VudF9wb2xpY3kKCmRlZmF1bHQgQWRkQVJQTmVpZ2hib3JzUmVxdWVzdCA6PSB0cnVlCmRlZmF1bHQgQWRkU3dhcFJlcXVlc3QgOj0gdHJ1ZQpkZWZhdWx0IENsb3NlU3RkaW5SZXF1ZXN0IDo9IHRydWUKZGVmYXVsdCBDb3B5RmlsZVJlcXVlc3QgOj0gdHJ1ZQpkZWZhdWx0IENyZWF0ZUNvbnRhaW5lclJlcXVlc3QgOj0gdHJ1ZQpkZWZhdWx0IENyZWF0ZVNhbmRib3hSZXF1ZXN0IDo9IHRydWUKZGVmYXVsdCBEZXN0cm95U2FuZGJveFJlcXVlc3QgOj0gdHJ1ZQpkZWZhdWx0IEV4ZWNQcm9jZXNzUmVxdWVzdCA6PSB0cnVlCmRlZmF1bHQgR2V0TWV0cmljc1JlcXVlc3QgOj0gdHJ1ZQpkZWZhdWx0IEdldE9PTUV2ZW50UmVxdWVzdCA6PSB0cnVlCmRlZmF1bHQgR3Vlc3REZXRhaWxzUmVxdWVzdCA6PSB0cnVlCmRlZmF1bHQgTGlzdEludGVyZmFjZXNSZXF1ZXN0IDo9IHRydWUKZGVmYXVsdCBMaXN0Um91dGVzUmVxdWVzdCA6PSB0cnVlCmRlZmF1bHQgTWVtSG90cGx1Z0J5UHJvYmVSZXF1ZXN0IDo9IHRydWUKZGVmYXVsdCBPbmxpbmVDUFVNZW1SZXF1ZXN0IDo9IHRydWUKZGVmYXVsdCBQYXVzZUNvbnRhaW5lclJlcXVlc3QgOj0gdHJ1ZQpkZWZhdWx0IFB1bGxJbWFnZVJlcXVlc3QgOj0gdHJ1ZQpkZWZhdWx0IFJlYWRTdHJlYW1SZXF1ZXN0IDo9IHRydWUKZGVmYXVsdCBSZW1vdmVDb250YWluZXJSZXF1ZXN0IDo9IHRydWUKZGVmYXVsdCBSZW1vdmVTdGFsZVZpcnRpb2ZzU2hhcmVNb3VudHNSZXF1ZXN0IDo9IHRydWUKZGVmYXVsdCBSZXNlZWRSYW5kb21EZXZSZXF1ZXN0IDo9IHRydWUKZGVmYXVsdCBSZXN1bWVDb250YWluZXJSZXF1ZXN0IDo9IHRydWUKZGVmYXVsdCBTZXRHdWVzdERhdGVUaW1lUmVxdWVzdCA6PSB0cnVlCmRlZmF1bHQgU2V0UG9saWN5UmVxdWVzdCA6PSB0cnVlCmRlZmF1bHQgU2lnbmFsUHJvY2Vzc1JlcXVlc3QgOj0gdHJ1ZQpkZWZhdWx0IFN0YXJ0Q29udGFpbmVyUmVxdWVzdCA6PSB0cnVlCmRlZmF1bHQgU3RhcnRUcmFjaW5nUmVxdWVzdCA6PSB0cnVlCmRlZmF1bHQgU3RhdHNDb250YWluZXJSZXF1ZXN0IDo9IHRydWUKZGVmYXVsdCBTdG9wVHJhY2luZ1JlcXVlc3QgOj0gdHJ1ZQpkZWZhdWx0IFR0eVdpblJlc2l6ZVJlcXVlc3QgOj0gdHJ1ZQpkZWZhdWx0IFVwZGF0ZUNvbnRhaW5lclJlcXVlc3QgOj0gdHJ1ZQpkZWZhdWx0IFVwZGF0ZUVwaGVtZXJhbE1vdW50c1JlcXVlc3QgOj0gdHJ1ZQpkZWZhdWx0IFVwZGF0ZUludGVyZmFjZVJlcXVlc3QgOj0gdHJ1ZQpkZWZhdWx0IFVwZGF0ZVJvdXRlc1JlcXVlc3QgOj0gdHJ1ZQpkZWZhdWx0IFdhaXRQcm9jZXNzUmVxdWVzdCA6PSB0cnVlCmRlZmF1bHQgV3JpdGVTdHJlYW1SZXF1ZXN0IDo9IHRydWUK spec: runtimeClassName: kata-remote containers: - name: skr-openshift image: registry.access.redhat.com/ubi9/ubi:9.3 command: - sleep - "36000" securityContext: privileged: false seccompProfile: type: RuntimeDefault
Le pod metada
annotations
remplace la stratégie qui empêche l’écriture de données sensibles en E/S standard.Créez le pod en exécutant la commande suivante :
$ oc create -f verification-pod.yaml
Connectez-vous à l’interpréteur de commandes Bash du pod ocp-cc-pod en exécutant la commande suivante :
$ oc exec -it ocp-cc-pod -- bash
Récupérez (fetch) le secret de pod en exécutant la commande suivante :
$ curl http://127.0.0.1:8006/cdh/resource/default/kbsres1/key1
Exemple de sortie
res1val1
Le serveur du client approuvé retourne le secret uniquement si l’attestation réussit.