Skip to content

플랫폼 엔지니어링

eMudhra CA 침해: Kubernetes 노드 패치만으로는 충분하지 않은 이유

eMudhra 침해가 Kubernetes 노드, 컨테이너 이미지, 애플리케이션 런타임, CA 번들에 어떤 영향을 미치는지, 그리고 각 계층에서 어디를 업데이트해야 하는지 설명합니다.

Todea Engineering

클라우드 네이티브 실무

21 분 소요
#kubernetes#security#pki#tls#supply-chain#platform-engineering
eMudhra CA 침해: Kubernetes 노드 패치만으로는 충분하지 않은 이유

2026년 10월, 인증 기관인 eMudhra가 인증서 서명용 개인 키 8개를 무작위 384비트 값이 아니라 1바이트 숫자(4, 56, 66, 115, 155, 156, 230, 237)로 생성했다는 사실을 한 연구자가 발견했습니다. 이 때문에 누구나 공개된 CA 인증서에서 1초도 안 되는 시간에 개인 키를 복구할 수 있었습니다. 영향을 받는 TLS 서명 키를 복구한 사람은 자신이 통제하지 않는 도메인의 인증서를 발급할 수 있습니다. 여기에 트래픽까지 가로채거나 우회시킬 수 있는 공격자는, 침해된 발급자를 여전히 신뢰하는 클라이언트를 상대로 정상 서비스를 사칭할 수 있습니다. 사용 중인 인증서가 eMudhra에서 발급된 것이 아니더라도 연결은 위험에 노출될 수 있습니다. 클라이언트가 위조된 인증서를 수락하면, 공격자는 해당 연결로 전송되는 자격 증명과 요청 데이터를 받아 보고 변조된 응답을 돌려줄 수 있습니다.

주요 브라우저에는 영향을 받는 인증서를 차단하는 업데이트가 배포되었지만, 그 보호가 Kubernetes까지 자동으로 적용되지는 않습니다. 노드, 컨테이너 이미지, 애플리케이션 런타임, 클러스터 구성은 저마다 신뢰할 인증서를 제공하거나 자체 검증 규칙을 적용할 수 있습니다. 어디를 조치해야 하는지는 실행 중인 구성 요소가 실제로 무엇을 사용하는지에 따라 달라집니다.

Kubernetes는 신뢰 정보를 어디에 두는가

Kubernetes 클러스터는 하나의 공유 트러스트 스토어를 사용하지 않습니다. 컨테이너 런타임은 보통 노드의 인증서에 의존하고, 애플리케이션은 이미지 안에 자체 번들을 포함할 수 있으며, 언어 런타임이 또 다른 인증서 집합을 제공하기도 합니다. 추가 CA 번들을 Kubernetes 구성에 저장해 워크로드에 마운트할 수도 있습니다.

이 사본들은 각각 따로 업데이트됩니다. 또한 실행 중인 프로세스는 업데이트 이전에 로드한 인증서를 계속 유지할 수 있으므로, 파일을 수정했다고 해서 애플리케이션의 신뢰 판단까지 바로잡히는 것은 아닙니다. 이어지는 섹션에서는 각 계층에서 무엇을 업데이트해야 하는지, 그리고 언제 재시작이나 다시 로드가 필요한지 설명합니다.

이번 문제는 영향을 받는 퍼블릭 발급자를 신뢰하는 연결에 해당합니다. 프라이빗 클러스터 CA나 메시 CA만 신뢰하도록 제한된 연결은 이번 사고로 자동으로 노출되지 않습니다.

아래 다이어그램은 일반적인 이미지 가져오기와 애플리케이션 연결을 비교합니다. 애플리케이션은 TLS 구성에 따라 표시된 소스 중 하나 이상을 사용할 수 있습니다.

노드의 신뢰 정보와 워크로드의 신뢰 정보는 서로 다른 경로로 업데이트됩니다. 실행 중인 각 클라이언트는 변경된 인증서를 다시 로드해야 합니다.

1. 노드: 컨테이너 런타임과 컨트롤 플레인

Kubernetes가 이미지를 내려받을 때, kubelet은 containerd나 CRI-O 같은 컨테이너 런타임에 이미지를 가져오도록 요청합니다. 런타임은 레지스트리에 연결하고, 노드가 신뢰하는 CA를 사용해 레지스트리의 HTTPS 인증서를 검증합니다. containerd나 CRI-O에 구성한 레지스트리 전용 CA는 그 풀을 대체하는 것이 아니라 풀에 추가되므로, 해당 레지스트리에도 노드 번들이 그대로 적용됩니다.

그 신뢰 구성이 침해된 발급자를 여전히 수락한다면, 네트워크 경로상의 공격자가 레지스트리를 사칭할 수 있습니다. 이는 워크로드가 시작되기 전에 일어나는 일이므로, 워크로드 이미지 안의 인증서를 업데이트해도 다운로드는 보호되지 않습니다.

배포판의 CA 업데이트를 설치하거나, 수정된 노드 이미지로 노드를 교체하세요. 그런 다음 이전 인증서를 캐시하고 있는 관련 프로세스를 재시작합니다. 여기에는 컨테이너 런타임과 관련된 노드 및 컨트롤 플레인 구성 요소가 포함됩니다. 새로 시작한 진단 도구는 업데이트된 번들을 사용하더라도, 오래 실행 중인 서비스는 여전히 이전 번들을 사용하고 있을 수 있습니다.

컨트롤 플레인에도 주의가 필요합니다. kubeadm 클러스터에서는 API 서버와 컨트롤러 매니저가 노드의 인증서 디렉터리를 마운트합니다. 이 저장소들은 외부 HTTPS 연결에 사용될 수 있습니다. 예를 들어 어드미션 웹훅 구성에 명시적인 caBundle이 없으면 API 서버는 시스템 루트 인증서를 사용합니다. 번들이 지정되어 있다면 그 번들은 별도로 검토해야 합니다.

kubeadm 컨트롤 플레인 구성 요소에는 지원되는 정적 파드 재시작 절차를 사용하세요. API로 미러 파드 오브젝트를 삭제해도 실제 컨테이너는 재시작되지 않습니다. 다중화된 컨트롤 플레인은 한 번에 한 노드씩 진행하고, 다음 노드로 넘어가기 전에 준비 상태를 확인하세요.

아울러 인증서 검증 수정이 포함된 Kubernetes 및 런타임 릴리스 가운데 해당하는 것을 배포하세요. 매니지드 Kubernetes에서는 컨트롤 플레인과 노드 이미지 롤아웃에 대한 제공업체의 안내를 따르세요. 제공업체의 업데이트가 애플리케이션 이미지나 커스텀 CA 번들을 자동으로 교체해 주지는 않습니다.

2. 이미지: 컨테이너 자체의 트러스트 스토어

노드의 CA 번들을 업데이트해도 그 노드에서 실행되는 컨테이너 이미지 안의 인증서는 업데이트되지 않습니다. 많은 이미지가 자체 /etc/ssl/certs를 포함하고 있으며, 여기에는 이미지를 빌드할 때 설치된 인증서가 들어 있습니다.

연구자의 공개 사이트는 영향을 받는 발급자의 인증서를 제시하는 테스트 엔드포인트를 제공합니다. 다음 명령은 특정 curl 이미지를 사용해 emSign 엔드포인트를 확인합니다.

kubectl run curl --image=curlimages/curl:8.22.0 --restart=Never --rm -i -- \
  -sS -o /dev/null -w '%{http_code}\n' https://dv-g3b-emudhra.we-have-a-problem.com/

아래 비교에서는 CA 패키지를 업데이트한 동일한 노드에서 두 개의 이미지를 사용했습니다.

curlimages/curl:8.22.020260611-r0수락: HTTP 200
curlimages/curl:8.23.020261020-r0거부: curl: (60)

이전 이미지는 자체 번들이 수정 이전의 것이기 때문에 영향을 받는 인증서를 여전히 수락합니다. 직접 관리하는 이미지는 CA 패키지를 업데이트한 뒤 다시 빌드하고 재배포하세요. 벤더 이미지는 수정이 포함된 릴리스를 사용하고, 실행 중인 파드가 해당 릴리스로 전환되었는지 확인하세요.

이 명령이 확인하는 것은 curl의 신뢰 구성입니다. 같은 컨테이너 안의 애플리케이션은 다른 번들이나 런타임을 사용할 수 있으며, 이 엔드포인트를 거부한다고 해서 다른 모든 인증서 체인이 차단된다는 증거가 되지는 않습니다.

3. 런타임: 애플리케이션의 인증서 검증

애플리케이션이 항상 이미지의 /etc/ssl/certs를 사용하는 것은 아닙니다. 일부 런타임은 자체적으로 신뢰하는 인증서를 포함합니다. 또 어떤 런타임은 트러스트 스토어에 영향을 받는 루트 인증서가 남아 있더라도 침해된 서명 키를 거부하는 코드를 포함하고 있습니다.

Kubernetes의 컨트롤 플레인 구성 요소와 많은 컨트롤러가 Go로 작성되어 있기 때문에 Go는 특히 중요합니다. Go 1.27.3과 1.26.10은 침해된 키가 포함된 인증서 체인을 거부하는 차단 목록을 crypto/x509에 추가했습니다.

세 가지 Go 버전으로 빌드한 테스트 클라이언트가 그 차이를 보여 줍니다. 동일하게 오래된 CA 번들을 사용했을 때의 결과는 다음과 같습니다.

go1.26.9수락수락
go1.26.10거부: x509: no valid chains built수락
go1.27.3거부: x509: no valid chains built수락

업데이트된 클라이언트는 영향을 받는 인증서를 거부하면서도 대조용 연결은 계속 수락합니다. 이 보호는 애플리케이션에 컴파일되어 포함됩니다. 패치된 툴체인으로 빌드된 릴리스를 배포하거나, 직접 다시 빌드해 재배포하세요. go.mod에 선언된 버전만으로는 배포된 바이너리를 어떤 툴체인이 빌드했는지 알 수 없습니다. 바이너리의 빌드 메타데이터와 실제 동작을 함께 확인하세요.

Java, Node.js, Python, Rust 애플리케이션도 런타임별 확인이 필요합니다. 런타임의 보안 안내와, Python의 certifi처럼 별도로 번들된 CA 패키지를 검토하세요. 운영체제의 인증서를 업데이트한다고 해서 이러한 사본까지 업데이트되는 것은 아닙니다.

4. 클러스터 구성: Kubernetes 오브젝트 안의 CA 번들

Kubernetes 오브젝트에는 워크로드와 컨트롤러가 연결을 검증하는 데 사용하는 CA 번들이 들어 있을 수 있습니다. 노드나 컨테이너 이미지를 업데이트해도 이렇게 저장된 사본은 교체되지 않습니다.

애플리케이션이 신뢰할 인증서를 전달받는 위치를 검토하세요.

  • ConfigMap과 Secret: Argo CD의 argocd-tls-certs-cm, ca.crt가 들어 있는 Secret, Istio나 Kasten이 참조하는 번들 등.
  • Kubernetes API 구성: 어드미션 웹훅, APIService, CRD 변환 웹훅에 들어 있는 CA 번들 등.
  • 애플리케이션 구성: 커스텀 리소스와 Helm values의 CA 설정, trust-manager가 배포하는 번들 등.

해당 루트 인증서를 식별하려면 이 공개 사이트의 영향을 받는 루트 인증서 목록에 있는 SHA-256 인증서 지문을 사용하세요. 명시적으로 신뢰하도록 설정한, 영향을 받는 중간 CA 인증서도 검토하세요. 같은 종류의 Kubernetes 오브젝트에 저장되어 있다는 이유만으로, 관련 없는 프라이빗 클러스터 또는 메시의 트러스트 앵커를 삭제하지 마세요.

trust-manager를 사용한다면 기본 CA 패키지와 리포지토리 또는 태그 재정의 여부를 확인하세요. v0.25.0까지의 차트는 기본적으로 영향을 받는 패키지를 설치하며, v0.26.0은 수정된 패키지를 설치합니다. 기본 패키지를 업데이트해도 추가 Bundle 소스를 통해 제공되는, 영향을 받는 인증서는 제거되지 않습니다.

사용 가능한 수정 사항과 업그레이드 안내

아래 표는 2026년 11월 9일 기준 스냅샷에 따라 Kubernetes 구성 요소, 매니지드 클러스터, 클라우드 네이티브 도구에 필요한 조치를 정리한 것입니다. 롤아웃을 계획하기 전에, 링크된 각 프로젝트의 안내에서 더 새로운 버전이 있는지 확인하세요. 커스텀 번들, 헬퍼 프로그램, 그 밖의 이미지 변형은 여전히 별도의 확인이 필요합니다.

Kubernetes와 컨테이너 런타임

Kubernetesv1.37.2, v1.36.6, v1.35.10 또는 과거 버전용 수정인 v1.34.13을 사용하세요. 지원되는 마이너 릴리스를 우선 사용하세요. 노드의 트러스트 스토어는 별도로 업데이트하세요. 바이너리를 업데이트해도 이미지에서 인증서가 제거되지는 않습니다.
containerd배포판의 CA 업데이트를 설치하고 containerd를 재시작하세요. 가능하다면 Docker의 containerd.io 2.4.2-3처럼 수정된 Go로 다시 빌드된 벤더 패키지를 사용하세요. 더 새로운 버전을 선택하기 전에 업스트림 릴리스 노트를 확인하세요.
CRI-O노드의 CA 패키지를 업데이트하고 CRI-O를 재시작하세요. 수정된 벤더 빌드 또는 지원되는 브랜치의 다음 패치 릴리스를 사용하세요. OpenShift 사용자는 Red Hat의 롤아웃 안내를 따라야 합니다.
etcd해당 브랜치의 v3.7.3, v3.6.16 또는 v3.5.35를 사용하세요. 커스텀 CA 구성과, 이미지의 CA 번들을 사용하는 추가 프로그램이 있는지 검토하세요.
k3drancher/k3s:v1.37.2-k3s1과 같은 수정된 k3s 이미지, 또는 사용 중인 마이너 버전에 맞는 패치 릴리스를 명시적으로 지정하세요. 이렇게 하면 노드는 업데이트되지만, k3d CLI 자체의 TLS 검증은 업데이트되지 않습니다.
k3s, RKE2k3s v1.37.2+k3s1, v1.36.6+k3s1, v1.35.10+k3s1 또는 이에 대응하는 RKE2 +rke2r1 릴리스를 사용하세요. 과거 1.34용 수정 버전도 있지만, 지원이 끝난 브랜치는 유지 관리되는 버전으로 옮기세요.

매니지드 Kubernetes

제공업체의 업데이트가 출시되었다고 해서 그 업데이트가 내 클러스터에 적용되었다는 뜻은 아닙니다. 컨트롤 플레인, 노드 이미지, 롤아웃 상태를 확인한 다음, 고객이 직접 관리하는 워크로드는 별도로 조치하세요.

Amazon EKS관리형 노드, 자체 관리형 노드, Karpenter 노드를 패치된 AMI로 교체하세요. AWS는 AL2023 v20261023을 트러스트 스토어 수정 버전으로 안내하지만, 스냅샷은 containerd 추가 재빌드가 포함된 v20261031을 권장합니다. Bottlerocket은 v1.68.0 이상을 사용하고, Auto Mode의 노드 교체가 완료되었는지 확인하세요.
Google GKEGoogle 보안 게시판에 명시된 컨트롤 플레인 및 노드 버전을 그대로 사용하세요. 기록된 스냅샷 시점에는 1.33, 1.36, 1.37용 Ubuntu 수정이 아직 제공되지 않았습니다. 제공업체가 지원하는 수동 업그레이드 경로를 따르고, 애플리케이션 이미지는 별도로 다시 빌드하세요.
Azure AKS노드 이미지 업그레이드 절차를 사용해 Linux 노드 풀을 이미지 202610.23.0 또는 그 이후의 패치된 이미지로 교체하세요. 특히 자동 업데이트가 제한된 환경에서는 Windows 노드가 업데이트된 인증서 신뢰 목록을 받았는지 확인하세요.
Red Hat OpenShift사용 중인 마이너 버전과 이용 가능한 업데이트 채널에 맞는 수정된 z-stream을 선택하세요. 해당하는 경우 4.21의 4.21.41처럼 다시 빌드된 CRI-O가 포함된 버전을 선택하세요. machine-config 롤아웃이 완료되는지 확인하세요. 4.x 권고만 보고 5.x도 조치되었다고 추정하지 마세요.
IBM CloudRHCOS 지원이 포함된 11월 2일자 워커 수정 팩을 적용하세요. 그보다 앞선 10월 27일자 팩은 Ubuntu와 RHEL 9 워커를 대상으로 합니다. 모든 워커가 업데이트되거나 교체되었는지 확인하세요.
Nebius노드 그룹을 인프라 버전 78 또는 그 이후의 패치된 버전으로 업그레이드한 뒤, 교체된 노드를 확인하세요. 애플리케이션 이미지와 마운트된 CA 번들은 여전히 별도로 업데이트해야 합니다.
Oracle OKE노드의 패키지가 해당하는 Oracle Linux 권고(경우에 따라 ELSA-2026-88550 또는 ELSA-2026-88459)와 일치하는지 확인하세요. 이미지의 빌드 날짜가 11월이라는 사실만으로 조치가 완료되었다고 판단하지 마세요.
Alibaba ACK노드 OS용 수정된 ca-certificates 패키지를 확인하고, ACK가 지원하는 업데이트 또는 노드 교체 절차를 사용하세요. 인플레이스 업데이트 후에는 런타임을 재시작하세요. 새 이미지를 수정된 것으로 간주하기 전에 제공업체의 안내를 확인하세요.
DigitalOcean, Akamai, OVHcloud, Scaleway, Civo, Tencent어떤 노드 이미지와 매니지드 구성 요소에 수정이 포함되어 있는지 제공업체에 문의하세요. 실행 중인 노드의 패키지와 런타임을 확인한 다음, 지원되는 롤아웃 절차를 사용하세요. 공개된 권고가 없다는 사실만으로는 서비스가 취약한지, 수정되었는지 알 수 없습니다.
Naver Cloud, NHN Cloud, KT Cloud, Samsung SDS수정된 노드 이미지 또는 CA 패키지를 제공업체에 확인하고, 배포된 버전을 점검하세요. 필요한 경우 재시작을 포함해, 제공업체가 지원하는 롤아웃 절차를 사용하세요.

서비스 메시, 게이트웨이, 네트워킹

Istio스냅샷에 기재된 1.31.4 또는 1.30.8, 혹은 그 이후의 지원되는 패치를 사용하세요. 수정은 1.31.3과 1.30.7부터 포함되었습니다. egress용 커스텀 CA 번들은 별도로 확인하세요. 1.29.10에는 Go 차단 목록이 추가되지 않았습니다.
Linkerdedge-26.11.1 또는 그 이후의 패치된 edge 릴리스를 사용하고 CLI도 업데이트하세요. 트러스트 앵커에 자체 프라이빗 CA만 들어 있다면, 프라이빗 메시 mTLS는 퍼블릭 루트 인증서를 통해 노출되지 않습니다. 퍼블릭 CA를 사용하는 부분과 커스텀 번들은 별도로 검토하세요.
Buoyant Enterprise for Linkerd (BEL)지원되는 BEL 브랜치의 수정된 릴리스로 업그레이드하고 Buoyant의 롤아웃 안내를 따르세요. 커스텀 번들은 별도로 검토하세요. 프록시 의존성에 대한 탐지 결과만으로는, 프라이빗 메시 루트 인증서만 신뢰하는 메시 mTLS가 노출되었다고 볼 수 없습니다.
Envoy해당 브랜치의 v1.40.2, v1.39.6, v1.38.9 또는 v1.37.11을 사용하세요. trusted_ca로 제공하는 번들이 있다면 업데이트하세요. 이미지를 업데이트해도 해당 커스텀 번들은 교체되지 않습니다.
Envoy Gateway업그레이드 변경 사항을 검토한 뒤 v1.10.0을 사용하세요. v1.9.3 또는 v1.8.6에서는 distroless-v1.39.6이나 distroless-v1.38.9처럼 대응하는 수정된 Envoy 이미지를 구성하고 프록시를 롤아웃하세요.
Cilium지원되는 브랜치의 1.20.4, 1.19.10 또는 1.18.16을 사용하세요. 태그나 다이제스트 재정의를 포함해 agent, operator, cilium-envoy 이미지를 차트와 일치시키세요.
ConsulConsul, consul-k8s, consul-dataplane을 기재된 2.1.0 릴리스로 업그레이드하세요. terminating gateway에는 CAFile에 수정된 번들을 구성하고, 게이트웨이가 이를 로드하는지 확인하세요.
Kuma해당 브랜치의 3.0.1, 2.14.7, 2.13.12 또는 2.11.20을 사용하세요. 커스텀 Corefile이 DNS-over-TLS 포워딩을 사용한다면, CoreDNS 헬퍼의 TLS 검증과 트러스트 스토어를 별도로 검토하세요.
Traefik해당 브랜치의 v3.7.17 또는 v2.11.61을 사용하세요. v3.7.16에도 수정이 포함되어 있습니다. 오래된 이미지를 교체하고, 백엔드용 커스텀 CA 구성이 있다면 검토하세요.
NGINX Gateway Fabric2.8.1로 업그레이드하고, 컨트롤러와 NGINX 데이터 플레인 파드가 모두 업데이트된 이미지로 실행되는지 확인하세요. 업스트림 TLS에 사용하는 커스텀 CA 번들이 있다면 확인하세요.
ingress-nginx(지원 종료)유지 관리되는 컨트롤러로의 마이그레이션을 계획하세요. 마이그레이션하는 동안 업스트림 TLS 검증과 proxy-ssl-secret CA 번들을 검토하세요. 업스트림 인증서 검증을 비활성화해 둔 것은 이번 사고의 완화책이 아닙니다.
Kong Ingress Controller해당 브랜치의 KIC 3.5.14 또는 3.4.21을 사용하세요. Kong Gateway는 별도로 업데이트하고 커스텀 CA 번들을 검토하세요. 컨트롤러의 수정은 게이트웨이의 아웃바운드 연결에는 적용되지 않습니다.
Kong Gateway EnterpriseKong이 지원하는 구성(해당하는 경우 lua_ssl_trusted_certificate 포함)을 사용해 수정된 아웃바운드 CA 번들을 로드하세요. 관련된 모든 TLS 경로를 확인하고, 수정된 벤더 이미지가 제공되면 적용하세요.
ContourContour v1.33.8을 distroless-v1.38.9와 같은 수정된 Envoy 이미지와 함께 사용하세요. 제공한 CA Secret과 Envoy 신뢰 구성은 별도로 확인하세요. 컨트롤러에 번들이 없다고 해서 게이트웨이까지 조치된 것은 아닙니다.
Emissary-ingress해당하는 아웃바운드 TLS 연결에는 수정된 ca_secret을 사용하세요. 업그레이드하기 전에 수정된 안정 릴리스가 제공되는지 확인하세요. 4.2.0-rc.0에서 이미지의 CA 번들까지 수정되었다고 가정하지 마세요.
Calico v3.32 (tigera-operator v1.42)tigera-operator를 v1.42.7로 업그레이드해 수정된 구성 요소를 배포하거나, 매니페스트 기반 설치라면 v3.32.3 매니페스트를 적용하세요. 모든 Calico 이미지가 롤아웃되었는지 확인하세요.
Calico v3.33 (tigera-operator v1.44)다음 3.33 패치 릴리스를 추적하고, 그동안에는 지원되는 방법으로 실제 사용되는 CA 저장소를 업데이트하세요. 신규 배포의 경우 스냅샷은 3.32.3을 수정된 선택지로 제시합니다. 지원되는 계획 없이 기존 클러스터를 다운그레이드하지 마세요.
CoreDNS, external-dns클러스터 호환성을 확인한 뒤 CoreDNS 1.15.0과 external-dns v0.24.0을 사용하세요. Kubernetes 업그레이드로 바뀌었을 것이라고 가정하지 말고, 배포된 DNS 이미지를 확인하세요. 커스텀 TLS 포워딩 설정과 프로바이더 신뢰 설정을 검토하세요.

인증서, 아이덴티티, 정책

cert-manager해당하는 지원 브랜치의 v1.21.3 또는 v1.20.5를 사용하세요. 지원되지 않는 이전 브랜치는 유지 관리되는 릴리스로 옮기고, 외부 issuer용으로 구성한 CA 번들은 별도로 확인하세요.
trust-manager차트 v0.26.0을 사용하거나, 권고에 안내된 대응하는 수정된 Trixie 또는 Bookworm 패키지를 구성하세요. 리포지토리와 태그 재정의를 모두 확인하세요. Bundle 타깃이 업데이트되는지 확인한 다음, 인증서를 다시 로드하지 못하는 소비자 워크로드를 재시작하세요.
SPIRE호환성이 깨지는 변경 사항을 검토한 뒤 v1.16.0을 사용하거나, Go 수정이 포함된 백포트인 v1.15.5와 v1.14.9를 사용하세요. 백포트 이미지에는 영향을 받는 루트 인증서가 남아 있습니다. https_web 페더레이션과 커스텀 트러스트 번들은 별도로 검토하세요.
Dexv2.46.1을 사용하세요. 시작 템플릿이 원격 HTTPS 데이터를 가져온다면, 번들된 gomplate 헬퍼와 그 헬퍼가 사용하는 트러스트 스토어를 확인하세요. 관련된 모든 헬퍼가 수정된 CA 번들을 사용할 수 있도록 유지하세요.
Keycloak26.8.2를 사용하거나, 수정되어 다시 빌드된 26.8.1-2의 다이제스트를 검증하세요. 커스텀 이미지는 업데이트된 JDK와 OS 트러스트 스토어로 다시 빌드하고, 직접 제공하는 추가 트러스트 스토어도 검토하세요.
Vault Secrets OperatorVSO 1.6.2를 사용하고 컨트롤러 롤아웃을 확인하세요. 수정된 기본 이미지를 우선 사용하거나, 1.6.2-ubi에 남아 있는 루트 인증서를 조치하세요. Vault 연결용으로 구성한 CA 번들을 검토하세요.
External Secrets Operator컨트롤러와 차트를 2.14.0으로 업그레이드한 다음 롤아웃 완료를 확인하세요. 외부 시크릿 프로바이더용으로 구성한 CA 번들은 컨트롤러 이미지와 별개로 확인하세요.
Kyverno기존 설치 환경에는 수정된 트러스트 스토어를 사용하고, 변경 후 파드를 재시작하세요. global.caCertificates.data 마운트는 번들 파일 하나만 교체합니다. 추가 인증서 디렉터리 때문에 영향을 받는 루트 인증서가 되살아나지 않는지 확인하세요. 수정된 안정 릴리스가 제공되면 그 릴리스를 우선 사용하세요.
OPA해당 브랜치의 v1.22.2 또는 v1.21.4를 사용하세요. 배포 형태에 맞게 기본 이미지 또는 static 이미지를 업데이트하고, 아웃바운드 연결용 커스텀 신뢰 구성이 있다면 검토하세요.
Gatekeeper프로세스가 로드하는 모든 CA 파일과 디렉터리를 수정한 다음 파드를 재시작하세요. 번들 파일 하나만 교체해서는 충분하지 않을 수 있습니다. 수정된 Go 툴체인으로 빌드된 지원 릴리스가 제공되면 적용하세요.
cosign이미지 서명 워크플로에는 v3.1.4 릴리스 바이너리 또는 그 이후의 검증된 빌드를 사용하세요. 컨테이너 이미지를 사용한다면 이미지의 수정된 번들을 유지하고, 인증서 파일이나 디렉터리 재정의를 검토하세요. 파이프라인이 실제로 사용하는 아티팩트를 검증하세요.
policy-controller실제 사용되는 트러스트 스토어를 수정된 것으로 제공하고 웹훅 파드를 재시작하세요. 로드되는 모든 CA 파일과 디렉터리를 확인한 다음, 수정된 릴리스가 제공되면 적용하세요. Go 업데이트가 병합되었다는 것만으로 기존 배포가 바뀌지는 않습니다.
FalcoFalco 0.45.2를 차트 9.2.2와 함께 사용하세요. falcoctl 0.14.3, driver-loader 0.45.2 등 버전을 고정한 헬퍼 이미지도 확인하고, 업데이트된 구성 요소가 실행 중인지 확인하세요.
oauth2-proxyv7.15.6을 사용하세요. 수정된 기본 이미지를 우선 사용하거나, Alpine 변형에 남아 있는 영향을 받는 루트 인증서를 조치하세요. 프로바이더용 및 업스트림용 커스텀 CA 번들은 별도로 확인하세요.

딜리버리와 공급망

Argo CD(Argo Workflows 및 Argo Rollouts 포함)Argo CD는 3.6.1, 3.5.7 또는 3.4.13, Rollouts는 1.10.2 또는 1.9.3, Workflows는 4.1.6 또는 4.0.15를 사용하세요. 헬퍼 도구가 수정된 번들을 사용할 수 있도록 유지하고, argocd-tls-certs-cm과 그 밖의 재정의를 검토하세요.
HelmHelm을 실행하는 모든 워크스테이션과 러너에서 트러스트 스토어를 업데이트하세요. 이후의 릴리스 노트를 확인하고, 수정된 것으로 간주하기 전에 내려받은 바이너리의 빌드 툴체인을 검증하세요.
FluxFlux 2.10.0을 사용하거나, 2.9와 2.8용으로 문서화된 접미사 포함 컨트롤러 재빌드 태그를 정확히 지정하세요. 접미사가 없는 기존 태그가 반드시 교체된 것은 아닙니다. 업그레이드하기 전에 2.10의 RBAC 및 notification API 변경 사항을 검토하세요.
Tekton Pipelinev1.18.0 또는 해당하는 유지 관리 대상 백포트인 v1.15.5, v1.12.3, v1.9.9 중 하나를 사용하세요. Git CLI를 사용하는 Git 리졸버의 경우, Git이 실제로 로드하는 CA 저장소를 수정하고 리졸버 파드를 재시작하세요.
Harbor지원되는 업그레이드 경로를 따르고 Redis에서 Valkey로의 변경 사항을 검토한 뒤 v2.16.0을 사용하세요. 기재된 백포트 v2.14.6에는 Go 수정이 포함되어 있지만, 이미지 번들에는 영향을 받는 루트 인증서가 남아 있습니다.
Actions Runner Controller컨트롤러와 해당하는 스케일 세트 차트를 0.15.1로 업그레이드하세요. 스케일 세트가 사용하는 러너 이미지와 잡 컨테이너는 별도로 업데이트하세요. 컨트롤러를 업데이트해도 이들의 런타임이나 CA 번들은 교체되지 않습니다.

컨테이너 빌드, 레지스트리, 스캐닝

BuildKit독립 실행형 또는 클러스터 내 빌더를 moby/buildkit:v0.34.2 또는 그 이후의 패치 릴리스로 교체하세요. buildx가 관리하는 빌더는 해당 드라이버의 절차에 따라 업데이트하세요. 로컬 Docker CLI를 변경해도 기존 원격 빌더는 업데이트되지 않습니다.
Trivy, GrypeTrivy 0.76.1과 Grype 0.121.1, 또는 그 이후의 검증된 패치를 사용하세요. 이미지 빌드 및 어드미션 워크플로에서 사용하는 스캐너 이미지와 버전 고정을 업데이트하세요.
ORASORAS가 실행되는 모든 곳에서 트러스트 스토어를 업데이트하거나, 패치된 지원 Go 툴체인으로 v1.3.6을 다시 빌드하세요. 결과 바이너리를 검증하세요. 대상 레지스트리를 제한하는 것만으로는 허용된 연결에 대한 가로채기를 막지 못합니다.
crane (go-containerregistry)패치된 지원 Go 툴체인으로 v0.22.1을 다시 빌드하거나, 그 이후의 검증된 릴리스를 사용하세요. 런타임 CA 저장소도 수정한 다음, 내려받은 바이너리와 버전을 고정한 컨테이너 이미지를 모두 검증하세요.

옵저버빌리티, 데이터, 플랫폼

Prometheus, Alertmanager, blackbox_exporter해당하는 것에 따라 Prometheus는 3.16.0, 3.15.1 또는 3.13.5, Alertmanager는 0.34.2, blackbox_exporter는 0.29.1을 사용하세요. 롤아웃 전에 Alertmanager의 CORS 변경 사항과 커스텀 TLS 설정을 검토하세요.
Prometheus node_exporterTLS 클라이언트 인증을 구성했다면 그 설정을 검토하고, 해당 CA 번들을 의도한 클라이언트로만 제한하세요. 해당하는 트러스트 스토어를 수정하고, 검증된 수정 빌드가 제공되면 적용하세요. 이미지에 대한 탐지 결과만으로는 도달 가능한 TLS 경로가 있는지 알 수 없습니다.
Grafana 13.1, 13.0, 12.4해당 브랜치의 13.1.9, 13.0.12 또는 12.4.14를 사용하세요. 별도로 설치한 플러그인과 커스텀 CA 번들은 서버 업데이트로 해결되었다고 가정하지 말고 따로 확인하세요.
Grafana 13.3, 13.2해당하는 13.3.0 또는 13.2.5를 사용하고 수정된 번들을 유지하세요. 플러그인 바이너리와 해당 CA 재정의는 별도로 확인하고, 플러그인 업데이트가 제공되는 대로 적용하세요.
Loki, Tempo, Mimir, ThanosLoki는 3.7.9 또는 3.6.19, Tempo는 3.1.1, 3.0.5 또는 2.10.10, Mimir는 3.2.3 또는 3.1.8, Thanos는 v0.42.5를 사용하거나, 각 브랜치의 그 이후 검증된 패치를 사용하세요. 커스텀 TLS 저장소를 검토하세요.
OpenTelemetry Collector0.163.2 또는 그 이후의 패치된 core, contrib, Kubernetes 배포판을 사용하세요. 명시적으로 고정한 이미지 지정을 업데이트하고, 실행 중인 Collector 파드가 새 이미지를 사용하는지 확인하세요.
OpenTelemetry Operatoroperator 0.162.0을 사용하고, spec.image 또는 operator의 Collector 이미지 설정으로 Collector 0.163.2 이상을 명시적으로 지정하세요. 문서화된 Python 업데이트를 포함해, 주입되는 자동 계측 이미지는 별도로 확인하세요.
Jaegerv2.23.0 또는 그 이후의 검증된 릴리스를 사용하고 커스텀 TLS 번들을 검토하세요. 플로팅 태그가 기존 파드를 갱신했을 것이라고 가정하지 말고, 배포된 이미지를 검증하세요.
Fluentd, Fluent Bit, Vector해당하는 것에 따라 Fluentd는 v1.19.4-1.2 이미지 또는 그 이후의 수정된 빌드, Fluent Bit는 5.1.5, Vector는 0.61.0을 사용하세요. 오래된 이미지 태그를 교체하고, 출력에서 사용하는 마운트된 CA 번들을 확인하세요.
Velero수정된 안정 릴리스가 제공되면 그 릴리스를 우선 사용하고, 플러그인은 별도로 확인하세요. 임시로 트러스트 스토어를 업데이트한다면 Velero와 node-agent가 로드하는 모든 CA 파일과 디렉터리를 포함한 다음, 이들을 재시작하세요. 결과를 검증하지 않은 채 파일 하나만 교체하지 마세요.
Longhorn1.12에서는 v1.12.2를 사용하세요. 1.13에서는 다음 패치 릴리스와 해당하는 임시 안내를 따르세요. 버전 번호가 더 높다는 이유만으로 1.12.2에서 패치되지 않은 1.13.0으로 옮기지 마세요.
Veeam Kasten9.0.9 이상을 사용하고 모든 Kasten 구성 요소가 교체되었는지 확인하세요. cacertconfigmap.name이 참조하는 ConfigMap을 검토하세요. 컨테이너 안의 트러스트 스토어를 수동으로 수정하지 말고 Veeam의 업그레이드 절차를 따르세요.
Crossplane(코어)코어는 해당하는 2.4.3, 2.3.7, 2.2.7 또는 1.20.14를 사용하세요. 설치된 각 provider와 function 이미지는 구성된 CA 번들을 포함해 개별적으로 확인하세요.
Cluster APICluster API 1.14.4 또는 1.13.8과 이에 대응하는 clusterctl 버전을 사용하세요. CAPA, CAPZ 및 그 밖에 설치된 인프라 프로바이더는 각자의 릴리스와 신뢰 구성을 기준으로 확인하세요.
Karpenter (AWS)환경에 맞게 1.15.1 또는 1.14.3을 사용하세요. 과거 빌드인 1.9.3에는 Go 수정이 포함되어 있지만 영향을 받는 루트 인증서가 남아 있습니다. 컨트롤러를 업그레이드해도 기존 워커 AMI는 교체되지 않으므로, 해당 롤아웃은 별도로 계획하세요.
KEDA수정된 릴리스를 기다리는 동안에는 실제 사용되는 트러스트 스토어를 수정된 것으로 바꾸거나 검증된 재빌드를 사용하세요. 스케일러의 HTTPS 연결과 커스텀 번들을 확인하세요. 네트워크 egress 제한은 노출을 줄일 수 있지만 인증서 검증 자체를 고치지는 못합니다.
Dapr, NATS해당하는 것에 따라 Dapr는 1.19.1, 1.18.10, 1.17.19 또는 1.16.21, nats-server는 2.15.2 또는 2.14.9를 사용하세요. 제공한 TLS CA 파일과 추가 구성 요소는 별도로 점검하세요.
Kubeflow Pipelines해당하는 2.18.0 또는 2.17.3을 사용하세요. 파이프라인 단계 이미지는 업데이트된 OS 인증서와 Python 의존성, 그리고 사용하는 경우 certifi와 pip를 포함해 다시 빌드하세요. 이들이 실제로 사용하는 신뢰 구성은 백엔드와 별개로 검증하세요.
KubeRayKubeRay 1.7.2 또는 그 이후의 검증된 릴리스를 사용하고 operator의 신뢰 구성을 검토하세요. Ray head 및 worker 이미지는 별도로 업데이트하세요. operator를 업그레이드해도 이들의 Python 런타임이나 CA 번들은 업데이트되지 않습니다.
KServe패치된 Go 툴체인으로 만든 검증된 컨트롤러 재빌드를 사용하고, 모델 서버 런타임과 CA 번들을 업데이트하세요. 모든 서빙 이미지를 확인하세요. egress를 제한하는 것만으로는 허용된 HTTPS 연결에 대한 가로채기를 막지 못합니다.
Kubernetes 애드온: metrics-server, VPA, cluster-autoscalermetrics-server v0.9.1, VPA 1.8.1 또는 1.7.3, 그리고 사용 중인 Kubernetes 마이너 버전에 맞는 autoscaler 릴리스(1.37.0, 1.36.2, 1.35.3 또는 1.34.6)를 사용하세요. 매니지드 애드온은 제공업체의 안내를 따르세요.
Kubernetes 애드온: kube-state-metrics패치된 릴리스가 제공되면 적용하고 바이너리와 이미지 번들을 검증하세요. 일반적인 API 서버 연결은 프라이빗 클러스터 CA를 신뢰하므로, 스캐너 탐지 결과를 악용 가능한 경로로 간주하기 전에 실제 신뢰 구성을 평가하세요.

결론

eMudhra 침해는 노드를 패치한 뒤에도 Kubernetes 보안 업데이트가 불완전한 상태로 남을 수 있는 이유를 보여 줍니다. 컨테이너는 오래된 CA 번들을 그대로 가지고 있을 수 있고, 애플리케이션은 별도의 런타임 저장소를 사용할 수 있으며, 클러스터 구성은 두 업데이트를 모두 거치고도 남아 있는 인증서를 제공할 수 있습니다. 또한 실행 중인 프로세스는 재시작해야만 수정이 반영될 수 있습니다.

영향을 받는 클라이언트마다 인증서를 어떻게 검증하는지 파악하고, 해당하는 업데이트를 적용한 뒤, 정상 연결은 계속 동작하면서 침해된 체인은 거부되는지 확인하세요. 검증해야 할 결과는 실제로 사용하는 이미지, 구성, 헬퍼 프로그램을 포함한, 실행 중인 플랫폼의 동작입니다.

FAQ

eMudhra 침해에 대해 가장 자주 받는 질문 다섯 가지.

서비스 메시 mTLS도 영향을 받나요?

아니요. 메시 mTLS는 메시의 프라이빗 CA만 신뢰합니다. 메시가 퍼블릭 루트 인증서를 신뢰하는 지점, 즉 egress TLS, JWKS 조회, https_web을 통한 SPIFFE 페더레이션을 확인하세요.

노드의 ca-certificates만 업데이트하면 충분한가요?

아니요. 실행 중인 프로세스는 재시작하기 전까지 이전 루트 인증서를 유지합니다. 이미지, 일부 런타임, ConfigMap, Secret은 각자 사본을 가지고 있어 별도로 업데이트해야 합니다.

어떤 Kubernetes 버전에 수정이 포함되어 있나요?

v1.37.2, v1.36.6, v1.35.10, v1.34.13입니다. 1.33 이하에는 수정이 없습니다. 구성 요소 이미지는 여전히 해당 루트 인증서를 신뢰하므로, 보호는 Go 차단 목록에서 나옵니다.

실제로 공격받은 사례가 있나요?

악용 사례는 보고되지 않았습니다. 다만 클러스터 안의 클라이언트 대부분은 Certificate Transparency를 확인하지 않으므로, 이들에 대한 공격 가능성을 배제할 수는 없습니다.

취약점 스캐너가 이를 잡아내나요?

일부만 잡아냅니다. Trivy와 Grype는 Go 표준 라이브러리를 탐지하지만, ca-certificates 수정에는 CVE가 없어 오래된 번들이 문제없음으로 나올 수 있습니다. 번들은 지문으로 확인하세요.

노출 범위 평가와 조치 계획 수립에 도움이 필요하다면 플랫폼 준비도 진단에 대해 Todea에 문의하세요.