Ztunnel 투명 암호화

Ztunnel 투명 암호화 (Beta)

Cilium이 ztunnel을 사용해 Cilium 관리 엔드포인트 간의 투명 암호화와 상호 TLS(mTLS) 인증을 수행하도록 구성하는 방법을 설명하는 문서예요. 베타 기능이에요.

출처: Ztunnel Transparent Encryption (Beta)

본문

참고: 이 기능은 베타 기능이에요. 문제가 발생하면 피드백을 주고 GitHub issue를 제출해 주세요.

이 가이드는 Cilium 관리 엔드포인트 간의 투명 암호화와 상호 TLS(mTLS) 인증을 위해 Cilium이 ztunnel을 사용하도록 구성하는 방법을 설명해요. ztunnel은 파드 간 통신을 위한 투명한 Layer 4 mTLS 암호화와 인증을 제공하는, 목적에 맞게 만들어진 노드별 프록시예요.

Cilium에서 ztunnel이 활성화되면 각 클러스터 노드에서 실행되는 에이전트가 로컬 ztunnel 프록시와 컨트롤 플레인 연결을 설정해요. Cilium은 네임스페이스 단위로 파드를 메시에 등록(enroll)해, 어떤 워크로드가 mTLS 암호화에 참여할지 세밀하게 제어할 수 있게 해 줘요. 등록된 파드는 해당 네트워크 네임스페이스에 구성된 iptables 규칙을 사용해 트래픽이 ztunnel 프록시로 투명하게 리다이렉트되며, 트래픽은 목적지로 보내지기 전에 상호 TLS를 사용해 암호화되고 인증돼요.

인증용 시크릿 생성 (Generating secrets for authentication)

Cilium의 ztunnel 통합은 Kubernetes 시크릿을 통해 일련의 개인 키와 그에 따른 인증서가 존재해야 해요. 이는 IPsec 키 주입과 동일한 패턴을 따르며, Cilium을 배포하기 전에 다음 bash 스크립트로 키를 생성할 수 있어요.

#!/usr/bin/env bash
# SPDX-License-Identifier: Apache-2.0
# Copyright Authors of Cilium

set -eu

# == Bootstrap ===
openssl genrsa -out bootstrap-private.key 2048

echo '
[ req ]
distinguished_name = req_distinguished_name
x509_extensions = v3_ca
prompt = no

[ req_distinguished_name ]
O = cluster.local

[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names

[alt_names]
DNS.1 = localhost
' > openssl.conf

openssl req -x509 -new -nodes -key bootstrap-private.key -sha256 -days 3650 -out bootstrap-root.crt -config openssl.conf

# == CA ==
openssl genrsa -out ca-private.key 2048

echo '
[ req ]
distinguished_name = req_distinguished_name
x509_extensions = v3_ca
prompt = no

[ req_distinguished_name ]
O = cluster.local

[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
' > openssl.conf

openssl req -x509 -new -nodes -key ca-private.key -sha256 -days 3650 -out ca-root.crt -config openssl.conf

kubectl --namespace kube-system create secret generic cilium-ztunnel-secrets \
      --from-file=bootstrap-private.key=bootstrap-private.key \
      --from-file=bootstrap-root.crt=bootstrap-root.crt \
      --from-file=ca-private.key=ca-private.key \
      --from-file=ca-root.crt=ca-root.crt

'bootstrap' 키는 ztunnel과 Cilium의 xDS 및 인증서 서버 구현 사이의 연결을 보호하는 데 사용돼요. 'ca' 키는 ztunnel의 요청에 따라 인메모리 및 임시 클라이언트 인증서를 만들기 위한 루트 인증서로 사용돼요.

Cilium에서 ztunnel 활성화 (Enable ztunnel in Cilium)

ztunnel을 활성화한 상태로 Cilium을 설치하기 전에 다음을 확인하세요.

  • 필요한 Kubernetes 시크릿이 있는지 확인하세요.
  • Cluster Mesh가 활성화되지 않았는지 확인하세요(ztunnel은 현재 Cluster Mesh와 호환되지 않아요).

Cilium CLI로 Cilium을 배포한다면 다음 옵션을 전달하세요.

cilium install 1.20.2 \
   --set encryption.enabled=true \
   --set encryption.type=ztunnel

Helm을 사용해 Cilium을 배포한다면 다음 옵션을 전달하세요.

helm install cilium cilium/cilium --version 1.20.2 \
  --namespace kube-system \
  --set encryption.enabled=true \
  --set encryption.type=ztunnel

네임스페이스 등록 (Enrolling Namespaces)

Cilium에서 ztunnel을 활성화한 후에는 워크로드에 대한 mTLS 암호화를 활성화하기 위해 네임스페이스를 명시적으로 등록해야 해요. 이는 네임스페이스에 라벨을 적용해 수행해요.

kubectl label namespace <namespace-name> io.cilium/mtls-enabled=true

네임스페이스가 등록됐는지 확인하려면:

kubectl get namespace <namespace-name> --show-labels

네임스페이스가 등록되면:

  • 네임스페이스의 모든 기존 파드(ztunnel 파드 자체 제외)가 등록돼요
  • 각 파드의 네트워크 네임스페이스에 트래픽 리다이렉션용 iptables 규칙이 구성돼요
  • 파드 메타데이터가 ZDS 프로토콜을 통해 ztunnel 프록시로 전송돼요
  • 이후 네임스페이스에서 생성되는 파드는 자동으로 등록돼요

네임스페이스 등록을 해제하려면:

kubectl label namespace <namespace-name> io.cilium/mtls-enabled-

이렇게 하면:

  • 네임스페이스의 모든 파드가 ztunnel에서 등록 해제돼요
  • 각 파드의 네트워크 네임스페이스에서 iptables 규칙이 제거돼요
  • ztunnel이 해당 워크로드에 대한 트래픽 처리를 중지하도록 알려요

설정 검증 (Validate the Setup)

  • ztunnel이 활성화됐는지 확인하세요. kubectl -n kube-system describe cm cilium-config | grep enable-ztunnel -A2 ztunnel 암호화가 활성화됐음을 나타내는 출력이 보여야 해요.
  • 등록된 네임스페이스를 확인하세요. kubectl get namespaces -l io.cilium/mtls-enabled=true ztunnel 등록용으로 라벨이 지정된 모든 네임스페이스를 보여줘요. 이 네임스페이스들이 실제로 StateDB 테이블에 등록됐는지 확인하려면: kubectl exec -n kube-system ds/cilium -- cilium-dbg statedb dump | jq '.["mtls-enrolled-namespaces"]' 이 쿼리 결과는 등록 리콘실러(reconciler)가 성공적으로 처리한 네임스페이스를 보여줘야 해요.
  • mtls로 등록된 파드를 호스팅하는 Cilium 파드 중 하나에서 kubectl -n kube-system exec -ti pod/<cilium-pod-hosting-mtls-pod> -- bash로 bash 셸을 실행하고 다음 명령을 실행하세요.
    • tcpdump 설치: $ apt-get update $ apt-get -y install tcpdump
    • 트래픽이 암호화되는지 확인하세요. 아래 예제에서 패킷이 15008(HBONE) 목적지 포트를 가지는 것으로 확인할 수 있어요. 아래 예제에서 eth0은 파드 간 통신에 사용되는 인터페이스예요. 터널링이 활성화된 경우 이 인터페이스를 cilium_vxlan 같은 것으로 바꾸세요. tcpdump -i eth0 port 15008 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes 13:00:06.982499 IP 10.244.1.95.15008 > 10.244.2.3.33446: ... 13:00:06.982536 IP 10.244.2.3.33446 > 10.244.1.95.15008: ... 13:00:06.982675 IP 10.244.2.3.33446 > 10.244.1.95.15008: ...

제한 사항 (Limitations)

  • 워크로드 간 트래픽은 출발지와 목적지 엔드포인트가 모두 ztunnel에 등록된 경우에만 지원돼요. 등록된 워크로드와 등록되지 않은 워크로드 간의 통신은 지원되지 않아요.
  • ztunnel 통합은 현재 네임스페이스 라벨을 통한 등록만 지원해요. 파드 수준 등록은 지원되지 않아요.
  • mTLS 암호화는 현재 TCP 트래픽만 지원돼요. UDP 및 기타 프로토콜은 ztunnel로 리다이렉트되지 않아요.
  • 통합은 커널의 iptables 지원이 필요하며, iptables를 지원하지 않는 환경(일부 최소 컨테이너 런타임 등)에서는 사용할 수 없어요.
  • 트래픽이 파드를 떠나기 전에 암호화되므로 ztunnel은 Cilium 네트워크 정책을 방해해요. L4 정책은 ztunnel HBONE 포트(15008)를 직접 대상으로 하는 경우를 제외하고는 작동하지 않아요.

알려진 이슈 (Known Issues)

  • ztunnel이 활성화되면 Cluster Mesh는 현재 지원되지 않아요. 둘 다 활성화하려 하면 검증 오류가 발생해요.
  • 네트워크 네임스페이스 경로가 없는 파드(예: 호스트 네트워킹 파드)는 ztunnel에 등록할 수 없으며 등록 중에 건너뛰어져요.

더 알아보기 (Learn more)