[K8S Deploy] Kubernets the Hard Way -04 - Provisioning a CA and Generating TLS Certificates & 인증 관련 개념 정리

진웅·2026년 1월 9일

k8s deploy

목록 보기
2/20

CA 설정 및 TLS 인증서 생성 (PKI 구성)**

목표 : CA 설정 및 TLS 인증서 생성 (PKI 구성)

  • 쿠버네티스의 모든 컴포넌트는 서로를 신뢰하기 위해 CA(Certificate Authority)를 통해 서명된 인증서가 필요하다.
  • 크게 CA 생성 → 클라이언트/서버 인증서 생성 → 각 노드로 배포 순서로 진행한다.

K8S 인증서 표

항목개인키CSR인증서참고 정보 (DN / SAN)Extended Key Usage
Root CAca.keyXca.crtCN = CA-
adminadmin.keyadmin.csradmin.crtCN = admin, O = system:mastersTLS Web Client Authentication
node-0node-0.keynode-0.csrnode-0.crtCN = system:node:node-0, O = system:nodesTLS Web Server / Client Authentication
node-1node-1.keynode-1.csrnode-1.crtCN = system:node:node-1, O = system:nodesTLS Web Server / Client Authentication
kube-proxykube-proxy.keykube-proxy.csrkube-proxy.crtCN = system:kube-proxy, O = system:node-proxierTLS Web Server / Client Authentication
kube-schedulerkube-scheduler.keykube-scheduler.csrkube-scheduler.crtCN = system:kube-scheduler, O = system:kube-schedulerTLS Web Server / Client Authentication
kube-controller-managerkube-controller-manager.keykube-controller-manager.csrkube-controller-manager.crtCN = system:kube-controller-manager, O = system:kube-controller-managerTLS Web Server / Client Authentication
kube-api-serverkube-api-server.keykube-api-server.csrkube-api-server.crtCN = kubernetes, SAN: IP(127.0.0.1, 10.32.0.1), DNS(kubernetes,..)TLS Web Server / Client Authentication
service-accountsservice-accounts.keyservice-accounts.csrservice-accounts.crtCN = service-accountsTLS Web Client Authentication

항목네트워크 대역 or IP비고
clusterCIDR10.200.0.0/16전체 Pod 네트워크
node-0 PodCIDR10.200.0.0/24node-0 할당 대역
node-1 PodCIDR10.200.1.0/24node-1 할당 대역
ServiceCIDR10.32.0.0/24Service 네트워크
api clusterIP10.32.0.1Kubernetes Service IP

1. 환경 변수 및 설정 파일 준비

먼저 인증서 생성에 필요한 설정 파일(ca.conf).
여기서 각 컴포넌트의 CN(Common Name)O(Organization), 그리고 SAN(Subject Alternative Name)이 정의된다.

💡 핵심 포인트:

  • Admin: O=system:masters (이 그룹은 RBAC 검사를 무시하고 무조건 슈퍼유저 권한을 가짐. 매우 중요!)
  • API Server: 10.32.0.1(Service Network 첫 IP)와 kubernetes 도메인 등이 SAN에 포함되어야 함.

📄 cat ca.conf 파일 내용 확인

구분역할
[req]OpenSSL 요청 기본 동작
[ca_*]CA 인증서
[admin]관리자 (kubectl)
[service-accounts]ServiceAccount 토큰 서명
[node-*]워커 노드(kubelet)
[kube-proxy]kube-proxy
[kube-controller-manager]컨트롤러
[kube-scheduler]스케줄러
[kube-api-server]API Server
[default_req_extensions]공통 CSR 옵션

# 작업 디렉토리 이동 (필요 시)
cd ~/

# 1. ca.conf 생성 (OpenSSL 설정 파일)
cat <<EOF > ca.conf
[req]
distinguished_name = req_distinguished_name
prompt             = no
x509_extensions    = ca_x509_extensions

[ca_x509_extensions]
basicConstraints = CA:TRUE
keyUsage         = cRLSign, keyCertSign

[req_distinguished_name]
C   = US
ST  = Washington
L   = Seattle
CN  = CA

[admin]
distinguished_name = admin_distinguished_name
prompt             = no
req_extensions     = default_req_extensions

[admin_distinguished_name]
CN = admin
O  = system:masters

[service-accounts]
distinguished_name = service-accounts_distinguished_name
prompt             = no
req_extensions     = default_req_extensions

[service-accounts_distinguished_name]
CN = service-accounts

[node-0]
distinguished_name = node-0_distinguished_name
prompt             = no
req_extensions     = node-0_req_extensions

[node-0_req_extensions]
basicConstraints     = CA:FALSE
extendedKeyUsage     = clientAuth, serverAuth
keyUsage             = critical, digitalSignature, keyEncipherment
nsCertType           = client
nsComment            = "Node-0 Certificate"
subjectAltName       = DNS:node-0, IP:127.0.0.1
subjectKeyIdentifier = hash

[node-0_distinguished_name]
CN = system:node:node-0
O  = system:nodes
C  = US
ST = Washington
L  = Seattle

[node-1]
distinguished_name = node-1_distinguished_name
prompt             = no
req_extensions     = node-1_req_extensions

[node-1_req_extensions]
basicConstraints     = CA:FALSE
extendedKeyUsage     = clientAuth, serverAuth
keyUsage             = critical, digitalSignature, keyEncipherment
nsCertType           = client
nsComment            = "Node-1 Certificate"
subjectAltName       = DNS:node-1, IP:127.0.0.1
subjectKeyIdentifier = hash

[node-1_distinguished_name]
CN = system:node:node-1
O  = system:nodes
C  = US
ST = Washington
L  = Seattle

[kube-proxy]
distinguished_name = kube-proxy_distinguished_name
prompt             = no
req_extensions     = kube-proxy_req_extensions

[kube-proxy_req_extensions]
basicConstraints     = CA:FALSE
extendedKeyUsage     = clientAuth, serverAuth
keyUsage             = critical, digitalSignature, keyEncipherment
nsCertType           = client
nsComment            = "Kube Proxy Certificate"
subjectAltName       = DNS:kube-proxy, IP:127.0.0.1
subjectKeyIdentifier = hash

[kube-proxy_distinguished_name]
CN = system:kube-proxy
O  = system:node-proxier
C  = US
ST = Washington
L  = Seattle

[kube-controller-manager]
distinguished_name = kube-controller-manager_distinguished_name
prompt             = no
req_extensions     = kube-controller-manager_req_extensions

[kube-controller-manager_req_extensions]
basicConstraints     = CA:FALSE
extendedKeyUsage     = clientAuth, serverAuth
keyUsage             = critical, digitalSignature, keyEncipherment
nsCertType           = client
nsComment            = "Kube Controller Manager Certificate"
subjectAltName       = DNS:kube-controller-manager, IP:127.0.0.1
subjectKeyIdentifier = hash

[kube-controller-manager_distinguished_name]
CN = system:kube-controller-manager
O  = system:kube-controller-manager
C  = US
ST = Washington
L  = Seattle

[kube-scheduler]
distinguished_name = kube-scheduler_distinguished_name
prompt             = no
req_extensions     = kube-scheduler_req_extensions

[kube-scheduler_req_extensions]
basicConstraints     = CA:FALSE
extendedKeyUsage     = clientAuth, serverAuth
keyUsage             = critical, digitalSignature, keyEncipherment
nsCertType           = client
nsComment            = "Kube Scheduler Certificate"
subjectAltName       = DNS:kube-scheduler, IP:127.0.0.1
subjectKeyIdentifier = hash

[kube-scheduler_distinguished_name]
CN = system:kube-scheduler
O  = system:kube-scheduler
C  = US
ST = Washington
L  = Seattle

[kube-api-server]
distinguished_name = kube-api-server_distinguished_name
prompt             = no
req_extensions     = kube-api-server_req_extensions

[kube-api-server_req_extensions]
basicConstraints     = CA:FALSE
extendedKeyUsage     = clientAuth, serverAuth
keyUsage             = critical, digitalSignature, keyEncipherment
nsCertType           = client, server
nsComment            = "Kube API Server Certificate"
subjectAltName       = @kube-api-server_alt_names
subjectKeyIdentifier = hash

[kube-api-server_alt_names]
IP.0  = 127.0.0.1
IP.1  = 10.32.0.1
DNS.0 = kubernetes
DNS.1 = kubernetes.default
DNS.2 = kubernetes.default.svc
DNS.3 = kubernetes.default.svc.cluster
DNS.4 = kubernetes.svc.cluster.local
DNS.5 = server.kubernetes.local
DNS.6 = api-server.kubernetes.local

[kube-api-server_distinguished_name]
CN = kubernetes
C  = US
ST = Washington
L  = Seattle

[default_req_extensions]
basicConstraints     = CA:FALSE
extendedKeyUsage     = clientAuth
keyUsage             = critical, digitalSignature, keyEncipherment
nsCertType           = client
nsComment            = "Admin Client Certificate"
subjectKeyIdentifier = hash
EOF

ca.conf 파일은 OpenSSL에게 "이런 조건으로 인증서를 만들어줘"라고 지시하는 설계도와 같다.

ca.conf 핵심 용어 및 설정 분석

OpenSSL 및 인증서 핵심 용어

용어 (Term)풀이 (Description)쿠버네티스에서의 의미
CN (Common Name)이름. 인증서의 주인.사용자 ID(admin, kubelet) 또는 호스트네임(kubernetes)으로 사용됨.
O (Organization)조직/소속.그룹(Group)으로 매핑됨. RBAC 권한 제어의 핵심. (예: system:masters)
DN (Distinguished Name)식별자.CN, O, 국가(C), 지역(L) 등을 합쳐서 부르는 고유한 이름 정보.
basicConstraints제약 조건.CA:TRUE면 이 인증서로 다른 인증서를 발급(서명)할 수 있음. (일반 인증서는 FALSE)
keyUsage키 용도.이 열쇠를 어디에 쓸지 제한함. (서명용, 암호화용 등)
extendedKeyUsage확장 용도.clientAuth(클라이언트 신분증), serverAuth(서버 신분증) 구분.
SAN (Subject Alt Name)대체 이름.하나의 인증서로 여러 IP나 도메인을 커버할 때 사용. (API 서버가 대표적)

설정 상세 분석

A. [req] 섹션

OpenSSL이 CSR(인증서 서명 요청)을 만들 때 기본적으로 따를 규칙이다.

  • distinguished_name: "이름 입력 양식은 어디에 정의되어 있니?" (req_distinguished_name 참조)
  • x509_extensions: "인증서 만들 때 확장 기능(옵션)은 뭘 넣을까?" (ca_x509_extensions 참조)

B. keyUsage (열쇠의 용도)

  • digitalSignature: 전자 서명용. (나임을 증명)
  • keyEncipherment: 키 암호화용. (데이터를 주고받을 때 비밀키 교환)
  • keyCertSign: 중요! 다른 인증서에 서명할 수 있는 권한. (Root CA만 가짐)

C. extendedKeyUsage (서버 vs 클라이언트)

  • serverAuth: "나는 서버야." (예: API 서버, Kubelet 서버). 클라이언트(kubectl)가 접속할 때 이 인증서를 보고 "진짜 서버 맞네"라고 신뢰함.
  • clientAuth: "나는 클라이언트야." (예: Kubectl, Kubelet 클라이언트). 서버(API 서버)에게 요청을 보낼 때 "나 admin 맞아요"라고 신분증을 제시함.
  • 참고: kubelet이나 api-server는 양쪽 역할(서버이면서 누군가의 클라이언트)을 다 하기 때문에 둘 다(serverAuth, clientAuth) 가지고 있음.

D. O = system:masters (절대 권력)

admin 섹션에 있는 이 설정이 제일 무서운 권력자.

  • 쿠버네티스 코드 내부에 하드코딩 되어 있어서, 이 그룹(O)을 가진 인증서가 들어오면 모든 권한 검사(RBAC)를 프리패스한다..

E. SAN (Subject Alternative Name)

kube-api-server 섹션을 보면 주소가 엄청 많다.

  • 127.0.0.1: 로컬에서 접속할 때.
  • 10.32.0.1: 클러스터 내부에서 Service IP로 접속할 때.
  • kubernetes.default...: 파드들이 도메인으로 접속할 때.
  • 핵심: 클라이언트가 어떤 주소(IP 혹은 도메인)로 찌르든, 인증서에 그 주소가 적혀 있어야 "안전한 사이트"로 인정해줘. 하나라도 빠지면 에러 남.

2. Root CA 생성 (모든 신뢰의 시작,최상위!)

항목개인키CSR인증서참고 정보 (DN / SAN)Extended Key Usage
Root CAca.keyXca.crtCN = CA-
# 1. CA 개인키 생성 (ca.key)
openssl genrsa -out ca.key 4096

# 2. CA 인증서 생성 (ca.crt) - Self Signed
openssl req -x509 -new -sha512 -noenc \
  -key ca.key -days 3653 \
  -config ca.conf \
  -out ca.crt

# 확인
ls -l ca.*
# 
-rw-r--r-- 1 root root 4820 Jan 11 00:09 ca.conf
-rw-r--r-- 1 root root 1899 Jan 11 00:09 ca.crt
-rw------- 1 root root 3268 Jan 11 00:09 ca.key

openssl x509 -in ca.crt -text -noout | grep -A 2 "Validity"
# 
        Validity
            Not Before: Jan 10 15:09:26 2026 GMT
            Not After : Jan 11 15:09:26 2036 GMT

3. Admin 및 컴포넌트 인증서 생성

항목개인키CSR인증서참고 정보 (DN / SAN)Extended Key Usage
adminadmin.keyadmin.csradmin.crtCN = admin, O = system:mastersTLS Web Client Authentication
node-0node-0.keynode-0.csrnode-0.crtCN = system:node:node-0, O = system:nodesTLS Web Server / Client Authentication
node-1node-1.keynode-1.csrnode-1.crtCN = system:node:node-1, O = system:nodesTLS Web Server / Client Authentication
kube-proxykube-proxy.keykube-proxy.csrkube-proxy.crtCN = system:kube-proxy, O = system:node-proxierTLS Web Server / Client Authentication
kube-schedulerkube-scheduler.keykube-scheduler.csrkube-scheduler.crtCN = system:kube-scheduler, O = system:kube-schedulerTLS Web Server / Client Authentication
kube-controller-managerkube-controller-manager.keykube-controller-manager.csrkube-controller-manager.crtCN = system:kube-controller-manager, O = system:kube-controller-managerTLS Web Server / Client Authentication
kube-api-serverkube-api-server.keykube-api-server.csrkube-api-server.crtCN = kubernetes, SAN: IP(127.0.0.1, 10.32.0.1), DNS(kubernetes,..)TLS Web Server / Client Authentication
service-accountsservice-accounts.keyservice-accounts.csrservice-accounts.crtCN = service-accountsTLS Web Client Authentication
# 1. 생성할 인증서 목록 정의
certs=(
  "admin"
  "node-0" "node-1"
  "kube-proxy" "kube-scheduler"
  "kube-controller-manager"
  "kube-api-server"
  "service-accounts"
)

# 2. 루프: 개인키 -> CSR -> CA 서명 -> CRT 생성
for i in ${certs[*]}; do
  echo "Generating ${i} certificate..."

  # 개인키 생성
  openssl genrsa -out "${i}.key" 4096

  # CSR 생성 (ca.conf의 섹션 참조)
  openssl req -new -key "${i}.key" -sha256 \
    -config "ca.conf" -section ${i} \
    -out "${i}.csr"

  # CA로 서명하여 인증서(CRT) 생성
  openssl x509 -req -days 3653 -in "${i}.csr" \
    -copy_extensions copyall \
    -sha256 -CA "ca.crt" \
    -CAkey "ca.key" \
    -CAcreateserial \
    -out "${i}.crt"
done
#
Generating admin certificate...
Certificate request self-signature ok
subject=CN = admin, O = system:masters
Generating node-0 certificate...
Certificate request self-signature ok
subject=CN = system:node:node-0, O = system:nodes, C = US, ST = Washington, L = Seattle
Generating node-1 certificate...
Certificate request self-signature ok
subject=CN = system:node:node-1, O = system:nodes, C = US, ST = Washington, L = Seattle
Generating kube-proxy certificate...
Certificate request self-signature ok
subject=CN = system:kube-proxy, O = system:node-proxier, C = US, ST = Washington, L = Seattle
Generating kube-scheduler certificate...
Certificate request self-signature ok
subject=CN = system:kube-scheduler, O = system:kube-scheduler, C = US, ST = Washington, L = Seattle
Generating kube-controller-manager certificate...
Certificate request self-signature ok
subject=CN = system:kube-controller-manager, O = system:kube-controller-manager, C = US, ST = Washington, L = Seattle
Generating kube-api-server certificate...
Certificate request self-signature ok
subject=CN = kubernetes, C = US, ST = Washington, L = Seattle
Generating service-accounts certificate...
Certificate request self-signature ok
subject=CN = service-accounts


# 3. 결과 확인
ls -1 *.crt *.key *.csr

#
admin.crt
admin.csr
admin.key
ca.crt
ca.key
kube-api-server.crt
kube-api-server.csr
kube-api-server.key
kube-controller-manager.crt
kube-controller-manager.csr
kube-controller-manager.key
kube-proxy.crt
kube-proxy.csr
kube-proxy.key
kube-scheduler.crt
kube-scheduler.csr
kube-scheduler.key
node-0.crt
node-0.csr
node-0.key
node-1.crt
node-1.csr
node-1.key
service-accounts.crt
service-accounts.csr
service-accounts.key

📚 Study Note: `system:masters admin.crt를 확인해보면 O=system:masters`로 되어 있어.
쿠버네티스 API 서버는 이 그룹에 속한 요청은 RBAC 검사를 아예 생략하고 슈퍼유저 권한을 부여해. 만약 이 키가 탈취되면 클러스터는 끝장나는 거야. (AWS Root 계정급)


4. 인증서 배포 (Distribution)

생성된 파일들을 각 서버의 적절한 위치로 보내자.

  • Worker Nodes (node-0, node-1): CA 인증서와 본인들의 Kubelet 인증서 필요.
  • Control Plane (server): CA 키/인증서, API Server 인증서, Service Account 키 필요.
# 1. Worker Node 배포 (node-0, node-1)
for host in node-0 node-1; do
  echo "--- Copying certs to ${host} ---"
  
  # 원격 디렉토리 생성
  ssh root@${host} mkdir -p /var/lib/kubelet/

  # CA 인증서 복사
  scp ca.crt root@${host}:/var/lib/kubelet/

  # 해당 노드의 인증서와 키를 'kubelet.crt/key'라는 이름으로 복사
  scp ${host}.crt root@${host}:/var/lib/kubelet/kubelet.crt
  scp ${host}.key root@${host}:/var/lib/kubelet/kubelet.key
done

# 2. Control Plane 배포 (server)
echo "--- Copying certs to server ---"
scp \
  ca.key ca.crt \
  kube-api-server.key kube-api-server.crt \
  service-accounts.key service-accounts.crt \
  root@server:~/

# 3. 배포 확인
echo "Checking node-0..."
ssh node-0 ls -l /var/lib/kubelet/
#
total 12
-rw-r--r-- 1 root root 1899 Jan 11 00:50 ca.crt
-rw-r--r-- 1 root root 2147 Jan 11 00:50 kubelet.crt
-rw------- 1 root root 3272 Jan 11 00:50 kubelet.key
echo "Checking server..."
ssh server ls -l /root/
# 
total 24
-rw-r--r-- 1 root root 1899 Jan 11 00:50 ca.crt
-rw------- 1 root root 3268 Jan 11 00:50 ca.key
-rw-r--r-- 1 root root 2354 Jan 11 00:50 kube-api-server.crt
-rw------- 1 root root 3272 Jan 11 00:50 kube-api-server.key
-rw-r--r-- 1 root root 2004 Jan 11 00:50 service-accounts.crt
-rw------- 1 root root 3272 Jan 11 00:50 service-accounts.key

🔎 심화 학습 : Kind 클러스터와 비교

참고용으로 가져온 Kind 클러스터 정보를 보면 우리가 하는 작업이 표준과 일치함을 알 수 있어.

  1. 유효기간: Kind는 기본 1년(364d), 우리는 10년(3653 days)으로 설정했어. (실무에선 보통 1년 후 갱신)
  2. API Server SANs: Kind도 10.96.0.1(Service IP), 127.0.0.1, kubernetes DNS 등을 SAN에 포함하고 있어. 우리 설정(10.32.0.1 등)도 이 규칙을 따른 거야.
  3. Service Account Key: API 서버 파드 옵션을 보면 --service-account-key-file--service-account-signing-key-file을 사용하여 토큰을 서명하고 검증해. 우리도 service-accounts.key를 생성해서 server로 보냈지.

다음 단계:
인증서 준비가 끝났으니, 이제 이 인증서들을 사용해서 Chapter 5. Kubernetes Configuration Files (kubeconfig) 생성 단계로 넘어가면 되겠어. 각 컴포넌트가 사용할 kubeconfig 파일을 만들어야 해.
이 이미지는 "쿠버네티스 The Hard Way"의 4단계(인증서)와 네트워크 설정이다.
두 가지 주제로 나누면 이해가 쉽다.

  1. 위쪽 파란 표: "누가 누구인가?" (신분증 리스트)
  2. 아래쪽 표: "어디에 사는가?" (네트워크 주소 지도)

1.인증서 (신분증 발급 리스트 ,위쪽 표)

쿠버네티스는 "모두가 서로를 의심하는 세계(Zero Trust)"다.
그래서 서버, 관리자, 노드 할 것 없이 전부 신분증(인증서)이 필요하다.

이 표는 "누구에게(Name), 어떤 권한(Group)으로 신분증을 만들어 줄 것인가?"를 정리한 것이다.

  • Root CA (ca.crt)
  • 역할: 대장. 얘가 도장을 찍어줘야 다른 인증서들이 효력이 생김.
  • 비유: 여권 발급해주는 외교부.
  • admin (admin.crt)
  • 역할: 나(관리자). kubectl 명령어를 칠 때 이 신분증을 쓴다.
  • 핵심: O = system:masters ← 이 부분이 "신(God)" 등급 권한을 의미함. 이게 없으면 명령 거부당함.
  • node-0, node-1 (node.crt)
  • 역할: 워커 노드들.
  • 핵심: CN에는 노드 이름이 들어가고, O = system:nodes 그룹에 속해야 노드로 인정받음.
  • kube-api-server (kube-api-server.crt)
  • 역할: ★제일 중요함. 클러스터의 대문(API 서버)이 쓰는 신분증.
  • 왜 복잡한가?: 얘는 별명(SAN: Subject Alternative Names)이 많아야 함.
  • "나 kubernetes야." (DNS)
  • "나 127.0.0.1이야." (로컬)
  • "나 10.32.0.1이야." (내부 서비스 IP)
  • 주의: 저기 적힌 IP 중 하나라도 빠지면 "너 가짜 사이트지?" 하고 통신 안 됨.
  • service-accounts
  • 역할: 파드(Pod)들이 API 서버랑 대화할 때 쓰는 토큰을 만들 때 사용하는 서명용 키.

2. 아래쪽 표: 네트워크

쿠버네티스는 IP 대역을 용도별로 철저하게 나눠 쓴다. "이 IP는 누구네 집 주소인가"를 정한 것이다.

  • Cluster CIDR (10.200.0.0/16)
  • 의미: 파드(Pod)들이 사용할 전체 IP 대역. (아파트 단지 전체)
  • 파드들은 이 안에서 IP를 하나씩 받는다.
  • Pod CIDR (10.200.0.0/24, 10.200.1.0/24)
  • 의미: 각 노드(동)마다 할당된 층수.
  • node-0에 뜨는 파드는 무조건 10.200.0.x를 받음.
  • node-1에 뜨는 파드는 무조건 10.200.1.x를 받음.
  • 이렇게 나눠야 라우팅이 쉬워짐.
  • Service CIDR (10.32.0.0/24)
  • 의미: 가상 IP 대역. (서비스용)
  • 실제 파드 IP가 아니라, 로드밸런싱 역할을 하는 '서비스(Service)'들이 쓰는 가짜 주소들.
  • api clusterIP (10.32.0.1)
  • 의미: Service CIDR첫 번째 IP는 관례적으로 API 서버가 가져감.
  • 클러스터 내부의 파드들이 "주인님(API 서버)!" 부를 때 이 IP(10.32.0.1)를 씀.
  • ★연결 고리: 위쪽 표 kube-api-server 인증서의 SAN10.32.0.1이 적혀있는 이유가 바로 이것 때문임.

한 줄 요약

  • 위쪽 표: "너는 관리자, 너는 노드1, 너는 API 서버..."라고 이름표 붙여주는 규칙.
  • 아래쪽 표: "파드는 200번지, 서비스는 32번지 써라"라고 나눠주는 규칙.


CFSSL은 한마디로 "Cloudflare가 만든 인증서 발급 자판기"다.

원래 리눅스에서 인증서 만들려면 openssl이라는 오래된 툴을 써야 하는데, 이게 설정 파일(cnf) 만들기도 어렵고 명령어가 너무 복잡하다.

그래서 Cloudflare 에서 내놓은 게 바로 CFSSL이다.


1. 왜 이걸 쓰는가? (openssl vs cfssl)

KTHW 가이드가 굳이 cfssl을 선택한 이유는 딱 하나다. "편하니까."

비교OpenSSL (구 방식)CFSSL (요즘 방식)
설정 방식이상한 문법의 .cnf 파일 작성깔끔한 JSON 파일 작성
명령어옵션이 수십 개라 외우기 힘듦gencert 하나면 끝
자동화스크립트 짜기 어려움JSON이라 자동화/API 연동 쉬움

내 생각:
openssl로 CA 만들고 서명하려면 명령어 3~4번 쳐야 하는데, cfssl은 JSON 파일 하나 던져주면 알아서 CA랑 키랑 인증서까지 한 방에 뱉어준다.

2. 작동 원리 (파이프라인)

명령어를 보면 항상 cfssl이랑 cfssljson이 세트로 다닌다.

cfssl gencert ... | cfssljson -bare admin

이게 무슨 짓이냐면:

  1. cfssl gencert ...:
  • "야, 이 JSON 설정대로 인증서 정보 좀 생성해봐."
  • 결과물: 화면(Standard Output)에 JSON 텍스트로 뿌려줌. (파일로 안 만들어줌)
  1. | (파이프):
  • 앞에서 뱉은 JSON 텍스트를 뒤로 넘김.
  1. cfssljson -bare admin:
  • "넘어온 JSON 데이터 받아서 실제 파일(.pem, .key)로 저장해."
  • 결과물: admin.pem, admin-key.pem, admin.csr 파일 3개 생성.

3. 세 줄 요약

  1. CFSSL은 복잡한 openssl 대신 쓰는 모던한 인증서 툴이다.
  2. 설정을 JSON으로 할 수 있어서 개발자가 읽고 쓰기 편하다.
  3. 명령어 칠 때 | cfssljson을 꼭 붙여야 실제 파일로 떨어진다.

profile
bytebliss

0개의 댓글