7.7. SELinux 프로필 관리


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

중요

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

7.7.1. SELinux 프로필 생성

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

SelinuxProfile 오브젝트에는 보안 강화 및 가독성을 개선할 수 있는 몇 가지 기능이 있습니다.

  • 현재 네임스페이스 또는 시스템 전체 프로필로 상속할 프로필을 제한합니다. 일반적으로 시스템에 설치된 프로필이 많이 있지만 클러스터 워크로드에서 하위 집합만 사용해야 하므로 상속 가능한 시스템 프로필은 spec.selinuxOptions.allowedSystemProfilesspod 인스턴스에 나열됩니다.
  • 권한, 클래스 및 라벨에 대한 기본 검증을 수행합니다.
  • 정책을 사용하여 프로세스를 설명하는 새 키워드 @self 를 추가합니다. 이를 통해 정책 사용이 이름과 네임스페이스를 기반으로 하므로 워크로드와 네임스페이스 간에 정책을 쉽게 재사용할 수 있습니다.
  • 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 에 배치됩니다. 정책은 /etc/selinux.d/<name>_<namespace>.cil 의 CIL(Common Intermediate Language) 형식으로 저장됩니다.

  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를 생성합니다.

SELinux 프로필의 경우 권한 있는 워크로드를 허용하려면 네임스페이스에 레이블을 지정해야 합니다.

프로세스

  1. 다음 명령을 실행하여 scc.podSecurityLabelSync=false 레이블을 nginx-deploy 네임스페이스에 적용합니다.

    $ oc label ns nginx-deploy security.openshift.io/scc.podSecurityLabelSync=false
  2. 다음 명령을 실행하여 nginx-deploy 네임스페이스에 privileged 레이블을 적용합니다.

    $ 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 유형이 있어야 합니다.

7.7.2.1. SELinux 로그 정책 적용

정책 위반 또는 AVC 거부를 로깅하려면 SElinuxProfile 프로필을 허용 으로 설정합니다.

중요

이 절차에서는 로깅 정책을 정의합니다. 시행 정책을 설정하지 않습니다.

프로세스

  • SElinuxProfilepermissive: true 추가 :

    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 오브젝트를 사용하여 동일한 네임스페이스에 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가 지정된 네임스페이스의 기본 보안 프로필로 바인딩됩니다.

  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.seLinuxOptions.type}'

    출력 예

    profile_nginx-binding.process

7.7.2.3. 컨트롤러 및 SecurityContextConstraints 복제

배포 또는 데몬 세트와 같은 컨트롤러를 복제하기 위한 SELinux 정책을 배포할 때 컨트롤러에서 생성한 Pod 오브젝트는 워크로드를 생성하는 사용자의 ID로 실행되지 않습니다. ServiceAccount 를 선택하지 않으면 사용자 정의 보안 정책 사용을 허용하지 않는 restricted SCC( SecurityContextConstraints )를 사용하여 Pod가 되돌릴 수 있습니다.

프로세스

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

    $ oc new-project nginx-secure
  2. 다음 RoleBinding 오브젝트를 생성하여 nginx-secure 네임스페이스에서 SELinux 정책을 사용할 수 있습니다.

    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 security context restraints가 있는 컨테이너는 로그 기반 기록을 방지합니다. 권한 있는 컨테이너는 SELinux 정책의 영향을 받지 않으며 로그 기반 기록에서는 특수 SELinux 프로필을 사용하여 이벤트를 기록합니다.

프로세스

  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: 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가 다음 두 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는 컨테이너별 프로필을 단일 프로필에 병합할 수 있습니다. 프로필 병합은 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 SelinuxProfile CRD
      # after reconciliation.
      name: test-recording
      namespace: my-namespace
    spec:
      kind: SelinuxProfile
      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 selinuxprofiles -lspo.x-k8s.io/recording-id=test-recording -n my-namespace

    selinuxprofiles의 출력 예

    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 정책 기록은 기록 중인 포드에 특수 SELinux 유형을 삽입하는 Webhook를 사용하여 구현됩니다. SELinux 유형은 pod를 허용 모드로 실행하고 모든 AVC 거부를 audit.log 에 기록합니다. 기본적으로 워크로드는 사용자 지정 SELinux 정책으로 실행할 수 없지만 자동 생성 유형을 사용합니다.

워크로드를 기록하려면 Webhook에서 허용 SELinux 유형을 삽입할 수 있는 SCC를 사용할 수 있는 권한이 있는 서비스 계정을 사용해야 합니다. 권한 있는 SCC에는 seLinuxContext: RunAsAny 가 포함되어 있습니다.

또한 privileged Pod 보안 표준 에서만 사용자 정의 SELinux 정책을 사용할 수 있으므로 클러스터가 Pod Security Admission 을 활성화하는 경우 pod-security.kubernetes.io/enforce: privileged 로 네임스페이스에 라벨을 지정해야 합니다.

추가 리소스

Red Hat logoGithubRedditYoutubeTwitter

자세한 정보

평가판, 구매 및 판매

커뮤니티

Red Hat 문서 정보

Red Hat을 사용하는 고객은 신뢰할 수 있는 콘텐츠가 포함된 제품과 서비스를 통해 혁신하고 목표를 달성할 수 있습니다.

보다 포괄적 수용을 위한 오픈 소스 용어 교체

Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 자세한 내용은 다음을 참조하세요.Red Hat 블로그.

Red Hat 소개

Red Hat은 기업이 핵심 데이터 센터에서 네트워크 에지에 이르기까지 플랫폼과 환경 전반에서 더 쉽게 작업할 수 있도록 강화된 솔루션을 제공합니다.

© 2024 Red Hat, Inc.