AppArmor는 리눅스 커널의 보안 모듈로, 프로그램이 수행할 수 있는 동작을 제어하는 강제적 접근 제어(Mandatory Access Control, MAC) 시스템입니다.
일반적인 리눅스의 권한 시스템(Discretionary Access Control, DAC)은 사용자가 파일 소유권을 기반으로 접근 권한을 제어합니다. 하지만 AppArmor는 사용자 권한과 관계없이, 프로그램 자체가 무엇을 할 수 있는지 엄격하게 정의된 규칙을 강제합니다.
AppArmor의 핵심 개념
- 보안 프로필(Profile) AppArmor의 모든 규칙은 보안 프로필이라는 텍스트 파일에 정의됩니다. 각 프로필은 특정 애플리케이션(예: nginx, mysql)에 대한 규칙을 담고 있습니다. 이 프로필에는 다음과 같은 규칙들이 포함됩니다.
- 파일 접근 제어: 특정 파일이나 디렉터리에 대한 읽기(r), 쓰기(w), 실행(x) 권한을 허용하거나 거부합니다.
- 네트워크 접근 제어: 네트워크 소켓을 생성하거나, 특정 포트에 연결하는 행위를 허용하거나 차단합니다.
- 자원 제어: 특정 시스템 자원(proc, sys)에 대한 접근을 제어합니다.
- 두 가지 동작 모드 AppArmor 프로필은 두 가지 모드로 동작할 수 있습니다.
- Enforce Mode (강제 모드): 프로필에 정의된 규칙을 강력하게 강제합니다. 규칙을 위반하는 모든 행위는 즉시 차단되고, 위반 기록이 시스템 로그에 남습니다.
- Complain Mode (경고 모드): 규칙을 위반하는 행위를 차단하지 않고, 경고 메시지만 로그에 남깁니다. 주로 프로필을 개발하거나 테스트하는 단계에서 애플리케이션의 동작을 모니터링하기 위해 사용됩니다.
쿠버네티스에서 AppArmor의 역할
쿠버네티스는 컨테이너의 보안을 강화하기 위해 AppArmor를 효과적으로 활용합니다.
- 노드에 프로필 로드: 먼저, kubelet이 실행되는 각 워커 노드에 AppArmor 프로필을 미리 로드해야 합니다. apparmor_parser -r /etc/apparmor.d/my-profile 명령어를 통해 프로필을 커널에 적용합니다.
- 파드 매니페스트에 애너테이션 추가: 파드 매니페스트 파일에 애너테이션을 추가하여, 해당 파드의 컨테이너가 어떤 AppArmor 프로필을 사용할지 지정합니다.
- 애너테이션: container.apparmor.security.beta.kubernetes.io/<컨테이너-이름>: "localhost/<프로필-이름>"
- 이 애너테이션은 kubelet에게 "이 컨테이너를 실행할 때, 호스트 노드에 로드된 AppArmor 프로필을 적용하라"고 지시합니다.
이를 통해 컨테이너가 해킹당하더라도, AppArmor 프로필이 허용하지 않는 시스템 호출이나 파일 접근을 시도하면 즉시 차단되어 공격의 확산을 막을 수 있습니다.
주요 AppArmor 도구
- apparmor_parser: 프로필을 파싱하고 커널에 로드하는 데 사용되는 핵심 도구입니다.
- aa-status: 현재 시스템에 로드된 AppArmor 프로필의 상태(enforce 모드인지, complain 모드인지)를 확인하는 데 사용됩니다.
- aa-logprof: 애플리케이션의 동작 로그를 분석하여 자동으로 새로운 프로필 규칙을 제안하는 도구입니다.
테스트
1. AppArmor 프로필 생성 및 적용 (워커 노드)
워커 노드에 접속하여 /etc/apparmor.d/test 파일을 다음 내용으로 생성합니다.
파일 경로: /etc/apparmor.d/test
#include <tunables/global>
# 프로필 이름: k8s-apparmor-example-deny-write
# attach_disconnected 플래그는 컨테이너와 연결이 끊어져도 프로필이 유지되게 합니다.
profile k8s-apparmor-example-deny-write flags=(attach_disconnected) {
# 리눅스 시스템에 필요한 기본 권한을 포함
#include <abstractions/base>
# 모든 파일 접근에 대한 기본 규칙 정의
file,
# 명시적으로 모든 파일 쓰기(write)를 거부합니다.
# deny: 거부 규칙
# /**: 모든 디렉터리와 파일
# w: 쓰기(write) 권한
deny /** w,
}
프로필을 커널에 로드
파일을 저장한 후, apparmor_parser를 사용하여 이 프로필을 리눅스 커널에 로드합니다.
sudo apparmor_parser -r /etc/apparmor.d/test
- -r 옵션은 프로필을 재로드(Reload) 또는 **강제 적용(Enforce)**하라는 의미입니다.
2. AppArmor 프로필을 적용한 파드 배포 (컨트롤 플레인)
이제 방금 생성한 AppArmor 프로필을 사용할 파드를 생성할 차례입니다.
파드 매니페스트 파일 생성
pod.yaml이라는 이름으로 아래 매니페스트 파일을 생성합니다.
apiVersion: v1
kind: Pod
metadata:
name: hello-apparmor
spec:
# 이 부분이 AppArmor 프로필을 적용하는 핵심 설정입니다.
securityContext:
appArmorProfile:
# type: Localhost는 프로필이 호스트 노드에 있다는 것을 의미합니다.
type: Localhost
# localhostProfile: 로드한 AppArmor 프로필의 이름을 지정합니다.
localhostProfile: k8s-apparmor-example-deny-write
containers:
- name: hello
image: busybox:1.28
command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
매니페스트 적용
kubectl apply 명령어로 파드를 생성합니다.
kubectl apply -f pod.yaml
3. AppArmor 동작 결과 확인
이제 파드가 정상적으로 생성되었는지 확인하고, AppArmor 프로필이 의도한 대로 동작하는지 테스트합니다.
1) 파드에 적용된 프로필 확인
cat /proc/1/attr/current 명령어를 사용하여 컨테이너의 프로세스에 어떤 AppArmor 프로필이 적용되었는지 확인할 수 있습니다.
kubectl exec hello-apparmor -- cat /proc/1/attr/current

2) 파일 쓰기 작업 거부 확인
마지막으로, touch 명령어를 통해 파일 쓰기를 시도하여 AppArmor가 이를 성공적으로 차단하는지 확인합니다.
kubectl exec hello-apparmor -- touch /tmp/test
https://kubernetes.io/docs/tutorials/security/apparmor/
Restrict a Container's Access to Resources with AppArmor
FEATURE STATE: Kubernetes v1.31 [stable] (enabled by default: true) This page shows you how to load AppArmor profiles on your nodes and enforce those profiles in Pods. To learn more about how Kubernetes can confine Pods using AppArmor, see Linux kernel sec
kubernetes.io
'k8s > CKS' 카테고리의 다른 글
[CKS] BOM 툴 trivy -2 (0) | 2025.09.10 |
---|---|
[CKS] k8s TLS 설정 (0) | 2025.09.09 |
[CKS] 쿠버네티스 API 서버 보안 강화: 익명 접근 차단 (0) | 2025.09.09 |
[CKS] BOM 툴 trivy -1 (0) | 2025.09.09 |
[CKS] Pod Security Standards - restricted (0) | 2025.09.08 |