Kubernetes API 서버 우회 위험

Kubernetes API 서버 우회 위험 (Kubernetes API Server Bypass Risks)

API 서버와 다른 컴포넌트들과 관련된 보안 아키텍처 정보를 다룰게요.

Kubernetes API 서버는 외부 주체(사용자와 서비스)가 상호작용하는 클러스터의 주요 진입점이에요. 이 역할의 일부로, API 서버에는 감사 로깅과 어드미션 컨트롤러 같은 몇 가지 핵심 보안 통제 기능이 내장되어 있습니다.

하지만 이러한 통제를 우회해서 클러스터의 구성이나 콘텐츠를 수정할 수 있는 방법들이 존재해요. 이 페이지는 Kubernetes API 서버에 내장된 보안 통제가 우회될 수 있는 방식들을 설명해서, 클러스터 운영자와 보안 아키텍트가 이러한 우회를 적절히 제한할 수 있도록 돕는 것이 목적이에요.

kubelet API

kubelet은 일반적으로 클러스터 워커 노드의 TCP 포트 10250에 노출되는 HTTP API를 제공합니다. 사용 중인 Kubernetes 배포판에 따라 API가 컨트롤 플레인 노드에도 노출될 수 있어요. 이 API에 직접 접근하면 노드에서 실행 중인 파드에 대한 정보, 그 파드들의 로그를 노출하고, 노드에서 실행 중인 모든 컨테이너 안에서 명령을 실행할 수 있게 됩니다.

Kubernetes 클러스터 사용자가 RBAC를 통해 Node 객체 하위 리소스에 접근 권한이 있다면, 그 접근은 kubelet API와 상호작용하기 위한 권한 부여로 작동해요. 정확한 접근 범위는 kubelet 권한 부여에 설명된 대로 어떤 하위 리소스 접근 권한이 부여되었는지에 따라 달라집니다. kubelet API에 대한 직접 접근은 어드미션 컨트롤의 적용을 받지 않으며 Kubernetes 감사 로깅에도 기록되지 않아요. 이 API에 직접 접근할 수 있는 공격자는 특정 동작을 탐지하거나 방지하는 통제를 우회할 수 있습니다.

kubelet API는 여러 방식으로 요청을 인증하도록 구성할 수 있어요. 기본적으로 kubelet 구성은 익명 접근을 허용합니다. 대부분의 Kubernetes 제공자는 기본값을 웹훅과 인증서 인증을 사용하도록 변경하죠. 이렇게 하면 컨트롤 플레인이 호출자가 nodes API 리소스 또는 하위 리소스에 접근할 권한이 있는지 보장할 수 있습니다. 기본 익명 접근은 이 주장을 컨트롤 플레인과 확인하지 않아요.

완화 방법 (Mitigations)

  • RBAC 같은 메커니즘을 사용해서 nodes API 객체의 하위 리소스에 대한 접근을 제한해요. 모니터링 서비스처럼 필요한 경우에만 이 접근 권한을 부여하세요.
  • get 동사만 있더라도 nodes/proxy 포괄(catch-all) 권한을 부여하지 마세요. 대신 세밀한(granular) 권한을 부여합니다.
  • kubelet 포트에 대한 접근을 제한해요. 지정된 신뢰할 수 있는 IP 주소 범위만 포트에 접근하도록 허용하세요.
  • kubelet 인증이 웹훅 또는 인증서 모드로 설정되어 있는지 확인합니다.
  • 인증되지 않은 "읽기 전용(read-only)" Kubelet 포트가 클러스터에서 활성화되지 않았는지 확인해요.

etcd API

Kubernetes 클러스터는 데이터 저장소로 etcd를 사용합니다. etcd 서비스는 TCP 포트 2379에서 수신 대기해요. 접근이 필요한 유일한 클라이언트는 Kubernetes API 서버와 사용하는 백업 도구입니다. 이 API에 직접 접근하면 클러스터에 보관된 모든 데이터를 노출하거나 수정할 수 있어요.

etcd에 대한 직접 접근은 Kubernetes 어드미션 컨트롤의 적용을 받지 않으며 Kubernetes 감사 로깅에도 기록되지 않습니다. API 서버의 etcd 클라이언트 인증서 개인 키에 대한 읽기 접근 권한이 있는(또는 새로 신뢰할 수 있는 클라이언트 인증서를 만들 수 있는) 공격자는 클러스터 시크릿에 접근하거나 접근 규칙을 수정해서 클러스터 관리자 권한을 얻을 수 있어요. Kubernetes RBAC 권한을 높이지 않더라도, etcd를 수정할 수 있는 공격자는 어떤 API 객체든 검색하거나 클러스터 안에 새 워크로드를 만들 수 있습니다.

많은 Kubernetes 제공자는 etcd가 상호 TLS(mutual TLS)를 사용하도록 구성합니다(클라이언트와 서버가 서로의 인증서를 확인해서 서로를 인증). etcd API에 대한 권한 부여의 널리 받아들여진 구현은 없지만, 그 기능 자체는 존재해요. 권한 부여 모델이 없기 때문에, 어떤 인증서든 (서비스에 대해 접근이 허용된 어떤 클라이언트의) 접근을 부여하게 됩니다.

완화 방법 (Mitigations)

  • etcd가 신뢰하는 인증 기관이 그 서비스에 대한 인증 목적으로만 사용되도록 하세요.
  • etcd 서버 인증서의 개인 키와 API 서버의 클라이언트 인증서 및 키에 대한 접근을 통제합니다.
  • 네트워크 수준에서 etcd 포트에 대한 접근을 제한해서, 지정된 신뢰할 수 있는 IP 주소 범위에서만 접근을 허용하는 것을 고려해요.

컨테이너 런타임 소켓 (Container runtime socket)

완화 방법 (Mitigations)

  • 컨테이너 런타임 소켓에 대한 파일시스템 접근을 엄격하게 통제하세요. 가능하면 이 접근을 root 사용자로 제한합니다.
  • Linux 커널 네임스페이스 같은 메커니즘을 사용해서 kubelet을 노드에서 실행되는 다른 컴포넌트와 격리해요.

더 알아보기