7.5. seccomp プロファイルの管理

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

重要

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

7.5.1. seccomp プロファイルの作成

プロファイルを作成するには、SeccompProfile オブジェクトを使用します。

SeccompProfile オブジェクトは、コンテナー内のシステムコールを制限して、アプリケーションのアクセスを制限できます。

手順

  • SeccompProfile オブジェクトを作成します。

    apiVersion: security-profiles-operator.x-k8s.io/v1beta1
    kind: SeccompProfile
    metadata:
      namespace: my-namespace
      name: profile1
    spec:
      defaultAction: SCMP_ACT_LOG

seccomp プロファイルは /var/lib/kubelet/seccomp/operator/<namespace>/<name>.json に保存されます。

init コンテナーは Security Profiles Operator のルートディレクトリーを作成し、root グループまたはユーザー ID 権限なしで Operator を実行します。ルートレスプロファイルストレージ /var/lib/openshift-security-profiles から、kubelet root /var/lib/kubelet/seccomp/operator 内のデフォルトの seccomp root パスへのシンボリックリンクが作成されます。

7.5.2. Pod への seccomp プロファイルの適用

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

手順

  1. securityContext を定義する Pod オブジェクトを作成します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pod
    spec:
      securityContext:
        seccompProfile:
          type: Localhost
          localhostProfile: operator/my-namespace/profile1.json
      containers:
        - name: test-container
          image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
  2. 次のコマンドを実行して、seccompProfile.localhostProfile 属性のプロファイルパスを表示します。

    $ oc -n my-namespace get seccompprofile profile1 --output wide

    出力例

    NAME       STATUS   AGE   SECCOMPPROFILE.LOCALHOSTPROFILE
    profile1   Active   14s   operator/my-namespace/profile1.json

  3. 次のコマンドを実行して、localhost プロファイルへのパスを表示します。

    $ oc get sp profile1 --output=jsonpath='{.status.localhostProfile}'

    出力例

    operator/my-namespace/profile1.json

  4. localhostProfile の出力をパッチファイルに適用します。

    spec:
      template:
        spec:
          securityContext:
            seccompProfile:
              type: Localhost
              localhostProfile: operator/my-namespace/profile1.json
  5. 次のコマンドを実行して、プロファイルを Deployment オブジェクトに適用します。

    $ oc -n my-namespace patch deployment myapp --patch-file patch.yaml --type=merge

    出力例

    deployment.apps/myapp patched

検証

  • 次のコマンドを実行して、プロファイルが正しく適用されたことを確認します。

    $ oc -n my-namespace get deployment myapp --output=jsonpath='{.spec.template.spec.securityContext}' | jq .

    出力例

    {
      "seccompProfile": {
        "localhostProfile": "operator/my-namespace/profile1.json",
        "type": "localhost"
      }
    }

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

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

手順

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

    apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
    kind: ProfileBinding
    metadata:
      namespace: my-namespace
      name: nginx-binding
    spec:
      profileRef:
        kind: SeccompProfile 1
        name: profile 2
      image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
    1
    kind: 変数は、プロファイルの名前を参照します。
    2
    name: 変数は、プロファイルの名前を参照します。
  2. 次のコマンドを実行して、namespace に enable-binding=true のラベルを付けます。

    $ oc label ns my-namespace spo.x-k8s.io/enable-binding=true
  3. Pod を削除して再作成し、ProfileBinding オブジェクトを使用します。

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

検証

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

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

    出力例

    {"localhostProfile":"operator/my-namespace/profile.json","type":"Localhost"}

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

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

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

注記

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

手順

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

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

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

    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. 次のコマンドを入力して、Pod が Running 状態であることを確認します。

    $ oc -n openshift-security-profiles get pods

    出力例

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

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

    $ 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"="seccomp"

検証

  1. Pod を削除します。

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

    $ oc get seccompprofiles -n my-namespace

    出力例

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

7.5.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 SeccompProfile CRD
      # after reconciliation.
      name: test-recording
    spec:
      kind: SeccompProfile
      recorder: logs
      mergeStrategy: containers
      podSelector:
        matchLabels:
          app: sp-record
  2. ワークロードを作成します。

    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. 個々のプロファイルを記録するには、次のコマンドを実行してデプロイメントを削除します。

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

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

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

    出力例

    NAME                          USAGE                                         STATE
    test-recording-nginx-record   test-recording-nginx-record_mytest1.process   Installed

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

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

関連情報