7.6. Gestion des profils SELinux


Créer et gérer des profils SELinux et les associer à des charges de travail.

7.6.1. Création de profils SELinux

Utilisez l'objet SelinuxProfile pour créer des profils.

L'objet SelinuxProfile présente plusieurs caractéristiques qui permettent de renforcer la sécurité et d'améliorer la lisibilité :

  • Limite les profils dont il faut hériter à l'espace de noms actuel ou à un profil général. Étant donné que de nombreux profils sont généralement installés sur le système, mais que seul un sous-ensemble doit être utilisé par les charges de travail en cluster, les profils système héritables sont répertoriés dans l'instance spod à l'adresse spec.selinuxOptions.allowedSystemProfiles.
  • Effectue une validation de base des autorisations, des classes et des étiquettes.
  • Ajoute un nouveau mot-clé @self qui décrit le processus utilisant la politique. Cela permet de réutiliser facilement une politique entre les charges de travail et les espaces de noms, car l'utilisation de la politique est basée sur le nom et l'espace de noms.
  • Ajoute des fonctionnalités pour améliorer le renforcement de la sécurité et la lisibilité par rapport à l'écriture d'un profil directement dans le langage SELinux CIL.

Procédure

  1. Créez une politique qui peut être utilisée avec une charge de travail non privilégiée en créant l'objet SelinuxProfile suivant :

    apiVersion: security-profiles-operator.x-k8s.io/v1alpha2
    kind: SelinuxProfile
    metadata:
      name: nginx-secure
      namespace: nginx-deploy
    spec:
      allow:
        '@self':
          tcp_socket:
          - listen
        http_cache_port_t:
          tcp_socket:
          - name_bind
        node_t:
          tcp_socket:
          - node_bind
      inherit:
      - kind: System
        name: container
  2. Attendez que selinuxd installe la politique en exécutant la commande suivante :

    $ oc wait --for=condition=ready -n nginx-deploy selinuxprofile nginx-secure

    Exemple de sortie

    selinuxprofile.security-profiles-operator.x-k8s.io/nginx-secure condition met

    Les politiques sont placées sur un site emptyDir dans le conteneur appartenant à l'opérateur de profils de sécurité. Les politiques sont sauvegardées au format Common Intermediate Language (CIL) dans /etc/selinux.d/<name>_<namespace>.cil.

  3. Accédez au pod en exécutant la commande suivante :

    $ oc -n openshift-security-profiles rsh -c selinuxd ds/spod

Vérification

  1. Affichez le contenu du fichier à l'aide de cat en exécutant la commande suivante :

    $ cat /etc/selinux.d/nginx-secure_nginx-deploy.cil

    Exemple de sortie

    (block nginx-secure_nginx-deploy
    (blockinherit container)
    (allow process nginx-secure_nginx-deploy.process ( tcp_socket ( listen )))
    (allow process http_cache_port_t ( tcp_socket ( name_bind )))
    (allow process node_t ( tcp_socket ( node_bind )))
    )

  2. Vérifiez qu'une politique a été installée en exécutant la commande suivante :

    $ semodule -l | grep nginx-secure

    Exemple de sortie

    nginx-secure_nginx-deploy

7.6.2. Appliquer des profils SELinux à un pod

Créer un pod pour appliquer l'un des profils créés.

Pour les profils SELinux, l'espace de noms doit être étiqueté pour autoriser les charges de travail privilégiées.

Procédure

  1. Appliquez l'étiquette scc.podSecurityLabelSync=false à l'espace de noms nginx-deploy en exécutant la commande suivante :

    $ oc label ns nginx-deploy security.openshift.io/scc.podSecurityLabelSync=false
  2. Appliquez l'étiquette privileged à l'espace de noms nginx-deploy en exécutant la commande suivante :

    $ oc label ns nginx-deploy --overwrite=true pod-security.kubernetes.io/enforce=privileged
  3. Obtenez la chaîne d'utilisation du profil SELinux en exécutant la commande suivante :

    $ oc get selinuxprofile.security-profiles-operator.x-k8s.io/nginx-secure -n nginx-deploy -ojsonpath='{.status.usage}'

    Exemple de sortie

    nginx-secure_nginx-deploy.process%

  4. Appliquer la chaîne de sortie dans le manifeste de charge de travail dans l'attribut .spec.containers[].securityContext.seLinuxOptions:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-secure
      namespace: nginx-deploy
    spec:
      containers:
        - image: nginxinc/nginx-unprivileged:1.21
          name: nginx
          securityContext:
            seLinuxOptions:
              # NOTE: This uses an appropriate SELinux type
              type: nginx-secure_nginx-deploy.process
    Important

    Le site SELinux type doit exister avant la création de la charge de travail.

7.6.2.1. Application des politiques de journalisation SELinux

Pour consigner les violations de la politique ou les refus d'AVC, définissez le profil SElinuxProfile sur permissive.

Important

Cette procédure définit les politiques de journalisation. Elle ne définit pas de politiques de mise en œuvre.

Procédure

  • Ajouter permissive: true à SElinuxProfile:

    apiVersion: security-profiles-operator.x-k8s.io/v1alpha2
    kind: SelinuxProfile
    metadata:
      name: nginx-secure
      namespace: nginx-deploy
    spec:
      permissive: true

7.6.2.2. Lier les charges de travail aux profils avec ProfileBindings

Vous pouvez utiliser la ressource ProfileBinding pour lier un profil de sécurité à la ressource SecurityContext d'un conteneur.

Procédure

  1. Pour lier un module qui utilise une image quay.io/security-profiles-operator/test-nginx-unprivileged:1.21 au profil de l'exemple SelinuxProfile, créez un objet ProfileBinding dans le même espace de noms que le module et les objets SelinuxProfile:

    apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
    kind: ProfileBinding
    metadata:
      namespace: my-namespace
      name: nginx-binding
    spec:
      profileRef:
        kind: SelinuxProfile 1
        name: profile 2
      image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
    1
    La variable kind: fait référence au nom du profil.
    2
    La variable name: fait référence au nom du profil.
  2. Etiqueter l'espace de noms avec enable-binding=true en exécutant la commande suivante :

    $ oc label ns my-namespace spo.x-k8s.io/enable-binding=true
  3. Supprimer et recréer le pod pour utiliser l'objet ProfileBinding:

    $ oc delete pods test-pod && oc create -f pod01.yaml

Vérification

  • Confirmez que le pod hérite de ProfileBinding en exécutant la commande suivante :

    $ oc get pod test-pod -o jsonpath='{.spec.containers[*].securityContext.seLinuxOptions.type}'

    Exemple de sortie

    profile_nginx-binding.process

7.6.2.3. Réplication des contrôleurs et des SecurityContextConstraints

Lors du déploiement de politiques SELinux pour les contrôleurs de réplication, tels que les déploiements ou les ensembles de démons, notez que les objets Pod créés par les contrôleurs ne sont pas exécutés avec l'identité de l'utilisateur qui crée la charge de travail. À moins qu'une adresse ServiceAccount ne soit sélectionnée, les pods risquent de revenir à l'utilisation d'une adresse SecurityContextConstraints restreinte (SCC) qui ne permet pas l'utilisation de politiques de sécurité personnalisées.

Procédure

  1. Créez l'objet RoleBinding suivant pour permettre l'utilisation des politiques SELinux dans l'espace de noms nginx-secure:

    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: spo-use-seccomp-scc
      namespace: nginx-secure
    subjects:
    - kind: ServiceAccount
      name: spo-deploy-test
    roleRef:
      kind: Role
      name: spo-use-seccomp-scc
      apiGroup: rbac.authorization.k8s.io
  2. Créer l'objet Role:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      creationTimestamp: null
      name: spo-use-seccomp-scc
      namespace: nginx-secure
    rules:
    - apiGroups:
      - security.openshift.io
      resources:
      - securitycontextconstraints
      resourceNames:
      - privileged
      verbs:
      - use
  3. Créer l'objet ServiceAccount:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      creationTimestamp: null
      name: spo-deploy-test
      namespace: nginx-secure
  4. Créer l'objet Deployment:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: selinux-test
      namespace: nginx-secure
      metadata:
        labels:
          app: selinux-test
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: selinux-test
      template:
        metadata:
          labels:
            app: selinux-test
        spec:
          serviceAccountName: spo-deploy-test
          securityContext:
            seLinuxOptions:
              type: nginx-secure_nginx-secure.process 1
          containers:
          - name: nginx-unpriv
            image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
            ports:
            - containerPort: 8080
    1
    Le site .seLinuxOptions.type doit exister avant la création du déploiement.
    Note

    Le type SELinux n'est pas spécifié dans la charge de travail et est géré par le SCC. Lorsque les pods sont créés par le déploiement et le site ReplicaSet, ils s'exécutent avec le profil approprié.

Assurez-vous que votre CCN n'est utilisable que par le bon compte de service. Pour plus d'informations, consultez le site Additional resources.

7.6.3. Enregistrement de profils à partir de charges de travail

L'opérateur de profils de sécurité peut enregistrer les appels système avec les objets ProfileRecording, ce qui facilite la création de profils de référence pour les applications.

Lors de l'utilisation de l'enrichisseur de journaux pour l'enregistrement des profils SELinux, vérifiez que la fonction d'enrichissement de journaux est activée. Voir Additional resources pour plus d'informations.

Note

Un conteneur avec privileged: true security context restraints empêche l'enregistrement basé sur le journal. Les conteneurs privilégiés ne sont pas soumis aux politiques SELinux, et l'enregistrement basé sur les journaux utilise un profil SELinux spécial pour enregistrer les événements.

Procédure

  1. Etiqueter l'espace de noms avec enable-recording=true en exécutant la commande suivante :

    $ oc label ns my-namespace spo.x-k8s.io/enable-recording=true
  2. Créer un objet ProfileRecording contenant une variable recorder: logs:

    apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
    kind: ProfileRecording
    metadata:
      name: test-recording
    spec:
      kind: SelinuxProfile
      recorder: logs
      podSelector:
        matchLabels:
          app: my-app
  3. Créer une charge de travail à enregistrer :

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
      labels:
        app: my-app
    spec:
      containers:
        - name: nginx
          image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
          ports:
            - containerPort: 8080
        - name: redis
          image: quay.io/security-profiles-operator/redis:6.2.1
  4. Confirmez que le pod est dans un état Running en entrant la commande suivante :

    $ oc -n openshift-security-profiles get pods

    Exemple de sortie

    NAME     READY   STATUS    RESTARTS   AGE
    my-pod   2/2     Running   0          18s

  5. Confirmez que l'enrichisseur indique qu'il reçoit les journaux d'audit pour ces conteneurs :

    $ oc -n openshift-security-profiles logs --since=1m --selector name=spod -c log-enricher

    Exemple de sortie

    …
    I0705 12:08:18.729660 1843190 enricher.go:136] log-enricher "msg"="audit"  "container"="redis" "executable"="/usr/local/bin/redis-server" "namespace"="default" "node"="127.0.0.1" "pid"=1847839 "pod"="my-pod" "syscallID"=232 "syscallName"="epoll_wait" "timestamp"="1625486870.273:187492" "type"="{type}"

Vérification

  1. Retirer la gousse :

    $ oc -n openshift-security-profiles delete pod my-pod
  2. Confirmez que l'opérateur de profils de sécurité réconcilie les deux profils SELinux :

    $ oc -n openshift-security-profiles get sp

    Exemple de sortie

    NAME                   STATUS      AGE
    test-recording-nginx   Installed   15s
    test-recording-redis   Installed   15s

7.6.3.1. Fusionner des instances de profil par conteneur

Par défaut, chaque instance de conteneur est enregistrée dans un profil distinct. L'opérateur de profils de sécurité peut fusionner les profils par conteneur en un seul profil. La fusion des profils est utile lors du déploiement d'applications utilisant les objets ReplicaSet ou Deployment.

Procédure

  1. Modifier un objet ProfileRecording pour y inclure une variable mergeStrategy: containers:

    apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
    kind: ProfileRecording
    metadata:
      # The name of the Recording is the same as the resulting SelinuxProfile CRD
      # after reconciliation.
      name: test-recording
    spec:
      kind: SelinuxProfile
      recorder: logs
      mergeStrategy: containers
      podSelector:
        matchLabels:
          app: sp-record
  2. Créer la charge de travail :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deploy
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: sp-record
      template:
        metadata:
          labels:
            app: sp-record
        spec:
          serviceAccountName: spo-record-sa
          containers:
          - name: nginx-record
            image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
            ports:
            - containerPort: 8080
  3. Pour enregistrer les profils individuels, supprimez le déploiement en exécutant la commande suivante :

    $ oc delete deployment nginx-deploy
  4. Pour fusionner les profils, supprimez l'enregistrement du profil en exécutant la commande suivante :

    $ oc delete profilerecording test-recording
  5. Pour lancer l'opération de fusion et générer le profil de résultats, exécutez la commande suivante :

    $ oc get sp -lspo.x-k8s.io/recording-id=test-recording

    Exemple de sortie

    NAME                          STATUS      AGE
    test-recording-nginx-record   Installed   17m

  6. Pour afficher les appels de service utilisés par l'un des conteneurs, exécutez la commande suivante :

    $ oc get sp test-recording-nginx-record -o yaml

7.6.3.2. À propos de seLinuxContext : RunAsAny

L'enregistrement des politiques SELinux est mis en œuvre avec un webhook qui injecte un type SELinux spécial dans les pods enregistrés. Le type SELinux fait tourner le pod en mode permissive, en enregistrant tous les refus d'AVC dans audit.log. Par défaut, une charge de travail n'est pas autorisée à s'exécuter avec une politique SELinux personnalisée, mais utilise un type généré automatiquement.

Pour enregistrer une charge de travail, celle-ci doit utiliser un compte de service disposant des autorisations nécessaires pour utiliser un SCC permettant au webhook d'injecter le type SELinux permissif. Le SCC privileged contient seLinuxContext: RunAsAny.

En outre, l'espace de noms doit être étiqueté avec pod-security.kubernetes.io/enforce: privileged si votre cluster active l'admission de sécurité des pods, car seul le standard de sécurité des pods privileged autorise l'utilisation d'une politique SELinux personnalisée.

Ressources supplémentaires

Red Hat logoGithubRedditYoutubeTwitter

Apprendre

Essayez, achetez et vendez

Communautés

À propos de la documentation Red Hat

Nous aidons les utilisateurs de Red Hat à innover et à atteindre leurs objectifs grâce à nos produits et services avec un contenu auquel ils peuvent faire confiance.

Rendre l’open source plus inclusif

Red Hat s'engage à remplacer le langage problématique dans notre code, notre documentation et nos propriétés Web. Pour plus de détails, consultez leBlog Red Hat.

À propos de Red Hat

Nous proposons des solutions renforcées qui facilitent le travail des entreprises sur plusieurs plates-formes et environnements, du centre de données central à la périphérie du réseau.

© 2024 Red Hat, Inc.