AppArmor는 리눅스 커널의 보안 모듈로, 프로그램이 수행할 수 있는 동작을 제어하는 강제적 접근 제어(Mandatory Access Control, MAC) 시스템입니다.
일반적인 리눅스의 권한 시스템(Discretionary Access Control, DAC)은 사용자가 파일 소유권을 기반으로 접근 권한을 제어합니다. 하지만 AppArmor는 사용자 권한과 관계없이, 프로그램 자체가 무엇을 할 수 있는지 엄격하게 정의된 규칙을 강제합니다.

AppArmor의 핵심 개념

  1. 보안 프로필(Profile) AppArmor의 모든 규칙은 보안 프로필이라는 텍스트 파일에 정의됩니다. 각 프로필은 특정 애플리케이션(예: nginx, mysql)에 대한 규칙을 담고 있습니다. 이 프로필에는 다음과 같은 규칙들이 포함됩니다.
    • 파일 접근 제어: 특정 파일이나 디렉터리에 대한 읽기(r), 쓰기(w), 실행(x) 권한을 허용하거나 거부합니다.
    • 네트워크 접근 제어: 네트워크 소켓을 생성하거나, 특정 포트에 연결하는 행위를 허용하거나 차단합니다.
    • 자원 제어: 특정 시스템 자원(proc, sys)에 대한 접근을 제어합니다.
  2. 두 가지 동작 모드 AppArmor 프로필은 두 가지 모드로 동작할 수 있습니다.
    • Enforce Mode (강제 모드): 프로필에 정의된 규칙을 강력하게 강제합니다. 규칙을 위반하는 모든 행위는 즉시 차단되고, 위반 기록이 시스템 로그에 남습니다.
    • Complain Mode (경고 모드): 규칙을 위반하는 행위를 차단하지 않고, 경고 메시지만 로그에 남깁니다. 주로 프로필을 개발하거나 테스트하는 단계에서 애플리케이션의 동작을 모니터링하기 위해 사용됩니다.

쿠버네티스에서 AppArmor의 역할

쿠버네티스는 컨테이너의 보안을 강화하기 위해 AppArmor를 효과적으로 활용합니다.

  1. 노드에 프로필 로드: 먼저, kubelet이 실행되는 각 워커 노드에 AppArmor 프로필을 미리 로드해야 합니다. apparmor_parser -r /etc/apparmor.d/my-profile 명령어를 통해 프로필을 커널에 적용합니다.
  2. 파드 매니페스트에 애너테이션 추가: 파드 매니페스트 파일에 애너테이션을 추가하여, 해당 파드의 컨테이너가 어떤 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

BOM(Software Bill of Materials) 소개

**BOM(Software Bill of Materials)**은 우리말로 소프트웨어 자재 명세서라고 불립니다. 이는 하나의 소프트웨어를 구성하는 모든 구성 요소(오픈 소스 라이브러리, 상용 소프트웨어, 내부 개발 코드 등)를 목록화한 것입니다. 마치 가공식품의 성분표처럼, 소프트웨어가 무엇으로 만들어졌는지 투명하게 보여주는 역할을 합니다.

왜 BOM이 중요한가요?

  • 공급망 보안 강화: 소프트웨어 공급망(Software Supply Chain) 공격에 대비하여, 내가 사용하는 소프트웨어가 어떤 취약한 구성 요소를 포함하고 있는지 파악할 수 있습니다.
  • 취약점 관리: SBOM을 통해 소프트웨어에 포함된 모든 패키지의 버전을 확인하고, 알려진 보안 취약점(CVE)이 있는지 자동으로 검사할 수 있습니다.
  • 라이선스 준수: 각 구성 요소의 오픈 소스 라이선스를 명확히 파악하여, 라이선스 의무를 위반할 위험을 줄일 수 있습니다.

BOM 툴의 종류

CKS(Certified Kubernetes Security Specialist) 시험에서 주로 다루는 BOM 툴은 TrivySyft입니다. 이 두 도구는 각각의 강점을 가지고 상호 보완적으로 사용됩니다.

1. Syft

Syft는 SBOM(Software Bill of Materials) 생성에 특화된 경량의 오픈 소스 도구입니다. 컨테이너 이미지나 파일 시스템을 빠르게 분석하여 정확한 SBOM을 생성하는 데 초점을 맞춥니다.

  • 주요 특징:
    • 전문성: 오직 SBOM 생성에만 집중하여 빠르고 정확한 결과를 제공합니다.
    • 다양한 출력 형식: SBOM 표준인 SPDXCycloneDX를 비롯해 JSON, YAML, 테이블 등 다양한 형식으로 출력할 수 있습니다.
    • 명령어 예시: syft <이미지> -o spdx-json > <파일명.spdx.json>

2. Trivy

Trivy는 컨테이너 이미지, 파일 시스템, Git 리포지토리 등의 취약점 스캔으로 더 잘 알려진 올인원(all-in-one) 보안 도구입니다. 하지만, SBOM 생성 기능도 함께 제공하여 하나의 도구로 여러 작업을 수행할 수 있습니다.

  • 주요 특징:
    • 통합 기능: 취약점 스캔과 SBOM 생성을 한 번에 처리할 수 있어 편리합니다.
    • 다양한 스캔 대상: 컨테이너 이미지뿐만 아니라, 로컬 파일 시스템, Git 리포지토리, 그리고 이미 생성된 SBOM 파일(trivy sbom)까지도 스캔할 수 있습니다.
    • 명령어 예시: trivy image --format spdx-json <이미지> > <파일명.spdx.json>

3. Grype

Grype는 Syft와 함께 사용되는 도구입니다. Syft로 생성된 SBOM 파일을 입력으로 받아, 해당 파일에 명시된 구성 요소들의 취약점만 빠르게 스캔하는 데 사용됩니다. 이는 대규모 컨테이너 환경에서 효율적인 보안 관리를 가능하게 합니다.


SPDX(Software Package Data Exchange) 파일에 대한 설명

SPDXSBOM을 작성하기 위한 국제 표준입니다. 즉, SBOM은 개념이고, SPDX는 그 개념을 구현하는 구체적인 파일 형식이라고 이해할 수 있습니다. SPDX 파일은 소프트웨어 구성 요소의 정보를 구조화된 형식으로 기록하여, 사람이 읽기 쉽고 소프트웨어가 자동으로 처리하기 용이하도록 설계되었습니다.

SPDX 파일에 포함된 주요 정보:

  • 구성 요소 목록: 소프트웨어에 포함된 모든 패키지(예: openssl, glibc)와 그 버전 정보.
  • 라이선스 정보: 각 패키지에 적용된 오픈 소스 라이선스의 종류.
  • 취약점 정보: 관련된 보안 취약점(CVE) 링크 등.
  • 저작권 및 제작자 정보: 각 구성 요소의 저작권 정보.

SPDX 파일의 중요성:

SPDX 파일은 소프트웨어 공급망에서 투명성을 보장하는 핵심 문서입니다. BOM 툴(Syft, Trivy)을 사용하여 SPDX 파일을 생성한 뒤, 이 파일을 보안 스캐너(Trivy, Grype)에 입력하여 자동으로 취약점을 분석하는 워크플로를 구축할 수 있습니다.

 

SPDX 파일 생성 방법

 

 

  • syft: SBOM 생성에 특화된 도구입니다.
    • 사용 예시: syft <이미지> --output spdx-json > <파일>
  • trivy: 취약점 스캐너이지만, SBOM 생성 기능도 지원합니다.
    • 사용 예시: trivy image <이미지> --format spdx-json > <파일>

 

 

 

 

 

 

 

 

'k8s > CKS' 카테고리의 다른 글

[CKS] AppArmor  (0) 2025.09.11
[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

쿠버네티스 TLS 암호화 설정 방법

TLS 암호화를 구성하는 것은 클러스터의 보안을 강화하는 중요한 단계입니다. 클라이언트와 서버 간의 통신에 사용되는 암호화 알고리즘을 지정하여, 안전한 데이터 전송을 보장할 수 있습니다. 쿠버네티스에서는 이 설정을 etcd, kube-apiserver, kubelet의 세 가지 주요 구성 요소에 각각 적용해야 합니다.

1. etcd 설정 변경

etcd는 쿠버네티스 클러스터의 모든 데이터를 저장하는 분산형 데이터베이스입니다. etcd 간의 통신과 etcd와 API 서버 간의 통신을 보호하기 위해 TLS 설정을 변경해야 합니다.

  • 설정 파일: /etc/kubernetes/manifests/etcd.yaml (kubeadm으로 설치한 경우)
  • 추가/수정 옵션:
    • --cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: etcd에서 지원할 TLS 암호화 스위트를 지정합니다. 이 옵션은 클라이언트-서버 및 etcd 노드 간의 통신에 적용됩니다.
    • --tls-min-version=TLS1.3: etcd가 지원할 최소 TLS 버전을 TLS 1.3으로 설정하여, 오래된 취약한 TLS 버전을 비활성화합니다.

https://etcd.io/docs/v3.6/op-guide/configuration/

Configuration options

etcd configuration files, flags, and environment variables

etcd.io

 
 

2. kube-apiserver 설정 변경

kube-apiserver는 클러스터의 모든 REST 요청을 처리하는 핵심 구성 요소입니다. API 서버가 클라이언트와 통신할 때 사용할 암호화 스위트를 명확히 지정해야 합니다.

  • 설정 파일: /etc/kubernetes/manifests/kube-apiserver.yaml
  • 추가/수정 옵션:
    • --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: API 서버가 사용하는 TLS 암호화 스위트를 지정합니다. 이 설정은 API 서버가 외부 클라이언트와 통신할 때 적용됩니다.
    • --tls-min-version=VersionTLS13: API 서버가 허용할 최소 TLS 버전을 TLS 1.3으로 설정합니다.

https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/

kube-apiserver

Synopsis The Kubernetes API server validates and configures data for the api objects which include pods, services, replicationcontrollers, and others. The API Server services REST operations and provides the frontend to the cluster's shared state through w

kubernetes.io

 
 

3. kubelet 설정 변경

kubelet은 각 노드에서 실행되는 에이전트로, API 서버와 통신하며 파드를 관리합니다. kubelet 또한 TLS 통신을 사용하므로, API 서버와 호환되는 TLS 설정을 갖추어야 합니다.

  • 설정 파일: /var/lib/kubelet/config.yaml
  • 추가/수정 옵션:
    • tlsCipherSuites: ["TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"]
    • tlsMinVersion: VersionTLS13
    • kubelet은 커맨드 라인 플래그(--tls-cipher-suites)를 사용하거나, 설정 파일(tlsCipherSuites, tlsMinVersion)을 통해 값을 설정할 수 있습니다.

https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/

kubelet

Synopsis The kubelet is the primary "node agent" that runs on each node. It can register the node with the apiserver using one of: the hostname; a flag to override the hostname; or specific logic for a cloud provider. The kubelet works in terms of a PodSpe

kubernetes.io

 

'k8s > CKS' 카테고리의 다른 글

[CKS] AppArmor  (0) 2025.09.11
[CKS] BOM 툴 trivy -2  (0) 2025.09.10
[CKS] 쿠버네티스 API 서버 보안 강화: 익명 접근 차단  (0) 2025.09.09
[CKS] BOM 툴 trivy -1  (0) 2025.09.09
[CKS] Pod Security Standards - restricted  (0) 2025.09.08

1. 개요: 왜 API 서버의 익명 접근을 차단해야 하는가?

쿠버네티스 클러스터에서 API 서버는 모든 작업의 중심입니다. 그러나 기본 설정은 보안 취약점을 내포할 수 있습니다. 특히, 인증되지 않은 사용자의 접근을 허용하는 익명 인증(--anonymous-auth)은 중요한 보안 위협입니다. 이 가이드는 kube-apiserver와 kubelet 설정을 수정하여 익명 접근을 차단하고, 클러스터의 전반적인 보안 수준을 높이는 방법을 다룹니다.

 

2. 익명 접근 차단 및 설정 방법

익명 접근을 막기 위해 두 가지 핵심 요소를 변경해야 합니다.

2.1. kube-apiserver 설정 변경

kube-apiserver의 기본 설정을 변경하여 익명 인증을 비활성화하고, 권한 부여 모드를 명확히 지정합니다.

  • 적용 파일: /etc/kubernetes/manifests/kube-apiserver.yaml
  • 추가/수정 옵션:
    • --anonymous-auth=false: 익명 사용자의 인증을 완전히 비활성화합니다. 이 옵션이 없으면 인증되지 않은 모든 요청이 system:anonymous 사용자로 처리됩니다.
    • --authorization-mode=Node,RBAC: API 서버의 권한 부여 모드를 명확히 Node와 RBAC로 지정합니다. 이를 통해 노드와 사용자/서비스 계정에 대한 접근 제어를 강제합니다.
    • --enable-admission-plugins=NodeRestriction: 노드가 자신이 관리하는 파드에 대한 정보만 수정하도록 제한하는 플러그인을 활성화합니다. 이는 클러스터 내부의 권한 에스컬레이션 공격을 방어하는 데 필수적입니다.

2.2. kubelet 설정 변경

kubelet은 API 서버와 통신하는 에이전트이므로, kube-apiserver 설정에 맞춰 kubelet의 인증/권한 부여 설정을 수정해야 합니다.

  • 적용 파일: /var/lib/kubelet/config.yaml
  • 수정 옵션:
    • authentication.anonymous.enabled: false: kubelet의 익명 인증을 비활성화합니다.
    • authentication.webhook.enabled: true: API 서버가 kubelet의 인증 요청을 처리하도록 활성화합니다.
    • authorization.mode: Webhook: kubelet의 권한 부여 요청을 API 서버의 Webhook으로 처리하도록 지정합니다.
      authentication:
        anonymous:
          enabled: false    # 익명 인증 비활성화
        webhook:
          cacheTTL: 0s
          enabled: true     # Webhook 기반 인증 활성화
        x509:
          clientCAFile: /etc/kubernetes/pki/ca.crt
      authorization:
        mode: Webhook       # Webhook 기반 권한 부여 활성화
        webhook:
          cacheAuthorizedTTL: 0s
          cacheUnauthorizedTTL: 0s
      

3. 익명 사용자 관련 RoleBinding 제거

kube-apiserver 설정을 변경했더라도, 기존에 존재하던 익명 사용자에 대한 RoleBinding을 명시적으로 제거해야만 완벽한 보안을 달성할 수 있습니다.

  • 관련 RoleBinding: system:anonymous
  • 제거 명령어:--kubeconfig 플래그는 관리자 권한으로 명령어를 실행하기 위해 필요합니다.
  • Bash
     
    kubectl --kubeconfig /etc/kubernetes/admin.conf delete clusterrolebinding system:anonymous
    

4. 최종 확인

위의 모든 단계를 완료한 후, kube-apiserver와 kubelet이 재시작되었는지 확인하고, 인증 정보 없이 API 서버에 접근하여 접근이 차단되는지 검증해야 합니다. 이로써 클러스터의 API 서버는 인증된 사용자에게만 접근을 허용하게 되어 보안이 강화됩니다.

'k8s > CKS' 카테고리의 다른 글

[CKS] BOM 툴 trivy -2  (0) 2025.09.10
[CKS] k8s TLS 설정  (0) 2025.09.09
[CKS] BOM 툴 trivy -1  (0) 2025.09.09
[CKS] Pod Security Standards - restricted  (0) 2025.09.08
[CKS] cilium  (0) 2025.09.08

Trivy는 컨테이너 이미지, 파일 시스템, Git 리포지토리 등을 스캔하여 취약점과 잘못된 구성(misconfigurations)을 찾아내는 경량의 통합 보안 스캐너입니다.


Trivy의 주요 특징

  • 자동화된 취약점 스캔: Trivy는 별도의 설정 없이도 컨테이너 이미지에 포함된 OS 패키지, 프로그래밍 언어 라이브러리(Java, Python, Go 등)의 알려진 취약점을 자동으로 식별합니다.
  • 간편한 사용: 단일 바이너리 파일로 제공되어 설치와 사용이 매우 간단합니다. trivy image <이미지_이름>과 같은 직관적인 명령어로 스캔을 시작할 수 있습니다.
  • 다양한 스캔 대상: 컨테이너 이미지뿐만 아니라, 로컬 파일 시스템, Git 리포지토리, Kubernetes 클러스터, 그리고 IaC(Infrastructure as Code) 파일(Terraform, CloudFormation 등)까지 스캔할 수 있습니다.
  • 개발 프로세스 통합: CI/CD 파이프라인에 쉽게 통합하여 개발 초기 단계부터 보안 취약점을 검사할 수 있습니다.

 

Trivy 설치

  1. 최신 버전 확인: Trivy의 GitHub 릴리스 페이지에서 최신 버전의 바이너리 이름을 확인합니다.
  2. 바이너리 다운로드: 예를 들어, 최신 버전이 v0.50.0이라면, wget을 사용해 .deb 파일을 다운로드합니다.버전이 다르면 위 URL의 버전 번호를 바꿔야 합니다.
  3. 패키지 다운
    wget https://github.com/aquasecurity/trivy/releases/download/v0.50.0/trivy_0.50.0_Linux-64bit.deb
    
  4. 패키지 설치: 다운로드한 .deb 파일을 dpkg로 설치합니다.
    sudo dpkg -i trivy_0.50.0_Linux-64bit.deb
    

 

설치가 완료되면 trivy --version 명령어로 버전을 확인하여 설치가 제대로 되었는지 검증할 수 있습니다.

trivy --version

 

 

Trivy 사용 방법

kube-system 네임스페이스에 있는 모든 파드의 컨테이너 이미지를 대상으로 Trivy를 실행하여 취약점을 스캔하는 방법입니다.

 

단계 1: kube-system 파드의 이미지 목록 조회

먼저, kube-system 네임스페이스에 존재하는 모든 파드와 해당 파드에 사용된 컨테이너 이미지 목록을 확인합니다.

kubectl get pods --namespace kube-system --output=custom-columns="NAME:.metadata.name,IMAGE:.spec.containers[*].image"

 

  • --output=custom-columns: 출력 형식을 사용자 정의합니다.
  • "NAME:.metadata.name,IMAGE:.spec.containers[*].image": 파드의 이름(NAME)과 사용된 이미지(IMAGE)를 출력 열로 지정합니다. *는 파드 내의 모든 컨테이너를 의미합니다.

 

 

단계 2: Trivy로 이미지 취약점 스캔

위 명령어로 확인한 이미지 이름을 기반으로 각 이미지에 대해 Trivy 스캔을 수행합니다.

trivy image docker.io/calico/kube-controllers:v3.24.1 | egrep -i 'high|critical'

'k8s > CKS' 카테고리의 다른 글

[CKS] k8s TLS 설정  (0) 2025.09.09
[CKS] 쿠버네티스 API 서버 보안 강화: 익명 접근 차단  (0) 2025.09.09
[CKS] Pod Security Standards - restricted  (0) 2025.09.08
[CKS] cilium  (0) 2025.09.08
[CKS] k8s Cluster & node version upgrade  (0) 2025.09.08

+ Recent posts