2020.09.02

'대세' 쿠버네티스, 문제는 '보안'··· 베스트 보안 프랙티스 5가지

Steven J. Vaughan-Nichols | Computerworld
세상에 등장한 지 6년이 채 되지 않았지만 ‘쿠버네티스’는 널리 사랑받는 컨테이너 오케스트레이션 프로그램으로 자리 잡았다. 하지만 인기를 얻는 만큼이나 원치 않는 유명세를 치르기 마련이다. 쿠버네티스를 사용한다면 보안에 만전을 기해야 한다. 물론 쉽지 않다.
 
ⓒGetty Images

클라우드 및 인프라 모니터링 업체 데이터독(Datadog)에 따르면 쿠버네티스가 컨테이너 시장을 지배하고 있다. 이 회사는 “컨테이너를 사용하는 데이터독 고객 가운데 45%가 쿠버네티스를 쓴다”라고 설명했다. 또한 데이터독은 마라톤(Marathon)과 도커스웜 모드(Docker swarm mode) 같은 다른 컨테이너 오케스트레이션 프로그램의 시장점유율은 감소했다고 덧붙였다. 

퍼블릭 클라우드 부문에서도 쿠버네티스는 인기가 많다. 데이터독은 “자사 집계에 의하면 애저에서 컨테이너를 운용하는 데이터독 고객 중 약 80%가 현재 쿠버네티스를 사용한다”라고 말했다. 

하지만 인기를 얻는 만큼이나 원치 않는 유명세를 치르기 마련이다. 이를테면 윈도우 사용자라면 잘 알겠지만 프로그램의 인기가 높을수록 공격받을 확률은 올라간다. 쿠버네티스도 마찬가지다. 쿠버네티스를 사용한다면 보안에 만전을 기해야 한다. 물론 쉽지 않다.

최근 쿠버네티스를 관장하는 CNCF(Cloud Native Computing Foundation)는 보안 업체 트레일 오브 비츠(Trail of Bits), 아트레디스 파트너스(Atredis Partners)에 보안 감사를 요청했다. 

트레일 오브 비츠는 “일부 구성 요소의 기본값 설정이 복잡하거나 운영 통제가 누락되는 등 쿠버네티스 구성 및 배포 측면에서 적지 않은 문제가 있다”라고 지적했다. 

정말 쉽지 않은 일이다. 그래도 노력을 멈출 순 없다. 여기서는 쿠버네티스를 안전하게 만드는 5가지 방법을 살펴본다.

1. 컨테이너 자체가 안전한지 확인한다
컨테이너가 엉망이라면 쿠버네티스 역시 안전할 수 없다. 지난해, 보안 업체 스니크(Snyk)는 가장 인기 있는 도커 이미지 10종을 분석한 보고서를 공개한 바 있다. 보고서에 따르면 모든 이미지가 취약한 시스템 라이브러리를 포함하고 있다는 사실이 드러났다. 

VM웨어 부사장 겸 최고 오픈소스 책임자(COSO) 더크 혼델은 2019년 오픈소스 리더십 서밋(Open Source Leadership Summit)에서 “컨테이너 패키징 형식은 윈도우의 .exe, 맥OS의 .dmg와 비슷하다. 기본적으로 모든 종속성이 포함된 전체 파일 시스템을 제공한다. 컨테이너에도 종속성이 포함돼 있기 때문에 출처를 비롯해 생성된 방법, 상응하는 소스 등 바이너리를 검토해야 한다”라고 언급했다.

다시 말해, 쿠버네티스에 배포하기 전에 컨테이너 콘텐츠를 신뢰할 수 있는지 확인해야 한다는 뜻이다. 그렇지 않으면 컴퓨터 업계에서 흔히 언급하는 ‘쓰레기가 들어가면 쓰레기가 나온다(Garbage in, garbage out)’라는 문제점에 직면하게 될 것이다. 

모든 프로덕션 컨테이너에 잠재적인 보안 문제가 없는지 반드시 확인해야 한다. 아주 힘든 일이다. 보안은 원래 쉬운 일이 아니다.

2. 컨테이너 리눅스 커널의 보안을 확보한다
컨테이너 외에도 커널이 안전한지 확인해야 한다. 모든 컨테이너가 하나의 리눅스 커널에서 실행되기 때문이다. 이는 리눅스 커널 보안 모듈인 AppArmor나 SELinux로 보안을 확보하는 것을 의미한다. 

리눅스 보안 모듈은 강제적인 접근 통제 아키텍처를 적용해 사용자 제어, 프로그램, 파일 액세스, 시스템 서비스 등을 제한한다. 이는 리눅스의 기본 보안 모델(명시적으로 금지한 경우를 제외한 모든 것을 허용)과는 근본적으로 다르다. 명시적으로 허용한 경우를 제외한 모든 것을 금지하기 때문이다.

이 때문에 많은 시스템 관리자가 설정(setting)에 어려움을 겪고 있다. 설정이 잘못된 경우에 닫았어야 할 보안창을 열어 두는 문제만 발생하는 것이 아니기 때문이다. 리눅스 시스템이 정지되면서 처음부터 다시 설정해야 할 수도 있다. 또는 제대로 설정했다고 생각했지만 컨테이너가 공격에 노출된 상태일 수도 있다. 

AppArmor 혹은 SELinux로 보호된 커널에서 애플리케이션을 실행하는 데 문제가 있을지도 모른다. 기본 운영체제는 보안 측면에서 자유로운 프로그램이 너무 많다. 이 보호된 커널들은 이러한 자유를 허용하지 않는다.

커널이 커널 모듈을 자동 로드하지 못하도록 차단해 일정 수준 보호를 받을 수 있다. 예를 들면 권한 없는 프로세스도 특정 네트워크 소켓을 만들어 일부 네트워크 프로토콜 관련 커널 모듈을 강제로 로드할 수 있기 때문에 의심스러운 모듈을 차단하는 규칙을 추가해야 한다. 금지된 모듈 구성 파일에서 다음의 작업을 진행하라. 

/etc/modprobe.d/kubernetes-blacklist.conf

여기에 다음의 명령을 집어넣는다.

# SCTP is not used in most Kubernetes clusters, and has also had
# vulnerabilities in the past.
blacklist sctp


하기 싫어도 피할 순 없다. 이를 악물고 AppArmor나 SELinux를 설치하라. 

3. 역할 기반 액세스 제어(RBAC)를 사용한다
쿠버네티스 버전 1.8부터 RBAC로 ‘사용자가 할 수 있는 일’을 통제할 수 있다. 이는 중요하다. 수십 개의 인스턴스와 클러스터를 실행시키는 사용자들을 통제하기란 어려운 일이기 때문이다. 

제로 트러스트 보안 방식인 RBAC를 사용하면 앱과 노드와 같은 구성 요소 그리고 사용자는 주어진 것보다 많은 권한을 얻지 못한다. 

RBAC는 API 레벨에서 작동한다. 이런 방식으로 RBAC 규칙은 권한 부여자 자체가 사용되지 않는 경우에도 사용자를 제한한다. 또 RBAC는 사용자가 역할 또는 역할 바인딩을 수정하여 자신에게 더 많은 권한을 부여하지 못하도록 차단한다. 

외부인 역시 차단하도록 기본 설정돼 있다. RBAC 정책은 제어 영역 구성 요소, 노드 및 컨트롤러에 범위가 지정된 권한을 부여한다. 그러나 쿠버네티스 시스템 네임스페이스 외부의 서비스 계정에는 권한을 주지 않는다(중요한 부분이다).

한편 쿠버네티스 RBAC를 쉽게 관리할 수 있도록 사전 정의된 역할들이 제공된다. 덕분에 개발자와 운영자, 클러스터 관리자는 필요한 권한만 가져와 적용할 수 있다.

이 시스템에서 클러스터 관리자의 역할은 유닉스와 리눅스에서 가장 강력한 권한을 갖는 ‘슈퍼유저(superuser)’와 동일하다. 클러스터 관리자는 모든 클러스터 리소스를 생성, 편집, 삭제할 수 있다. 즉 클러스터 관리자 역할에 대한 액세스를 신경 써서 보호해야 한다. 그렇다면, 이제 다음 단계로 넘어가 보자. 

4. 안전하게 유지하기란 힘든 일이다 
쿠버네티스 시크릿(Kubernetes Secrets)을 사용하면 비밀번호, OAuth 토큰, ssh 키 등 민감한 정보를 저장하고 관리할 수 있다. 이 민감한 정보는 이른바 ‘쿠버네티스 왕국’을 열 수 있는 열쇠이며, 반드시 보호돼야 할 대상이다. 

쿠버네티스는 API 액세스를 위해 시크릿을 자동 생성하고, 이를 사용하도록 포드(pods)를 수정한다. 그러나 포드가 데이터베이스에 액세스하는 데 필요한 이름과 비밀번호 같은 시크릿의 관리와 보호는 사용자가 책임져야 한다. 

간단한가? 유감스럽게도 쿠버네티스 시크릿에는 보안 취약점이 많다. 공식적으로 발표된 보안 취약점 목록을 보면 겁이 날 정도다.

• API 서버에서 시크릿 데이터는 쿠버네티스의 기본 분산형 키-값 저장소인 ‘etcd’에 저장된다. 기본적으로 etcd 데이터는 암호화되지 않는다. 즉 시크릿도 암호화되지 않는다는 뜻이다. 따라서 보관 시 암호화 기능을 활성화하고, etcd 액세스를 관리자급 사용자로 제한해야 한다.

• 많은 사용자가 시크릿을 JSON(JavaScript Object Notation)이나 YAML로 보관한다. 여기서 시크릿은 base64 문자열로 인코딩되지만, 암호화되진 않는다. 즉 파일을 공유하거나 소스 리포지토리에 체크인할 경우 자신의 시크릿을 공개하는 것이나 다름없다. 

• 애플리케이션이 특정 시크릿을 사용하면, 해당 앱은 이를 기록할 수 없고 신뢰할 수 없는 사람에게 전송할 수 없다. 

• 시크릿을 사용하는 동시에 포드를 생성할 수 있는 사용자는 시크릿값을 볼 수 있다. API 서버 정책에서 해당 사용자가 이를 읽는 것을 허용하지 않더라도 사용자는 포드를 실행할 수 있으며, 이는 시크릿을 노출시킨다.

• 현재 모든 노드에 관한 루트 권한을 가진 사람은 kubelet을 가장해 API 서버의 모든 시크릿을 읽을 수 있다. 이는 실제 기능이다. 오직 노드와 시크릿을 공유할 수 있게 만들어 루트 공격의 피해를 단일 노드로 제한하겠다는 개념이다. 


그다지 좋지 않은 상황이다. 위험을 완화하려면 가능할 때마다 시크릿을 암호화해야 한다. 또한 시크릿을 이미지나 포드에서 분리해 보관한다. 이를 위해서는 프로세스를 별개 컨테이너로 분할해야 한다. 

이를테면 한 애플리케이션을 프론트엔드 컨테이너와 백엔드 컨테이너로 분리할 수 있다. 백엔드에 개인 키라는 시크릿이 있으며, 프론트엔드의 로그인 요청에 응답한다.

이 밖에 서드파티 시크릿 도구로 시크릿을 보호해야 한다. 퍼블릭 클라우드의 경우 AWS 시크릿 매니저(AWS Secrets Manager), 구글 클라우드 플랫폼 KMS(Google Cloud Platform KMS), 애저 키 볼트(Azure Key Vault) 등이 있다. 그리고 기업용으로는 해시코프 볼트(Hashicorp Vault), 사이버아크/컨저(CyberArk/Conjur), 컨피던트(Confidant), 아쿠아 시큐리티 쿠버네티스 시큐리티(Aqua Security Kubernetes Security) 등의 프로그램이 있다. 

5. 네트워크를 안전하게 보호한다
위 내용에서 짐작할 수 있듯 etcd 액세스를 허용하는 것은 위험하다. 쿠버네티스 보안 업체 컨트롤플레인(ControlPlane)의 공동창업자 앤드류 마틴은 “API 서버의 etcd에 대한 쓰기 액세스는 전체 클러스터에서 루트 권한을 얻는 것과 동일하다. 심지어 읽기 액세스까지 사용해 쉽게 권한을 올릴 수 있다”라고 지적했다. 

이어서 그는 “따라서 피어 및 클라이언트 TLS 인증서로 etcd가 구성돼야 하며, 전용 노드에 배포돼야 한다. 작업자 노드에서 개인 키를 훔쳐 사용하는 것을 막기 위해 클러스터의 API 서버 액세스를 방화벽으로 차단할 수 있다”라고 덧붙였다. 개인적으로 볼 때는 ‘할 수 있다’가 아닌 ‘반드시 해야 한다’가 돼야 한다. 

네트워크 보호가 필요한 것은 etcd에 국한되지 않는다. 쿠버네티스는 API 기반이며, 모든 내부 클러스터 통신은 기본적으로 TLS로 암호화돼 있다. 하지만 이것으로는 부족하다. 쿠버네티스 포드가 모든 소스의 트래픽을 수신하도록 기본 설정돼 있기 때문이다. 

다시 말하지만 ‘모든 소스’다. 포드는 네트워크 연결에 광범위하게 개방돼 있고, 이는 안전하지 않다. 포드가 클러스터 내에서 그리고 외부 리소스와 커뮤니케이션하는 방식을 안전하게 정의하는 네트워크 정책을 정의해야 할 필요가 있다. 

네트워크 정책 컨트롤러를 지원하는 네트워킹 플러그인을 추가해 해당 작업을 진행할 수 있다. 이러한 컨트롤러가 없다면 설정한 네트워크 정책이 적용되지 않는다. 

안타깝게도 쿠버네티스에는 기본 탑재돼 있거나, 선택할 수 있는 네트워크 정책 컨트롤러가 없다. 칼리코(Calico), 실리움(Cilium), 쿠버라우터(Kube-router), 로마나(Romana), 위브넷(Weave Net)과 같은 서드파티 플러그인을 사용해야 한다. 

또한 ‘우선 차단(default-deny-all)’ 네트워크 정책으로 시작하라고 권고하고 싶다. 그렇게 하면 다른 네트워크 정책과 함께 명시적으로 허용하는 연결만 승인될 것이다. 

네트워크 정책은 네임스페이스에 설정돼야 하므로 네임스페이스에 따라 네트워크 정책을 설정해야 한다. 설정이 완료되면 적절한 네트워크 액세스 규칙을 적용할 수 있다. 먼저 쿠버네티스 네트워크 정책 가이드(Kubernetes Network Policy Recipes)를 참조하는 것이 좋다.

쿠버네티스 보안은 중요하다
앞서 언급한 것처럼 쿠버네티스를 안전하게 만드는 것은 쉬운 일이 아니다. 이 글을 읽었다면 모두 동의하리라 생각한다.

쿠버네티스는 처음부터 쉽게 배포할 수 있도록 설계됐다. 이를 다른 말로 하자면 설계상 안전하지 않다는 의미다. 그리고 쿠버네티스 클러스터가 제 기능을 하도록 보안을 확보하는 것은 사용자의 몫이라는 뜻이다. 

여기서는 쿠버네티스 보안에서 반드시 다뤄야 할 가장 중요한 문제만 간략히 언급했다. 이 밖에도 다른 문제가 많지만 무엇보다도 ‘쿠버네티스 보안’이 얼마나 중요한 일인지 인식하길 바란다. 

그렇다. 기업 자산이 공격에 노출되기 전에, 지금 당장 쿠버네티스 보안을 시작해야 한다. ciokr@idg.co.kr
 



2020.09.02

'대세' 쿠버네티스, 문제는 '보안'··· 베스트 보안 프랙티스 5가지

Steven J. Vaughan-Nichols | Computerworld
세상에 등장한 지 6년이 채 되지 않았지만 ‘쿠버네티스’는 널리 사랑받는 컨테이너 오케스트레이션 프로그램으로 자리 잡았다. 하지만 인기를 얻는 만큼이나 원치 않는 유명세를 치르기 마련이다. 쿠버네티스를 사용한다면 보안에 만전을 기해야 한다. 물론 쉽지 않다.
 
ⓒGetty Images

클라우드 및 인프라 모니터링 업체 데이터독(Datadog)에 따르면 쿠버네티스가 컨테이너 시장을 지배하고 있다. 이 회사는 “컨테이너를 사용하는 데이터독 고객 가운데 45%가 쿠버네티스를 쓴다”라고 설명했다. 또한 데이터독은 마라톤(Marathon)과 도커스웜 모드(Docker swarm mode) 같은 다른 컨테이너 오케스트레이션 프로그램의 시장점유율은 감소했다고 덧붙였다. 

퍼블릭 클라우드 부문에서도 쿠버네티스는 인기가 많다. 데이터독은 “자사 집계에 의하면 애저에서 컨테이너를 운용하는 데이터독 고객 중 약 80%가 현재 쿠버네티스를 사용한다”라고 말했다. 

하지만 인기를 얻는 만큼이나 원치 않는 유명세를 치르기 마련이다. 이를테면 윈도우 사용자라면 잘 알겠지만 프로그램의 인기가 높을수록 공격받을 확률은 올라간다. 쿠버네티스도 마찬가지다. 쿠버네티스를 사용한다면 보안에 만전을 기해야 한다. 물론 쉽지 않다.

최근 쿠버네티스를 관장하는 CNCF(Cloud Native Computing Foundation)는 보안 업체 트레일 오브 비츠(Trail of Bits), 아트레디스 파트너스(Atredis Partners)에 보안 감사를 요청했다. 

트레일 오브 비츠는 “일부 구성 요소의 기본값 설정이 복잡하거나 운영 통제가 누락되는 등 쿠버네티스 구성 및 배포 측면에서 적지 않은 문제가 있다”라고 지적했다. 

정말 쉽지 않은 일이다. 그래도 노력을 멈출 순 없다. 여기서는 쿠버네티스를 안전하게 만드는 5가지 방법을 살펴본다.

1. 컨테이너 자체가 안전한지 확인한다
컨테이너가 엉망이라면 쿠버네티스 역시 안전할 수 없다. 지난해, 보안 업체 스니크(Snyk)는 가장 인기 있는 도커 이미지 10종을 분석한 보고서를 공개한 바 있다. 보고서에 따르면 모든 이미지가 취약한 시스템 라이브러리를 포함하고 있다는 사실이 드러났다. 

VM웨어 부사장 겸 최고 오픈소스 책임자(COSO) 더크 혼델은 2019년 오픈소스 리더십 서밋(Open Source Leadership Summit)에서 “컨테이너 패키징 형식은 윈도우의 .exe, 맥OS의 .dmg와 비슷하다. 기본적으로 모든 종속성이 포함된 전체 파일 시스템을 제공한다. 컨테이너에도 종속성이 포함돼 있기 때문에 출처를 비롯해 생성된 방법, 상응하는 소스 등 바이너리를 검토해야 한다”라고 언급했다.

다시 말해, 쿠버네티스에 배포하기 전에 컨테이너 콘텐츠를 신뢰할 수 있는지 확인해야 한다는 뜻이다. 그렇지 않으면 컴퓨터 업계에서 흔히 언급하는 ‘쓰레기가 들어가면 쓰레기가 나온다(Garbage in, garbage out)’라는 문제점에 직면하게 될 것이다. 

모든 프로덕션 컨테이너에 잠재적인 보안 문제가 없는지 반드시 확인해야 한다. 아주 힘든 일이다. 보안은 원래 쉬운 일이 아니다.

2. 컨테이너 리눅스 커널의 보안을 확보한다
컨테이너 외에도 커널이 안전한지 확인해야 한다. 모든 컨테이너가 하나의 리눅스 커널에서 실행되기 때문이다. 이는 리눅스 커널 보안 모듈인 AppArmor나 SELinux로 보안을 확보하는 것을 의미한다. 

리눅스 보안 모듈은 강제적인 접근 통제 아키텍처를 적용해 사용자 제어, 프로그램, 파일 액세스, 시스템 서비스 등을 제한한다. 이는 리눅스의 기본 보안 모델(명시적으로 금지한 경우를 제외한 모든 것을 허용)과는 근본적으로 다르다. 명시적으로 허용한 경우를 제외한 모든 것을 금지하기 때문이다.

이 때문에 많은 시스템 관리자가 설정(setting)에 어려움을 겪고 있다. 설정이 잘못된 경우에 닫았어야 할 보안창을 열어 두는 문제만 발생하는 것이 아니기 때문이다. 리눅스 시스템이 정지되면서 처음부터 다시 설정해야 할 수도 있다. 또는 제대로 설정했다고 생각했지만 컨테이너가 공격에 노출된 상태일 수도 있다. 

AppArmor 혹은 SELinux로 보호된 커널에서 애플리케이션을 실행하는 데 문제가 있을지도 모른다. 기본 운영체제는 보안 측면에서 자유로운 프로그램이 너무 많다. 이 보호된 커널들은 이러한 자유를 허용하지 않는다.

커널이 커널 모듈을 자동 로드하지 못하도록 차단해 일정 수준 보호를 받을 수 있다. 예를 들면 권한 없는 프로세스도 특정 네트워크 소켓을 만들어 일부 네트워크 프로토콜 관련 커널 모듈을 강제로 로드할 수 있기 때문에 의심스러운 모듈을 차단하는 규칙을 추가해야 한다. 금지된 모듈 구성 파일에서 다음의 작업을 진행하라. 

/etc/modprobe.d/kubernetes-blacklist.conf

여기에 다음의 명령을 집어넣는다.

# SCTP is not used in most Kubernetes clusters, and has also had
# vulnerabilities in the past.
blacklist sctp


하기 싫어도 피할 순 없다. 이를 악물고 AppArmor나 SELinux를 설치하라. 

3. 역할 기반 액세스 제어(RBAC)를 사용한다
쿠버네티스 버전 1.8부터 RBAC로 ‘사용자가 할 수 있는 일’을 통제할 수 있다. 이는 중요하다. 수십 개의 인스턴스와 클러스터를 실행시키는 사용자들을 통제하기란 어려운 일이기 때문이다. 

제로 트러스트 보안 방식인 RBAC를 사용하면 앱과 노드와 같은 구성 요소 그리고 사용자는 주어진 것보다 많은 권한을 얻지 못한다. 

RBAC는 API 레벨에서 작동한다. 이런 방식으로 RBAC 규칙은 권한 부여자 자체가 사용되지 않는 경우에도 사용자를 제한한다. 또 RBAC는 사용자가 역할 또는 역할 바인딩을 수정하여 자신에게 더 많은 권한을 부여하지 못하도록 차단한다. 

외부인 역시 차단하도록 기본 설정돼 있다. RBAC 정책은 제어 영역 구성 요소, 노드 및 컨트롤러에 범위가 지정된 권한을 부여한다. 그러나 쿠버네티스 시스템 네임스페이스 외부의 서비스 계정에는 권한을 주지 않는다(중요한 부분이다).

한편 쿠버네티스 RBAC를 쉽게 관리할 수 있도록 사전 정의된 역할들이 제공된다. 덕분에 개발자와 운영자, 클러스터 관리자는 필요한 권한만 가져와 적용할 수 있다.

이 시스템에서 클러스터 관리자의 역할은 유닉스와 리눅스에서 가장 강력한 권한을 갖는 ‘슈퍼유저(superuser)’와 동일하다. 클러스터 관리자는 모든 클러스터 리소스를 생성, 편집, 삭제할 수 있다. 즉 클러스터 관리자 역할에 대한 액세스를 신경 써서 보호해야 한다. 그렇다면, 이제 다음 단계로 넘어가 보자. 

4. 안전하게 유지하기란 힘든 일이다 
쿠버네티스 시크릿(Kubernetes Secrets)을 사용하면 비밀번호, OAuth 토큰, ssh 키 등 민감한 정보를 저장하고 관리할 수 있다. 이 민감한 정보는 이른바 ‘쿠버네티스 왕국’을 열 수 있는 열쇠이며, 반드시 보호돼야 할 대상이다. 

쿠버네티스는 API 액세스를 위해 시크릿을 자동 생성하고, 이를 사용하도록 포드(pods)를 수정한다. 그러나 포드가 데이터베이스에 액세스하는 데 필요한 이름과 비밀번호 같은 시크릿의 관리와 보호는 사용자가 책임져야 한다. 

간단한가? 유감스럽게도 쿠버네티스 시크릿에는 보안 취약점이 많다. 공식적으로 발표된 보안 취약점 목록을 보면 겁이 날 정도다.

• API 서버에서 시크릿 데이터는 쿠버네티스의 기본 분산형 키-값 저장소인 ‘etcd’에 저장된다. 기본적으로 etcd 데이터는 암호화되지 않는다. 즉 시크릿도 암호화되지 않는다는 뜻이다. 따라서 보관 시 암호화 기능을 활성화하고, etcd 액세스를 관리자급 사용자로 제한해야 한다.

• 많은 사용자가 시크릿을 JSON(JavaScript Object Notation)이나 YAML로 보관한다. 여기서 시크릿은 base64 문자열로 인코딩되지만, 암호화되진 않는다. 즉 파일을 공유하거나 소스 리포지토리에 체크인할 경우 자신의 시크릿을 공개하는 것이나 다름없다. 

• 애플리케이션이 특정 시크릿을 사용하면, 해당 앱은 이를 기록할 수 없고 신뢰할 수 없는 사람에게 전송할 수 없다. 

• 시크릿을 사용하는 동시에 포드를 생성할 수 있는 사용자는 시크릿값을 볼 수 있다. API 서버 정책에서 해당 사용자가 이를 읽는 것을 허용하지 않더라도 사용자는 포드를 실행할 수 있으며, 이는 시크릿을 노출시킨다.

• 현재 모든 노드에 관한 루트 권한을 가진 사람은 kubelet을 가장해 API 서버의 모든 시크릿을 읽을 수 있다. 이는 실제 기능이다. 오직 노드와 시크릿을 공유할 수 있게 만들어 루트 공격의 피해를 단일 노드로 제한하겠다는 개념이다. 


그다지 좋지 않은 상황이다. 위험을 완화하려면 가능할 때마다 시크릿을 암호화해야 한다. 또한 시크릿을 이미지나 포드에서 분리해 보관한다. 이를 위해서는 프로세스를 별개 컨테이너로 분할해야 한다. 

이를테면 한 애플리케이션을 프론트엔드 컨테이너와 백엔드 컨테이너로 분리할 수 있다. 백엔드에 개인 키라는 시크릿이 있으며, 프론트엔드의 로그인 요청에 응답한다.

이 밖에 서드파티 시크릿 도구로 시크릿을 보호해야 한다. 퍼블릭 클라우드의 경우 AWS 시크릿 매니저(AWS Secrets Manager), 구글 클라우드 플랫폼 KMS(Google Cloud Platform KMS), 애저 키 볼트(Azure Key Vault) 등이 있다. 그리고 기업용으로는 해시코프 볼트(Hashicorp Vault), 사이버아크/컨저(CyberArk/Conjur), 컨피던트(Confidant), 아쿠아 시큐리티 쿠버네티스 시큐리티(Aqua Security Kubernetes Security) 등의 프로그램이 있다. 

5. 네트워크를 안전하게 보호한다
위 내용에서 짐작할 수 있듯 etcd 액세스를 허용하는 것은 위험하다. 쿠버네티스 보안 업체 컨트롤플레인(ControlPlane)의 공동창업자 앤드류 마틴은 “API 서버의 etcd에 대한 쓰기 액세스는 전체 클러스터에서 루트 권한을 얻는 것과 동일하다. 심지어 읽기 액세스까지 사용해 쉽게 권한을 올릴 수 있다”라고 지적했다. 

이어서 그는 “따라서 피어 및 클라이언트 TLS 인증서로 etcd가 구성돼야 하며, 전용 노드에 배포돼야 한다. 작업자 노드에서 개인 키를 훔쳐 사용하는 것을 막기 위해 클러스터의 API 서버 액세스를 방화벽으로 차단할 수 있다”라고 덧붙였다. 개인적으로 볼 때는 ‘할 수 있다’가 아닌 ‘반드시 해야 한다’가 돼야 한다. 

네트워크 보호가 필요한 것은 etcd에 국한되지 않는다. 쿠버네티스는 API 기반이며, 모든 내부 클러스터 통신은 기본적으로 TLS로 암호화돼 있다. 하지만 이것으로는 부족하다. 쿠버네티스 포드가 모든 소스의 트래픽을 수신하도록 기본 설정돼 있기 때문이다. 

다시 말하지만 ‘모든 소스’다. 포드는 네트워크 연결에 광범위하게 개방돼 있고, 이는 안전하지 않다. 포드가 클러스터 내에서 그리고 외부 리소스와 커뮤니케이션하는 방식을 안전하게 정의하는 네트워크 정책을 정의해야 할 필요가 있다. 

네트워크 정책 컨트롤러를 지원하는 네트워킹 플러그인을 추가해 해당 작업을 진행할 수 있다. 이러한 컨트롤러가 없다면 설정한 네트워크 정책이 적용되지 않는다. 

안타깝게도 쿠버네티스에는 기본 탑재돼 있거나, 선택할 수 있는 네트워크 정책 컨트롤러가 없다. 칼리코(Calico), 실리움(Cilium), 쿠버라우터(Kube-router), 로마나(Romana), 위브넷(Weave Net)과 같은 서드파티 플러그인을 사용해야 한다. 

또한 ‘우선 차단(default-deny-all)’ 네트워크 정책으로 시작하라고 권고하고 싶다. 그렇게 하면 다른 네트워크 정책과 함께 명시적으로 허용하는 연결만 승인될 것이다. 

네트워크 정책은 네임스페이스에 설정돼야 하므로 네임스페이스에 따라 네트워크 정책을 설정해야 한다. 설정이 완료되면 적절한 네트워크 액세스 규칙을 적용할 수 있다. 먼저 쿠버네티스 네트워크 정책 가이드(Kubernetes Network Policy Recipes)를 참조하는 것이 좋다.

쿠버네티스 보안은 중요하다
앞서 언급한 것처럼 쿠버네티스를 안전하게 만드는 것은 쉬운 일이 아니다. 이 글을 읽었다면 모두 동의하리라 생각한다.

쿠버네티스는 처음부터 쉽게 배포할 수 있도록 설계됐다. 이를 다른 말로 하자면 설계상 안전하지 않다는 의미다. 그리고 쿠버네티스 클러스터가 제 기능을 하도록 보안을 확보하는 것은 사용자의 몫이라는 뜻이다. 

여기서는 쿠버네티스 보안에서 반드시 다뤄야 할 가장 중요한 문제만 간략히 언급했다. 이 밖에도 다른 문제가 많지만 무엇보다도 ‘쿠버네티스 보안’이 얼마나 중요한 일인지 인식하길 바란다. 

그렇다. 기업 자산이 공격에 노출되기 전에, 지금 당장 쿠버네티스 보안을 시작해야 한다. ciokr@idg.co.kr
 

X