Pod와 컨테이너를 위한 Linux 커널 보안 제약
Pod와 컨테이너를 위한 Linux 커널 보안 제약 (Linux kernel security constraints for Pods and containers)
Pod와 컨테이너를 강화(harden)하는 데 사용할 수 있는 Linux 커널 보안 모듈과 제약의 개요를 살펴볼게요.
이 페이지에서는 Linux 커널에 내장된 보안 기능 중 쿠버네티스 워크로드에서 쓸 수 있는 것들을 설명해요. 이 기능들을 Pod와 컨테이너에 적용하는 방법을 배우려면 Pod 또는 컨테이너에 대한 SecurityContext 구성하기를 참고하세요. Linux와 쿠버네티스 워크로드의 기본기를 이미 알고 있다고 가정해요.
출처: Kubernetes 공식 문서 — Linux kernel security constraints for Pods and containers
루트 권한 없이 워크로드 실행하기
쿠버네티스에 워크로드를 배포할 때는 Pod 스펙을 사용해 그 워크로드가 노드에서 루트 사용자로 실행되지 않도록 제한하세요. Pod securityContext로 Pod 안 프로세스의 특정 Linux 사용자와 그룹을 정의하고, 컨테이너가 루트 사용자로 실행되지 않도록 명시적으로 제한할 수 있어요. 이런 값을 Pod 매니페스트에 설정하면 컨테이너 이미지의 비슷한 값보다 우선해요. 특히 소유하지 않은 이미지를 실행할 때 유용해요.
주의:
워크로드에 할당한 사용자나 그룹이 애플리케이션이 제대로 동작하는 데 필요한 권한을 갖고 있는지 확인하세요. 올바른 권한이 없는 사용자나 그룹으로 바꾸면 파일 접근 문제나 작업 실패로 이어질 수 있어요.
이 페이지의 커널 보안 기능을 구성하면 클러스터의 프로세스가 취할 수 있는 동작을 세밀하게 제어할 수 있지만, 이 구성을 대규모로 관리하는 건 어려울 수 있어요. 컨테이너를 비루트로 실행하거나, 루트 권한이 필요하면 사용자 네임스페이스 안에서 실행하면, 구성한 커널 보안 기능을 강제로 적용할 필요가 생길 가능성을 줄이는 데 도움이 돼요.
Linux 커널의 보안 기능
쿠버네티스를 사용하면 Linux 커널 기능을 구성하고 사용해서 컨테이너 워크로드의 격리를 개선하고 강화할 수 있어요. 흔한 기능은 다음과 같아요.
- 시큐어 컴퓨팅 모드(seccomp): 프로세스가 호출할 수 있는 시스템 호출을 필터링해요.
- AppArmor: 개별 프로그램의 접근 권한을 제한해요.
- SELinux(Security Enhanced Linux): 객체에 보안 라벨을 할당해 더 관리하기 쉬운 보안 정책을 강제해요.
이 기능 중 하나의 설정을 구성하려면, 노드에 선택한 운영체제가 커널에서 그 기능을 활성화해야 해요. 예를 들어 Ubuntu 7.10 이상은 기본적으로 AppArmor를 활성화해요. OS가 특정 기능을 활성화하는지 알아보려면 OS 문서를 확인하세요.
Pod 스펙의 securityContext 필드를 사용해 그 프로세스들에 적용할 제약을 정의해요. securityContext 필드는 특정 Linux capabilities나 UID·GID를 사용한 파일 접근 권한 같은 다른 보안 설정도 지원해요. 더 자세한 내용은 Pod 또는 컨테이너에 대한 SecurityContext 구성하기를 참고하세요.
seccomp
일부 워크로드는 노드의 호스트 머신에서 루트 사용자로 특정 작업을 수행할 권한이 필요할 수 있어요. Linux는 capabilities를 사용해 사용 가능한 권한을 범주로 나눠서, 프로세스가 모든 권한을 부여받지 않고도 특정 작업을 수행하는 데 필요한 권한만 얻을 수 있게 해줘요. 각 capability에는 프로세스가 호출할 수 있는 시스템 호출(syscall) 집합이 있어요. seccomp를 사용하면 이런 개별 syscall을 제한할 수 있어요. 프로세스의 권한을 샌드박싱해서, 사용자 공간에서 커널로 호출할 수 있는 호출을 제한하는 데 쓸 수 있어요.
쿠버네티스에서는 각 노드의 컨테이너 런타임을 사용해 컨테이너를 실행해요. 런타임 예시로는 CRI-O, Docker, containerd가 있어요. 각 런타임은 기본적으로 Linux capabilities의 일부만 허용해요. seccomp 프로필을 사용해 허용되는 syscall을 개별적으로 더 제한할 수 있어요. 컨테이너 런타임은 보통 기본 seccomp 프로필을 포함해요. 쿠버네티스는 노드에 로드된 seccomp 프로필을 Pod와 컨테이너에 자동으로 적용하게 해줘요.
참고:
쿠버네티스에는 Pod와 컨테이너를 위한
allowPrivilegeEscalation설정도 있어요.false로 설정하면 프로세스가 새 capabilities를 얻는 것을 막고, 권한 없는 사용자가 적용된 seccomp 프로필을 더 관대한 프로필로 바꾸는 것을 제한해요.
쿠버네티스에서 seccomp를 구현하는 방법을 배우려면 seccomp로 컨테이너의 Syscall 제한하기나 Seccomp 노드 참조를 참고하세요.
seccomp에 대해 더 알아보려면 Linux 커널 문서의 Seccomp BPF를 보세요.
seccomp 고려사항
seccomp는 저수준 보안 구성이라, Linux syscall에 대한 세밀한 제어가 필요한 경우에만 직접 구성해야 해요. 특히 대규모로 seccomp를 사용하면 다음과 같은 위험이 있어요.
- 애플리케이션 업데이트 중에 구성이 깨질 수 있어요.
- 공격자가 여전히 허용된 syscall을 사용해 취약점을 악용할 수 있어요.
- 개별 애플리케이션의 프로필 관리는 대규모에서 어려워져요.
권장사항: 컨테이너 런타임에 내장된 기본 seccomp 프로필을 사용하세요. 더 격리된 환경이 필요하다면 gVisor 같은 샌드박스 사용을 고려해보세요. 샌드박스는 커스텀 seccomp 프로필의 위험을 해결하지만, 노드에 더 많은 컴퓨팅 리소스가 필요하고 GPU나 다른 특수 하드웨어와의 호환성 문제가 있을 수 있어요.
AppArmor와 SELinux: 정책 기반 강제 접근 제어
AppArmor와 SELinux 같은 Linux 정책 기반 강제 접근 제어(MAC) 메커니즘을 사용해 쿠버네티스 워크로드를 강화할 수 있어요.
AppArmor
AppArmor는 표준 Linux 사용자·그룹 기반 권한을 보완해서 프로그램을 제한된 리소스 집합에 한정하는 Linux 커널 보안 모듈이에요. AppArmor는 공격 표면을 줄이고 더 깊이 있는 방어를 제공하기 위해 어떤 애플리케이션이든 구성할 수 있어요. 특정 프로그램이나 컨테이너가 필요로 하는 접근(Linux capabilities, 네트워크 접근, 파일 권한 같은 것)을 허용하도록 조정된 프로필을 통해 구성돼요. 각 프로필은 허용되지 않은 리소스에 대한 접근을 차단하는 enforcing 모드나 위반만 보고하는 complain 모드 중 하나로 실행될 수 있어요.
AppArmor는 컨테이너가 허용된 작업을 제한하고 시스템 로그를 통한 더 나은 감사를 제공해서 더 안전한 배포를 운영하는 데 도움이 돼요. 사용 중인 컨테이너 런타임이 기본 AppArmor 프로필을 제공할 수도 있고, 커스텀 프로필을 사용할 수도 있어요.
쿠버네티스에서 AppArmor를 사용하는 방법을 배우려면 AppArmor로 컨테이너의 리소스 접근 제한하기를 참고하세요.
SELinux
SELinux는 프로세스 같은 특정 주체(subject) 가 시스템의 파일에 접근하는 것을 제한할 수 있게 해주는 Linux 커널 보안 모듈이에요. 특정 SELinux 라벨이 있는 주체에 적용되는 보안 정책을 정의해요. SELinux 라벨이 있는 프로세스가 파일에 접근하려고 하면, SELinux 서버는 그 프로세스의 보안 정책이 접근을 허용하는지 확인하고 인가 결정을 내려요.
쿠버네티스에서는 매니페스트의 securityContext 필드에 SELinux 라벨을 설정할 수 있어요. 지정된 라벨은 그 프로세스들에 할당돼요. 그 라벨에 영향을 주는 보안 정책을 구성했다면 호스트 OS 커널이 그 정책을 강제해요.
쿠버네티스에서 SELinux를 사용하는 방법을 배우려면 컨테이너에 SELinux 라벨 할당하기를 참고하세요.
AppArmor와 SELinux의 차이점
Linux 노드의 운영체제는 보통 AppArmor나 SELinux 중 하나를 포함해요. 두 메커니즘 모두 비슷한 유형의 보호를 제공하지만, 차이점도 있어요.
- 구성: AppArmor는 리소스에 대한 접근을 정의하기 위해 프로필을 사용해요. SELinux는 특정 라벨에 적용되는 정책을 사용해요.
- 정책 적용: AppArmor에서는 파일 경로를 사용해 리소스를 정의해요. SELinux는 리소스의 인덱스 노드(inode)를 사용해 리소스를 식별해요.
기능 요약
아래 표는 각 보안 제어의 사용 사례와 범위를 설명해요. 이 제어들을 함께 사용해 더 강화된 시스템을 구축할 수 있어요.
| 보안 기능 | 설명 | 사용 방법 | 예시 |
|---|---|---|---|
| seccomp | 사용자 공간의 개별 커널 호출을 제한해요. 제한된 syscall을 사용하는 취약점이 시스템을 손상시킬 가능성을 줄여요. | 로드된 seccomp 프로필을 Pod나 컨테이너 스펙에 지정해 그 제약을 Pod 안 프로세스에 적용해요. | CVE-2022-0185에서 사용된 unshare syscall을 거부해요. |
| AppArmor | 특정 리소스에 대한 프로그램 접근을 제한해요. 프로그램의 공격 표면을 줄여요. 감사 로깅을 개선해요. | 로드된 AppArmor 프로필을 컨테이너 스펙에 지정해요. | 읽기 전용 프로그램이 시스템의 어떤 파일 경로에도 쓰지 못하게 해요. |
| SELinux | 라벨과 보안 정책을 사용해 파일, 애플리케이션, 포트, 프로세스 같은 리소스에 대한 접근을 제한해요. | 특정 라벨에 대한 접근 제한을 지정하고, 프로세스에 그 라벨을 태그해서 라벨과 관련된 접근 제한을 강제해요. | 컨테이너가 자기 파일시스템 밖의 파일에 접근하지 못하게 해요. |
참고:
AppArmor와 SELinux 같은 메커니즘은 컨테이너 너머까지 확장되는 보호를 제공할 수 있어요. 예를 들어 SELinux로 CVE-2019-5736을 완화하는 데 도움을 줄 수 있어요.
커스텀 구성 관리 고려사항
seccomp, AppArmor, SELinux는 보통 기본 보호를 제공하는 기본 구성을 가져요. 워크로드 요구사항을 충족하는 커스텀 프로필과 정책도 만들 수 있어요. 이런 커스텀 구성을 대규모로 관리하고 배포하는 건, 특히 세 가지 기능을 모두 함께 사용한다면 어려울 수 있어요. 이런 구성을 대규모로 관리하려면 Kubernetes Security Profiles Operator 같은 도구를 사용하세요.
커널 수준 보안 기능과 특권 컨테이너
쿠버네티스는 일부 신뢰할 수 있는 컨테이너가 특권(privileged) 모드로 실행되도록 지정할 수 있게 해줘요. Pod 안의 어떤 컨테이너든 특권 모드로 실행되어, 그렇지 않으면 접근할 수 없는 운영체제 관리 기능을 사용할 수 있어요. Windows와 Linux 모두에서 사용할 수 있어요.
특권 컨테이너는 워크로드에서 사용할 수 있는 Linux 커널 제약 중 일부를 명시적으로 덮어써요.
- seccomp: 특권 컨테이너는 매니페스트에서 지정한 seccomp 프로필을 덮어쓰고
Unconfinedseccomp 프로필로 실행돼요. - AppArmor: 특권 컨테이너는 적용된 AppArmor 프로필을 무시해요.
- SELinux: 특권 컨테이너는
unconfined_t도메인으로 실행돼요.
특권 컨테이너
컨테이너의 securityContext 필드에서 privileged: true를 설정하면 Pod 안의 어떤 컨테이너든 특권 모드를 켤 수 있어요. 특권 컨테이너는 적용된 seccomp 프로필, AppArmor 프로필, SELinux 제약 같은 많은 강화 설정을 덮어쓰거나 되돌려요. 특권 컨테이너에는 필요하지 않은 capabilities를 포함해 모든 Linux capabilities가 부여돼요. 예를 들어 특권 컨테이너의 루트 사용자는 노드에서 CAP_SYS_ADMIN과 CAP_NET_ADMIN capabilities를 사용해 런타임 seccomp 구성과 다른 제한을 우회할 수 있을지도 몰라요.
대부분의 경우 특권 컨테이너 사용을 피하고, 대신 securityContext 필드의 capabilities 필드로 컨테이너가 필요로 하는 특정 capabilities를 부여하세요. securityContext로 부여할 수 없는 capability가 있을 때만 특권 모드를 사용하세요. 네트워크 스택을 조작하거나 하드웨어 장치에 접근하는 것 같은 운영체제 관리 기능을 사용하려는 컨테이너에 유용해요.
쿠버네티스 1.26 이상에서는 Pod 스펙의 security context에서 windowsOptions.hostProcess 플래그를 설정해 Windows 컨테이너도 비슷하게 특권 모드로 실행할 수 있어요. 자세한 내용과 절차는 Windows HostProcess Pod 만들기를 참고하세요.
권장사항과 모범 사례
- 커널 수준 보안 기능을 구성하기 전에 네트워크 수준 격리를 먼저 구현하는 것을 고려하세요. 자세한 내용은 보안 체크리스트를 읽어보세요.
- 꼭 필요하지 않다면, Pod 매니페스트에 특정 사용자·그룹 ID를 설정하고
runAsNonRoot: true를 지정해서 Linux 워크로드를 비루트로 실행하세요.
추가로 Pod 매니페스트에서 hostUsers: false를 설정하면 사용자 네임스페이스에서 워크로드를 실행할 수 있어요. 이렇게 하면 사용자 네임스페이스 안에서는 루트 사용자로, 노드의 호스트 네임스페이스에서는 비루트 사용자로 컨테이너를 실행할 수 있어요. 이 기능은 아직 초기 개발 단계라서 필요한 수준의 지원이 없을 수도 있어요. 자세한 절차는 Pod와 함께 사용자 네임스페이스 사용하기를 참고하세요.