7.7. SELinux プロファイルの管理


SELinux プロファイルを作成および管理し、それらをワークロードにバインドします。

重要

Security Profiles Operator は、Red Hat Enterprise Linux CoreOS (RHCOS) ワーカーノードのみをサポートします。Red Hat Enterprise Linux (RHEL) ノードはサポートされていません。

7.7.1. SELinux プロファイルの作成

SelinuxProfile オブジェクトを使用してプロファイルを作成します。

SelinuxProfile オブジェクトには、セキュリティー強化と読みやすさを向上させるいくつかの機能があります。

  • 継承するプロファイルを現在の namespace またはシステム全体のプロファイルに制限します。通常、システムには多くのプロファイルがインストールされていますが、クラスターワークロードではサブセットのみを使用する必要があるため、継承可能なシステムプロファイルは、spec.selinuxOptions.allowedSystemProfilesspod インスタンスにリストされています。
  • 権限、クラス、およびラベルの基本的な検証を実行します。
  • ポリシーを使用するプロセスを説明する新しいキーワード @self を追加します。これにより、ポリシーの使用は名前と namespace に基づいているため、ワークロードと namespace の間でポリシーを簡単に再利用できます。
  • SELinux CIL 言語で直接プロファイルを作成する場合と比較して、セキュリティーを強化し、読みやすくするための機能を追加します。

手順

  1. 次のコマンドを実行してプロジェクトを作成します。

    $ oc new-project nginx-deploy
  2. 次の SelinuxProfile オブジェクトを作成して、特権のないワークロードで使用できるポリシーを作成します。

    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
  3. 次のコマンドを実行して、selinuxd がポリシーをインストールするのを待ちます。

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

    出力例

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

    ポリシーは、Security Profiles Operator が所有するコンテナー内の emptyDir に配置されます。ポリシーは Common Intermediate Language (CIL) 形式で /etc/selinux.d/<name>_<namespace>.cil に保存されます。

  4. 以下のコマンドを実行して Pod を作成します。

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

検証

  1. 次のコマンドを実行して、cat でファイルの内容を表示します。

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

    出力例

    (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. 次のコマンドを実行して、ポリシーがインストールされていることを確認します。

    $ semodule -l | grep nginx-secure

    出力例

    nginx-secure_nginx-deploy

7.7.2. Pod への SELinux プロファイルの適用

Pod を作成して、作成したプロファイルの 1 つを適用します。

SELinux プロファイルの場合、namespace にラベルを付けて、特権 ワークロードを許可する必要があります。

手順

  1. 次のコマンドを実行して、scc.podSecurityLabelSync=false ラベルを nginx-deploy namespace に適用します。

    $ oc label ns nginx-deploy security.openshift.io/scc.podSecurityLabelSync=false
  2. 次のコマンドを実行して、privileged ラベルを nginx-deploy namespace に適用します。

    $ oc label ns nginx-deploy --overwrite=true pod-security.kubernetes.io/enforce=privileged
  3. 次のコマンドを実行して、SELinux プロファイルの使用文字列を取得します。

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

    出力例

    nginx-secure_nginx-deploy.process

  4. ワークロードマニフェストの出力文字列を .spec.containers[].securityContext.seLinuxOptions 属性に適用します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-secure
      namespace: nginx-deploy
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - image: nginxinc/nginx-unprivileged:1.21
          name: nginx
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
            seLinuxOptions:
              # NOTE: This uses an appropriate SELinux type
              type: nginx-secure_nginx-deploy.process
    重要

    ワークロードを作成する前に、SELinux type が存在している必要があります。

7.7.2.1. SELinux ログポリシーの適用

ポリシー違反または AVC 拒否をログに記録するには、SElinuxProfile プロファイルを permissive に設定します。

重要

この手順では、ロギングポリシーを定義します。施行ポリシーを設定しません。

手順

  • permissive: trueSElinuxProfile に追加します。

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

7.7.2.2. ProfileBindings を使用してワークロードをプロファイルにバインドする

ProfileBinding リソースを使用して、セキュリティープロファイルをコンテナーの SecurityContext にバインドできます。

手順

  1. quay.io/security-profiles-operator/test-nginx-unprivileged:1.21 イメージを使用する Pod をサンプルの SelinuxProfile プロファイルにバインドするには、Pod と SelinuxProfile オブジェクトと同じ namespace に ProfileBinding オブジェクトを作成します。

    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 3
    1
    kind: 変数はプロファイルの種類を参照します。
    2
    name: 変数は、プロファイルの名前を参照します。
    3
    イメージ属性にワイルドカードを使用する (image: "*") と、デフォルトのセキュリティープロファイルを有効にすることができます。
    重要

    image: "*" ワイルドカード属性を使用すると、すべての新しい Pod が、指定された namespace 内のデフォルトのセキュリティープロファイルにバインドされます。

  2. 次のコマンドを実行して、namespace に enable-binding=true のラベルを付けます。

    $ oc label ns my-namespace spo.x-k8s.io/enable-binding=true
  3. test-pod.yaml という名前の Pod を定義します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pod
    spec:
      containers:
      - name: test-container
        image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
  4. Pod を作成します。

    $ oc create -f test-pod.yaml
    注記

    Pod がすでに存在する場合、Pod を再作成しなければバインディングは適切に機能しません。

検証

  • 次のコマンドを実行して、Pod が ProfileBinding を継承していることを確認します。

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

    出力例

    profile_nginx-binding.process

7.7.2.3. コントローラーと SecurityContextConstraints の複製

デプロイメントやデーモンセットなど、コントローラーをレプリケートするための SELinux ポリシーをデプロイする場合、コントローラーによって生成された Pod オブジェクトは、ワークロードを作成するユーザーの ID で実行されないことに注意してください。ServiceAccount が選択されていない場合、Pod は、カスタムセキュリティーポリシーの使用を許可しない、制限された SecurityContextConstraints (SCC) の使用に戻る可能性があります。

手順

  1. 次のコマンドを実行してプロジェクトを作成します。

    $ oc new-project nginx-secure
  2. 次の RoleBinding オブジェクトを作成して、SELinux ポリシーを nginx-secure namespace で使用できるようにします。

    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: spo-nginx
      namespace: nginx-secure
    subjects:
    - kind: ServiceAccount
      name: spo-deploy-test
    roleRef:
      kind: Role
      name: spo-nginx
      apiGroup: rbac.authorization.k8s.io
  3. Role オブジェクトを作成します。

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      creationTimestamp: null
      name: spo-nginx
      namespace: nginx-secure
    rules:
    - apiGroups:
      - security.openshift.io
      resources:
      - securitycontextconstraints
      resourceNames:
      - privileged
      verbs:
      - use
  4. ServiceAccount オブジェクトを作成します。

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      creationTimestamp: null
      name: spo-deploy-test
      namespace: nginx-secure
  5. 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
    デプロイメントが作成される前に、.seLinuxOptions.type が存在している必要があります。
    注記

    SELinux タイプはワークロードで指定されておらず、SCC によって処理されます。デプロイと ReplicaSet によって Pod が作成されると、Pod は適切なプロファイルで実行されます。

SCC が、正しいサービスアカウントのみで使用できることを確認してください。詳細は、その他のリソース を参照してください。

7.7.3. ワークロードからのプロファイルの記録

Security Profiles Operator は、ProfileRecording オブジェクトを使用してシステムコールを記録できるため、アプリケーションのベースラインプロファイルを簡単に作成できます。

ログエンリッチャーを使用して SELinux プロファイルを記録する場合は、ログエンリッチャー機能が有効になっていることを確認します。詳細は、関連情報 を参照してください。

注記

privileged: true のセキュリティーコンテキスト制限を持つコンテナーにより、ログベースの記録が防止されます。特権コンテナーは SELinux ポリシーの対象ではなく、ログベースの記録では特別な SELinux プロファイルを使用してイベントを記録します。

手順

  1. 次のコマンドを実行してプロジェクトを作成します。

    $ oc new-project my-namespace
  2. 次のコマンドを実行して、namespace に enable-recording=true のラベルを付けます。

    $ oc label ns my-namespace spo.x-k8s.io/enable-recording=true
  3. recorder: logs 変数を含む ProfileRecording オブジェクトを作成します。

    apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
    kind: ProfileRecording
    metadata:
      namespace: my-namespace
      name: test-recording
    spec:
      kind: SelinuxProfile
      recorder: logs
      podSelector:
        matchLabels:
          app: my-app
  4. 記録するワークロードを作成します。

    apiVersion: v1
    kind: Pod
    metadata:
      namespace: my-namespace
      name: my-pod
      labels:
        app: my-app
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: nginx
          image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
          ports:
            - containerPort: 8080
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
        - name: redis
          image: quay.io/security-profiles-operator/redis:6.2.1
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
  5. 次のコマンドを入力して、Pod が Running 状態であることを確認します。

    $ oc -n my-namespace get pods

    出力例

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

  6. エンリッチャーがそれらのコンテナーの監査ログを受信することを示していることを確認します。

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

    出力例

    I0517 13:55:36.383187  348295 enricher.go:376] log-enricher "msg"="audit" "container"="redis" "namespace"="my-namespace" "node"="ip-10-0-189-53.us-east-2.compute.internal" "perm"="name_bind" "pod"="my-pod" "profile"="test-recording_redis_6kmrb_1684331729" "scontext"="system_u:system_r:selinuxrecording.process:s0:c4,c27" "tclass"="tcp_socket" "tcontext"="system_u:object_r:redis_port_t:s0" "timestamp"="1684331735.105:273965" "type"="selinux"

検証

  1. Pod を削除します。

    $ oc -n my-namepace delete pod my-pod
  2. Security Profiles Operator が 2 つの SELinux プロファイルを調整することを確認します。

    $ oc get selinuxprofiles -lspo.x-k8s.io/recording-id=test-recording -n my-namespace

    selinuxprofile の出力例

    NAME                   USAGE                                       STATE
    test-recording-nginx   test-recording-nginx_my-namespace.process   Installed
    test-recording-redis   test-recording-redis_my-namespace.process   Installed

7.7.3.1. コンテナーごとのプロファイルインスタンスのマージ

デフォルトでは、各コンテナーインスタンスは個別のプロファイルに記録されます。Security Profiles Operator は、コンテナーごとのプロファイルを 1 つのプロファイルにマージできます。プロファイルのマージは、ReplicaSet または Deployment オブジェクトを使用してアプリケーションをデプロイメントするときに役立ちます。

手順

  1. ProfileRecording オブジェクトを編集して、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
      namespace: my-namespace
    spec:
      kind: SelinuxProfile
      recorder: logs
      mergeStrategy: containers
      podSelector:
        matchLabels:
          app: sp-record
  2. 以下のコマンドを実行して namespace にラベルを付けます。

    $ oc label ns my-namespace security.openshift.io/scc.podSecurityLabelSync=false pod-security.kubernetes.io/enforce=privileged pod-security.kubernetes.io/audit=privileged pod-security.kubernetes.io/warn=privileged --overwrite=true
  3. 次の YAML を使用してワークロードを作成します。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deploy
      namespace: my-namespace
    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
  4. 個々のプロファイルを記録するには、次のコマンドを実行してデプロイメントを削除します。

    $ oc delete deployment nginx-deploy -n my-namespace
  5. プロファイルをマージするには、次のコマンドを実行してプロファイルの記録を削除します。

    $ oc delete profilerecording test-recording -n my-namespace
  6. マージ操作を開始して結果プロファイルを生成するには、次のコマンドを実行します。

    $ oc get selinuxprofiles -lspo.x-k8s.io/recording-id=test-recording -n my-namespace

    selinuxprofile の出力例

    NAME                          USAGE                                              STATE
    test-recording-nginx-record   test-recording-nginx-record_my-namespace.process   Installed

  7. いずれかのコンテナーで使用されている権限を表示するには、次のコマンドを実行します。

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

7.7.3.2. About seLinuxContext: RunAsAny

SELinux ポリシーの記録は、記録される Pod に特別な SELinux タイプを挿入する Webhook で実装されます。SELinux タイプは、Pod を permissive モードで実行し、すべての AVC 拒否を audit.log に記録します。デフォルトでは、カスタム SELinux ポリシーを使用したワークロードの実行は許可されていませんが、自動生成されたタイプが使用されます。

ワークロードを記録するには、Webhook が許容された SELinux タイプを挿入できる SCC を使用する権限を持つサービスアカウントを使用する必要があります。privileged SCC には、seLinuxContext: RunAsAny が含まれています。

さらに、カスタム SELinux ポリシーの使用を許可するのは privilegedPod Security Standard のみであるため、クラスターで Pod Security Admission が有効になっている場合は、namespace に pod-security.kubernetes.io/enforce: privileged 付きのラベルを付ける必要があります。

関連情報

Red Hat logoGithubRedditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

© 2024 Red Hat, Inc.