7.5. seccomp 프로필 관리

seccomp 프로필을 생성 및 관리하고 워크로드에 바인딩합니다.

중요

Security Profiles Operator는 RHCOS(Red Hat Enterprise Linux CoreOS) 작업자 노드만 지원합니다. RHEL(Red Hat Enterprise Linux) 노드는 지원되지 않습니다.

7.5.1. seccomp 프로필 생성

SeccompProfile 오브젝트를 사용하여 프로필을 생성합니다.

seccompProfile 오브젝트는 컨테이너 내에서 syscall을 제한하여 애플리케이션 액세스를 제한할 수 있습니다.

프로세스

  1. 다음 명령을 실행하여 프로젝트를 생성합니다.

    $ oc new-project my-namespace
  2. 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를 실행합니다. rootless 프로필 스토리지 /var/lib/openshift-security-profiles 에서 kubelet 루트 루트 /var/lib/kubelet/seccomp/operator 내부의 기본 seccomp 루트 경로에 대한 심볼릭 링크가 생성됩니다.

7.5.2. Pod에 seccomp 프로필 적용

생성된 프로필 중 하나를 적용할 Pod를 생성합니다.

프로세스

  1. securityContext 를 정의하는 Pod 오브젝트를 생성합니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pod
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: Localhost
          localhostProfile: operator/my-namespace/profile1.json
      containers:
        - name: test-container
          image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
          securityContext:
            allowPrivilegeEscalation: false
            capabilities:
              drop: [ALL]
  2. 다음 명령을 실행하여 seccompProfile.localhostProfile 속성의 프로필 경로를 확인합니다.

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

    출력 예

    NAME       STATUS     AGE   SECCOMPPROFILE.LOCALHOSTPROFILE
    profile1   Installed  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 오브젝트를 사용하여 동일한 네임스페이스에 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. 다음 명령을 실행하여 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.seccompProfile}'

    출력 예

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

7.5.3. 워크로드의 프로필 기록

Security Profiles Operator는 ProfileRecording 오브젝트를 사용하여 시스템 호출을 기록할 수 있으므로 애플리케이션에 대한 기본 프로필을 더 쉽게 생성할 수 있습니다.

seccomp 프로필 기록에 로그 강화기를 사용하는 경우 로그 강화 기능이 활성화되었는지 확인합니다. 자세한 내용은 추가 리소스 를 참조하십시오.

참고

privileged: true security context restraints가 있는 컨테이너는 로그 기반 기록을 방지합니다. 권한 있는 컨테이너는 seccomp 정책의 영향을 받지 않으며 로그 기반 레코딩은 특수 seccomp 프로필을 사용하여 이벤트를 기록합니다.

프로세스

  1. 다음 명령을 실행하여 프로젝트를 생성합니다.

    $ oc new-project my-namespace
  2. 다음 명령을 실행하여 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: SeccompProfile
      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

    출력 예

    I0523 14:19:08.747313  430694 enricher.go:445] log-enricher "msg"="audit" "container"="redis" "executable"="/usr/local/bin/redis-server" "namespace"="my-namespace" "node"="xiyuan-23-5g2q9-worker-eastus2-6rpgf" "pid"=656802 "pod"="my-pod" "syscallID"=0 "syscallName"="read" "timestamp"="1684851548.745:207179" "type"="seccomp"

검증

  1. Pod를 제거합니다.

    $ oc -n my-namepace delete pod my-pod
  2. Security Profiles Operator가 두 seccomp 프로필을 조정하는지 확인합니다.

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

    seccompprofile 출력 예

    NAME                   STATUS      AGE
    test-recording-nginx   Installed   2m48s
    test-recording-redis   Installed   2m48s

7.5.3.1. 컨테이너당 프로필 인스턴스 병합

기본적으로 각 컨테이너 인스턴스는 별도의 프로필에 저장됩니다. Security Profiles Operator는 컨테이너별 프로필을 단일 프로필에 병합할 수 있습니다. 프로필 병합은 ReplicaSet 또는 Deployment 오브젝트를 사용하여 애플리케이션을 배포할 때 유용합니다.

프로세스

  1. mergeStrategy: containers 변수를 포함하도록 ProfileRecording 오브젝트를 편집합니다.

    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
      namespace: my-namespace
    spec:
      kind: SeccompProfile
      recorder: logs
      mergeStrategy: containers
      podSelector:
        matchLabels:
          app: sp-record
  2. 다음 명령을 실행하여 네임스페이스에 레이블을 지정합니다.

    $ 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 seccompprofiles -lspo.x-k8s.io/recording-id=test-recording -n my-namespace

    seccompprofiles 출력 예

    NAME                          STATUS       AGE
    test-recording-nginx-record   Installed    55s

  7. 컨테이너에서 사용하는 권한을 보려면 다음 명령을 실행합니다.

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

추가 리소스