Partage via


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 :

  1. Installez l’opérateur de conteneurs en sandbox OpenShift.

  2. Créez le secret des pods homologues.

  3. Créez le ConfigMap des pods homologues.

  4. 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 :

  1. Installez l’opérateur du client approuvé.

  2. Créez l’itinéraire du client approuvé.

  3. Activez la porte de fonctionnalité des conteneurs confidentiels.

  4. Mettez à jour le ConfigMap des pods homologues.

  5. Créez la ressource personnalisée KataConfig.

  6. Créez le secret d’authentification du client approuvé.

  7. Créez le ConfigMap du client approuvé.

  8. Configurer le client approuvé.

  9. Créez la ressource personnalisée KbsConfig.

  10. 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.

  1. Créez un fichier manifeste osc-namespace.yaml :

    apiVersion: v1
    kind: Namespace
    metadata:
        name: openshift-sandboxed-containers-operator
    
  2. Créez l’espace de noms en exécutant la commande suivante :

    $ oc apply -f osc-namespace.yaml

  3. 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
    
  4. Créez le groupe opérateur en exécutant la commande suivante

    $ oc apply -f osc-operatorgroup.yaml

  5. 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
    
  6. Créez l’abonnement en exécutant la commande suivante :

    $ oc apply -f osc-subscription.yaml

  7. 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.

  8. 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.

  1. 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\""
    
  2. 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`
        }
    
  3. Enregistrez la sortie RBAC à utiliser dans l’objet secret.

  4. 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.
  5. Créez le cluster en exécutant la commande suivante :

    $ oc apply -f peer-pods-secret.yaml

Créer le ConfigMap des pods homologues

  1. Obtenez les valeurs suivantes dans Azure :

    1. 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\""

    2. 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.

    3. 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\""
      
    4. 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\""
      
    5. 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\""

  2. 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.
  3. 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.

  1. Générez une paire de clés SSH en exécutant la commande suivante :

    $ ssh-keygen -f ./id_rsa -N ""

  2. 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
    
  3. 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é

  1. Créez un fichier manifeste trustee-namespace.yaml :

    apiVersion: v1
    kind: Namespace
    metadata:
    name: trustee-operator-system
    
  2. Créez l’espace de noms trustee-operator-system en exécutant la commande suivante :

    $ oc apply -f trustee-namespace.yaml

  3. 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
    
  4. Créez le groupe Opérateur en exécutant la commande suivante :

    $ oc apply -f trustee-operatorgroup.yaml

  5. 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
    
  6. Créez l’abonnement en exécutant la commande suivante :

    $ oc apply -f trustee-subscription.yaml

  7. 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.

  8. 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.

  1. 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é.

  2. 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})
    
  3. Vérifiez l’itinéraire en exécutant la commande suivante :

    $ echo $TRUSTEE_HOST

    Exemple de sortiekbs-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

  1. 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"
    
  2. Créez le ConfigMap en exécutant la commande suivante :

    $ oc apply -f cc-feature-gate.yaml

Mettre à jour le ConfigMap des pods homologues

  1. 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\""

  2. 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é.
  3. Créez le ConfigMap en exécutant la commande suivante :

    $ oc apply -f peer-pods-cm.yaml

  4. 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

  1. 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'.

  2. 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.

  3. 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.

  4. 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

  5. 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é

  1. Créez une clé privée en exécutant la commande suivante :

    $ openssl genpkey -algorithm ed25519 > privateKey

  2. Créez une clé publique en exécutant la commande suivante :

    $ openssl pkey -in privateKey -pubout -out publicKey

  3. 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

  4. Vérifiez le secret en exécutant la commande suivante :

    $ oc get secret -n trustee-operator-system

Créer le ConfigMap du client approuvé

  1. 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"
          }
        }
    
  2. 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.

  1. 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.

  2. 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.

  1. 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.

  2. 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.

  1. 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/.

  2. 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.

  1. 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.
  2. 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.

  1. 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 ».
  2. 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é.

  1. 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 valeur kbsSecretResources 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écifier NodePort, LoadBalancer, ou ExternalName.
  2. 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é.

  1. Définissez le projet par défaut en exécutant la commande suivante :

    $ oc project trustee-operator-system

  2. 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
    
  3. 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)

  4. 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.

  1. 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.

  2. Créez le pod en exécutant la commande suivante :

    $ oc create -f verification-pod.yaml

  3. 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

  4. 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.