kubectl이 사용자의 전체 권한으로, 사용자 모르게 셸 스크립트를 포함한 임의의 실행 파일을 실행할 수 있다는 사실을 알고 계셨나요? kubeconfig를 다운로드하거나 자동 생성할 때마다 users[n].exec.command 필드는 사용자를 대신하여 자격 증명을 가져오는 실행 파일을 지정할 수 있습니다. 오해하지 마세요, 이것은 외부 ID 공급자로 클러스터에 인증할 수 있게 해주는 놀라운 기능입니다. 그럼에도 불구하고, 여러분은 아마 문제점을 짐작할 수 있을 것입니다. 여러분의 kubeconfig가 시스템에서 정확히 어떤 실행 파일을 실행하는지 알고 계신가요? kubeconfig를 생성한 파이프라인을 신뢰하시나요? 만약 kubeconfig를 생성하는 코드에 공급망 공격이 있었거나, 생성 파이프라인이 손상되었다면, 공격자는 여러분의 kubeconfig가 임의의 코드를 실행하도록 속여 시스템에 불미스러운 일을 저지를 수도 있습니다.
사용자에게 시스템에서 실행되는 내용에 대한 더 많은 제어권을 주기 위해, SIG-Auth와 SIG-CLI는 Kubernetes 1.35에 자격 증명 플러그인 정책 및 허용 목록을 베타 기능으로 추가했습니다. 이 기능은 client-go 라이브러리를 사용하는 모든 클라이언트에서 REST 구성의 ExecProvider.PluginPolicy 구조체를 채워서 사용할 수 있습니다. 이러한 변경의 영향력을 넓히기 위해, Kubernetes v1.35는 한 줄의 애플리케이션 코드도 작성하지 않고 이 기능을 관리할 수 있게 해줍니다. kuberc 설정 파일에 credentialPluginPolicy와 credentialPluginAllowlist 두 필드를 추가하여 kubectl이 이 정책과 허용 목록을 강제하도록 설정할 수 있습니다. 이 필드 중 하나 또는 둘 다를 추가하면 kubectl이 실행할 수 있는 자격 증명 플러그인이 제한됩니다.
작동 방식
이 기능에 대한 자세한 설명은 kuberc에 대한 공식 문서에서 확인할 수 있지만, 이 블로그 게시물에서는 새로운 보안 기능에 대한 간략한 개요를 제공합니다. 새로운 기능은 베타 버전이며 어떠한 기능 게이트도 사용하지 않고 사용할 수 있습니다.
다음 예시는 가장 간단한 예시입니다. 단순히 새로운 필드를 지정하지 않는 것입니다.
apiVersion: kubectl.config.k8s.io/v1beta1
kind: Preference
이렇게 하면 kubectl은 항상 그랬던 것처럼 작동하며, 모든 플러그인이 허용됩니다.
다음 예시는 기능적으로 동일하지만, 더 명시적이므로 실제로 원하는 바라면 이 방식이 더 선호됩니다.
apiVersion: kubectl.config.k8s.io/v1beta1
kind: Preference
credentialPluginPolicy: AllowAll
만약 exec 자격 증명 플러그인을 사용하고 있는지 모른다면, 정책을 DenyAll로 설정해 보세요.
apiVersion: kubectl.config.k8s.io/v1beta1
kind: Preference
credentialPluginPolicy: DenyAll
만약 자격 증명 플러그인을 사용하고 있다면, kubectl이 무엇을 실행하려고 하는지 빠르게 알게 될 것입니다. 다음과 같은 오류가 발생할 것입니다.
서버에 연결할 수 없습니다: 자격 증명을 가져오는 중: 플러그인 "cloudco-login"이 허용되지 않음: 정책이 "DenyAll"로 설정됨
문제 디버깅에 충분한 정보가 없다면, 다음 명령을 실행할 때 로깅 상세도를 높여보세요. 예를 들어:
# 문제가 여전히 불분명하면 상세도를 높이거나 낮추세요
kubectl get pods --verbosity 5
플러그인 선택적 허용
일상 업무에 cloudco-login 플러그인이 필요하다면 어떨까요? 그렇기 때문에 정책에 세 번째 옵션인 Allowlist가 있습니다. 특정 플러그인을 허용하려면 정책을 설정하고 credentialPluginAllowlist를 추가하세요.
apiVersion: kubectl.config.k8s.io/v1beta1
kind: Preference
credentialPluginPolicy: Allowlist
credentialPluginAllowlist:
- name: /usr/local/bin/cloudco-login
- name: get-identity
허용 목록에 두 개의 항목이 있는 것을 알 수 있습니다. 하나는 전체 경로로 지정되었고, 다른 하나인 get-identity는 단순히 기본 이름입니다. 기본 이름만 지정하면 exec.LookPath를 사용하여 전체 경로를 찾게 되는데, 이는 globbing을 확장하거나 와일드카드를 처리하지 않습니다. 현재 globbing은 지원되지 않습니다. 두 가지 형식(기본 이름 및 전체 경로) 모두 허용되지만, 전체 경로를 사용하는 것이 허용되는 바이너리의 범위를 더욱 좁히기 때문에 더 선호됩니다.
향후 개선 사항
현재 허용 목록 항목에는 name이라는 필드만 있습니다. 앞으로 저희(Kubernetes SIG CLI)는 다른 요구 사항들이 추가되기를 바랍니다. 유용해 보이는 한 가지 아이디어는 체크섬 검증입니다. 예를 들어, 바이너리가 b9a3fad00d848ff31960c44ebb5f8b92032dc085020f857c98e32a5d5900ff9c라는 SHA256 합계를 가지고 있으며 /usr/bin/cloudco-login 경로에 존재할 때만 실행이 허용되는 방식입니다.
또 다른 가능성은 신뢰할 수 있는 서명 키 세트 중 하나로 서명된 바이너리만 허용하는 것입니다.
참여하기
자격 증명 플러그인 정책은 아직 개발 중이며, 여러분의 피드백에 매우 관심이 많습니다. 이 기능의 좋은 점과 해결되었으면 하는 문제점에 대해 듣고 싶습니다. 또는 위에 언급된 개선 사항 중 하나를 기여할 여력이 있다면, 이는 Kubernetes에 기여를 시작하는 좋은 방법이 될 것입니다. Slack에서 자유롭게 토론에 참여하세요: