Post

[Security] TLS, HTTPS, 인증 토큰 그리고 Kafka 인증서 심화 정리

📌 들어가며

이번 글에서는 IT 보안의 기초인 TLS·HTTPS·인증 토큰을 비유로 정리하고, 나아가 쿠버네티스에서 Kafka(Strimzi)를 운영할 때 마주치는 복잡한 인증서 구조와 자동 갱신 메커니즘까지 심화 정리한다.

3대 요소 비유TLS(SSL)=도청 불가한 방음 터널/금고, 인증서(Certificate)=서버임을 증명하는 신분증/여권, CA(인증기관)=신분증이 진짜임을 보증하는 구청/발급 기관. 클라이언트는 서버 신분증을 검사하려면 CA Bundle(신뢰 기관 목록)을 반드시 가져야 한다.


1. TLS 핸드셰이크

TLS는 “느리지만 안전한 방식(공개키)으로 세션 키를 공유”한 뒤, “빠른 방식(대칭키)으로 데이터를 주고받는다.”

sequenceDiagram
    participant C as Client
    participant S as Server
    C->>S: ① Client Hello
    S->>C: ② 인증서(공개키) 전달
    C->>C: ③ CA 서명 검증
    C->>S: ④ 세션 키를 공개키로 잠가 전송
    S->>S: ⑤ 개인키로 열어 세션 키 획득
    C-->>S: ⑥ 세션 키(대칭키)로 빠른 암호화 통신
단계내용
핸드셰이크인증서 검증 + 세션 키 교환(공개키)
데이터 전송세션 키(대칭키)로 빠른 암호화 통신

💡 왜 공개키 → 대칭키인가 — 공개키 암호는 안전하지만 느리다. 그래서 세션 키를 나눌 때만 공개키를 쓰고, 실제 데이터는 빠른 대칭키(세션 키)로 처리한다. 안전함과 속도를 모두 잡는 방식이다.


2. HTTPS & TLS Termination

HTTPS = HTTP + TLS — HTTP라는 ‘편지 내용’은 그대로, TLS라는 ‘강철 금고’에 넣어 보내는 것이다.

TLS Termination(종단) — 쿠버네티스·클라우드의 표준 패턴이다.

flowchart LR
    User(("외부")) -- "HTTPS(암호)" --> Ing["Ingress<br/>(TLS 종료)"]
    Ing -- "HTTP(평문)" --> Pod["내부 Pod"]
구간프로토콜
외부 ↔ IngressHTTPS(보안 철저)
Ingress ↔ 내부 PodHTTP(가볍게)

💡 암호화/복호화 부하를 입구(Ingress)에서 한 번만 처리하고 내부는 평문으로 가볍게 통신한다. 각 Pod에 인증서를 심을 필요가 없어 관리가 단순해진다.


3. Bearer Token 인증

안전한 터널(TLS)이 연결된 뒤 “내가 누구인지” 증명하는 수단이다.

Bearer Token이란? “이 토큰을 소지한(Bearer) 사람에게 권한을 부여한다”는 방식. 현금(지폐)과 같아서, 잃어버리면 주운 사람이 주인 행세를 한다. 반드시 TLS 터널 안에서만 주고받아야 한다.

1
Authorization: Bearer <토큰문자열>

JWT 검증 원리 — 서버는 DB를 조회하지 않고 수학적 계산을 한다: ① 서버만 아는 비밀키(Secret Key)로 ② 토큰 서명이 풀리는지 계산 → ③ 맞으면 유효(위조 불가).

누가 무엇을 가지는가

구분클라이언트서버
역할서버를 의심·검사신분 증명
필요한 것CA Bundle(검증 도장 목록)인증서 + 개인키
토큰Access Token(입장권)Secret Key(검증용 비밀키)

4. Kafka(Strimzi) 인증서 심화

쿠버네티스에서 Kafka를 운영하면 여러 시크릿이 복잡하게 얽힌다. 핵심은 “검증용(공개)”과 “발급용(기밀)”을 물리적으로 분리하는 것이다.

CA 시크릿이 2개인 이유

시크릿파일비유역할보안
kafka-cluster-ca-certca.crt신분증 견본확인용공개(모두 가짐)
kafka-cluster-caca.key인감 도장발급(서명)용1급 기밀(오퍼레이터만)

⚠️ 브로커(Pod)조차 도장(ca.key)을 갖지 않는다. 오직 오퍼레이터만 금고에 보관한다. 인증서를 검증하는 것(ca.crt)과 발급하는 것(ca.key)을 분리해, 서명 권한이 유출되지 않게 하는 보안 원칙이다.

클라이언트 신뢰 저장소 (ca.crt vs ca.p12)

파일형식주 사용자
ca.crtPEMPython·Go·Node·curl
ca.p12PKCS#12(암호)Java(Spring Boot)
ca.password비밀번호ca.p12 열 때

최종 사용자 인증서 & 신뢰의 사슬

파일비유공개
tls.crt내 여권공개
tls.key내 지문절대 비밀
1
2
3
4
신뢰의 사슬(Chain of Trust)
① 오퍼레이터가 ca.key(도장)로 tls.crt(여권)를 서명
② 브로커가 tls.crt를 들고 통신 시도
③ 상대방이 ca.crt(견본)로 "진짜 도장이네" 하고 신뢰

자동 갱신 & 확인

Strimzi는 별도 설정이 없으면 자동 갱신이 기본값이다.

1
2
3
4
spec:
  clientsCa:
    generateCertificateAuthority: true
    renewalDays: 30    # 만료 30일 전 갱신
1
2
3
# 만료일 확인
kubectl get secret kafka-clients-ca-cert \
  -o jsonpath="{.data['ca\.crt']}" | base64 -d | openssl x509 -noout -dates

💡 시크릿의 managedFields를 보면 누가 갱신했는지 알 수 있다. manager: strimzi-cluster-operator면 자동 갱신, kubectl-client-side-apply면 사람이 수동 수정한 것이다. 인증서 문제 추적 시 유용하다.


📝 정리

1
2
3
4
5
TLS·인증
├─ TLS      핸드셰이크(공개키로 세션키 교환) → 대칭키 통신
├─ HTTPS    HTTP+TLS, Ingress에서 TLS 종료
├─ 토큰      Bearer=현금, TLS 안에서만, JWT는 서명 계산
└─ Kafka CA 검증용(ca.crt·공개) vs 발급용(ca.key·기밀) 분리
개념한 줄 정의
TLS암호화 통신 터널
CA Bundle신뢰 기관 목록(검증용)
Bearer Token소지자에게 권한 부여

보안의 핵심은 TLS로 터널을 만들고(암호화), 인증서로 상대를 검증하며(신원), 토큰으로 권한을 증명하는 3단 구조다. Kafka 인증서에서 보듯, 검증용(공개)과 발급용(기밀)을 분리하는 것이 신뢰 체계의 근간이다.

This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.