안녕하세요. 이번 글에서는 최근 CNCF에서 졸업한 cert-manager라는 Kubernetes 내부 TLS 인증서 관리 프로젝트에 대해 살펴보면서, TLS 인증서에 대해서도 알아보겠습니다.

📜TLS 인증서가 무엇인가요?

Kubernetes 내부에서 배포된 여러 서비스가 서로 통신할 때, 암호화되지 않은 HTTP보다 보안 측면에서 우수한 HTTPS를 사용하는 경우가 많은데요. 이건 실생활에서 사용되는 대부분의 웹 서비스도 마찬가지입니다.

(우리가 사용하는 웹 브라우저에서도 HTTPS를 사용하는 안전한 페이지는 위 사진과 같이 확인할 수 있습니다.)

HTTPS는 기존 HTTP에 TLS라는 프로토콜을 사용해서 암호화한 것으로, 이 TLS 덕분에 HTTPS는…

  • 외부의 제3자가 전송되는 데이터를 보지 못하게 숨기고, (암호화)
  • 정보를 교환하는 당사자가 실제로 요청된 당사자임을 보장하며, (인증)
  • 전송하는 데이터가 위조되거나 변조되지 않았음을 확인 가능하게 됩니다. (무결성)

이렇게 TLS가 보안 관점에서 뛰어난 이유는 인증서라는 개념을 사용하기 때문인데요. 인증서는 아래와 같은 역할을 합니다.

  • 클라이언트(요청을 하는 쪽)에서 접근하려는 서버(요청을 받는 쪽)가 신뢰할 수 있는 서버임을 보증
  • 통신 중 암호화할 때 사용하는 정보를 클라이언트에게 전달

인증서에는 해당 서버에 대한 도메인 정보와 통신 중 암호화할 때 사용할 정보(정확히는 서버의 공개 키입니다.)가 담겨있는데요. 이 인증서는 서버가 가지고 있다가, 클라이언트가 해당 서버에게 요청을 하면 서버가 클라이언트에게 전달합니다.

클라이언트는 서버로부터 받은 인증서를 이용해서 해당 서버가 신뢰할 수 있는지 확인하고, 이후 해당 서버와 통신할 때 인증서에 포함된 서버의 공개 키를 이용하여 암호화 통신을 할 수도 있는 거죠.

이 인증서를 TLS 프로토콜을 사용한 인증서라고 해서 TLS 인증서라고 불립니다.

❔신뢰할 수 있는 서버인 것을 어떻게 TLS 인증서로 알 수 있나요?

TLS 인증서는 서버가 아닌 별도의 주체가 발급하는데요. 일반적으로 CA(Certificate Authority)라고 하는 공인된 기관에서 TLS 인증서를 발급합니다.

서버가 자신의 정보와 공개 키를 CA로 보내 인증서 생성을 요청하면, CA는 CA의 비공개 키를 이용해서 서버가 보낸 도메인 정보와 서버의 공개 키를 암호화함으로써 인증서를 생성한 다음에 서버로 전달합니다.

클라이언트가 해당 서버에 연결을 시도할 때, 서버로부터 TLS 인증서를 받는다고 했었죠. 이 TLS 인증서는 CA의 비공개 키로 암호화되어 있는데요.

CA의 공개 키는 누구에게나 공개되어 있기 때문에 클라이언트는 TLS 인증서를 CA의 공개 키로 복호화 시도를 할 것이고, 만약 TLS 인증서 복호화에 성공하면 해당 인증서는 CA가 발급한 진짜 인증서라는 뜻이겠죠.

이 과정으로 해당 서버가 신뢰할 수 있음을 TLS 인증서를 통해 알 수 있는 것입니다.

TLS 인증서에 대해 살펴보다보니… 은근슬쩍 공개 키와 비공개 키라는 개념이 새로 등장했는데요. TLS 인증서에서 공개 키와 비공개 키, 또는 비대칭 암호화 방식이라고 하는 개념은 뗄 수 없는 관계이다보니 가볍게 짚고 가겠습니다.

주고 받는 데이터를 암호화하는 방식 중 하나인 비대칭 암호화 방식은, 한 쌍의 공개 키와 비공개 키를 가지고 데이터를 암호화할 수 있습니다. 이 방식은…

  • 공개 키로 암호화한 데이터같은 쌍의 비공개 키로 풀 수 있고,
  • 비공개 키로 암호화한 데이터같은 쌍의 공개 키로 풀 수 있는 건데요.

이렇게 데이터 암호화와 복호화에 두 가지 키를 사용하기 때문에 더 안전하다는 장점과 더불어 특징이 한 가지 더 있습니다. 암호화를 공개 키로 하느냐, 비공개 키로 하느냐에 따라 사용되는 분야가 달라진다는 점인데요.

위에서 살펴봤던 TLS 인증서 사용 과정을 다시 보면, 비대칭 암호화를 사용하는 방식이 두 가지로 나뉩니다.

  • CA가 자신의 비공개 키로 암호화한 인증서를 클라이언트가 CA의 공개 키로 복호화하여 CA가 발급한 인증서임을 확인
  • 클라이언트가 인증서에 포함된 서버의 공개 키로 통신을 암호화하여 서버로 전송 (이후 서버가 자신의 비공개 키로 복호화)

즉, 비공개 키로 암호화한 경우에는 인증에 중점을 둔 것이고, 공개 키로 암호화한 경우에는 데이터 보안에 중점을 둔 것이라고 할 수 있습니다.

지금까지 알아본 TLS 인증서를 Kubernetes 클러스터 내에서 쉽게 발급하고 서비스가 사용할 수 있도록 관리 가능한 것이 바로, 맨 위에서 이야기했던 cert-manager입니다.

🔎cert-manager가 k8s 내부에서 TLS 인증서를 어떻게 관리하나요?

cert-manager는 두 가지 CRD(Custom Resource Definition, k8s에서 커스텀으로 제작한 리소스 정의)를 사용하는데요. 바로, IssuerCertificate입니다.

IssuerKubernetes 클러스터 내에서 사용할 TLS 인증서를 발급해주는 리소스입니다. 위에서 살펴봤던 CA와 같은 역할을 수행하는데요.

외부에 이미 존재하는 CA와 연동된 Issuer Type들이 이미 개발되어 있기 때문에 이걸 사용할 수도 있고, 클러스터 내부에서 직접 서명하는 Issuer Type을 사용해서 Issuer 리소스를 배포할 수 있습니다.

다음은 Certificate입니다. Issuer가 발급할 인증서에 대해 정의하는 리소스인데요. 인증서 대상 도메인과 유효 기간, 갱신 시점 등을 정의한 Certificate 리소스를 배포하면, 미리 배포되어 있던 Issuer 리소스가 이를 감지하여 서명한 인증서와 키 정보 등을 Kubernetes Secret 리소스로 저장합니다.

이렇게 cert-manager는 Kubernetes 내에서 사용할 인증서를 쉽게 발급 및 관리할 수 있다는 특징 덕분에 사용자도 점점 더 많아지고 있는데요. 최근 CNCF에서 졸업을 달성했기 때문에 이후 더 많은 적용 사례가 기대되는 프로젝트입니다.

References