백엔드 데이터 인프라 71편 — Redis TLS (전송 암호화 · mTLS)

2026-05-17백엔드 데이터 인프라

백엔드 데이터 인프라 71편. Redis TLS — 클라이언트·replication·cluster bus 전송 암호화. tls-cert-file·tls-key-file·tls-ca-cert-file 설정, mTLS (client cert 인증), Spring Boot 통합, 성능 부담과 절충까지 풀어쓴 학습 노트.

📚 백엔드 데이터 인프라 · 71편 — Redis TLS (전송 암호화 · mTLS)

이 글은 백엔드 데이터 인프라 시리즈 130편 중 71편이에요. 70편 에서 인증·권한 관리 를 풀었다면, 보안의 두 번째 — TLS (전송 암호화). Part 4-5 운영의 마지막 글이고, 보안의 두 번째 축.

Redis TLS가 어렵게 느껴지는 이유

TLS 자체는 HTTPS 와 동일 한 개념인데, Redis 특유의 자리가 두 가지예요.

첫째로 여러 통신 경로가 있어요. 클라이언트-Redis 외에 Redis 끼리 (replication), Sentinel 끼리, Cluster bus 등 모두 별도로 TLS 활성화가 필요한데, 한 가지만 켜면 나머지 통신은 평문 그대로예요.

둘째는 Build-time 옵션이에요. Redis 가 기본 빌드에 TLS 미포함이라 make BUILD_TLS=yes 로 컴파일하거나 TLS 포함 빌드된 패키지 를 써야 해요. 기본 docker 이미지·apt 패키지 중에 TLS 빠진 것이 있어요.

이 글에서 TLS 빌드·기본 설정·mTLS (상호 TLS 인증)·각 통신 경로별 설정·성능 부담·운영 가이드 정리.

TLS 빌드 + 기본 설정

빌드

make BUILD_TLS=yes

OpenSSL 개발 라이브러리 (libssl-dev 등) 필요. 공식 docker 이미지TLS 포함 변형 도 있음 (redis:7-alpine-tls 같은).

인증서 준비

자체 CA (인증 기관) 또는 외부 CA (Let's Encrypt 등):

# 자체 CA
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha256 -key ca.key -days 3650 -out ca.crt

# Redis 서버 키·인증서
openssl genrsa -out redis.key 2048
openssl req -new -sha256 -key redis.key -out redis.csr
openssl x509 -req -sha256 -in redis.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 365 -out redis.crt

# DH params (Diffie-Hellman 키 교환 파라미터, 선택)
openssl dhparam -out redis.dh 2048

redis.conf

tls-cert-file /etc/redis/tls/redis.crt
tls-key-file /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crt
tls-dh-params-file /etc/redis/tls/redis.dh

# TLS 전용 포트
tls-port 6379

# 평문 비활성
port 0

port 0 으로 평문 비활성. 평문·TLS 둘 다 듣게 하려면 두 포트 모두 박음:

port 6379          # 평문 (개발용, 같은 머신만)
tls-port 6380      # TLS (외부)

클라이언트 - Redis 통신 TLS

Python (redis-py)

import redis

r = redis.Redis(
    host="redis-host",
    port=6379,
    ssl=True,
    ssl_ca_certs="/path/to/ca.crt",
)
r.set("key", "value")

Java (Lettuce / Spring Data Redis)

spring:
  data:
    redis:
      host: redis-host
      port: 6379
      ssl:
        enabled: true
        bundle: redis-tls
spring.ssl.bundle.jks.redis-tls:
  truststore:
    location: classpath:redis-ca.jks
    password: trust-pass

mTLS — Client Certificate 인증

기본 = Redis 가 클라이언트의 인증서를 요구. 클라이언트도 키·인증서 필요.

서버 측 설정

tls-auth-clients yes        # 기본값, mTLS 활성
# 또는
tls-auth-clients optional   # 인증서 있으면 검증, 없어도 OK
# 또는
tls-auth-clients no         # 클라이언트 인증서 요구 안 함

클라이언트 측 — Python

r = redis.Redis(
    host="redis-host",
    port=6379,
    ssl=True,
    ssl_ca_certs="/path/to/ca.crt",
    ssl_certfile="/path/to/client.crt",
    ssl_keyfile="/path/to/client.key",
)

mTLS 장점 — 비밀번호 + 인증서 이중 인증. 비밀번호만보다 훨씬 강한 보안. 단점 — 클라이언트 인증서 배포·관리 복잡.

Replication TLS

여기서 시험 함정이 하나 있어요 — Replication 통신은 별도 설정 필요.

# replica 측
tls-replication yes

이 옵션 없으면 master-replica 사이 가 평문 → 복제 데이터 도청 위험. 공용 클라우드의 다른 AZ (가용 영역)·리전 환경에서 특히 중요.

Cluster Bus TLS

Cluster 환경에서 노드 간 gossip (노드끼리 상태 교환) 통신 도 별도:

tls-cluster yes

활성 시 cluster bus 포트 (master port + 10000) 도 TLS.

Sentinel TLS

Sentinel ↔ Sentinel, Sentinel ↔ Redis 모두 TLS:

# sentinel.conf
tls-port 26379
tls-cert-file ...
tls-key-file ...
tls-ca-cert-file ...
tls-replication yes
tls-cluster yes        # Sentinel 이 cluster 환경 모니터링 시

TLS 프로토콜·암호 슈트 설정

tls-protocols "TLSv1.2 TLSv1.3"
tls-ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:..."
tls-ciphersuites "TLS_AES_128_GCM_SHA256:..."

권장:

  • TLSv1.2 + TLSv1.3 (이전 버전 차단)
  • 현대적 AEAD (인증 + 암호화 결합 모드) 암호 슈트만

운영 환경에서는 조직 보안 정책 따라.

성능 부담

TLS 핸드셰이크 + 암호화 = CPU 부담 증가. 측정:

  • 단순 GET 처리량: 평문 100,000 req/sec → TLS 70,000~85,000 req/sec
  • 한 번 연결 후 재사용 (connection pool) 하면 핸드셰이크 부담 한 번만

권장:

  • Connection pool 필수
  • AES-NI hardware acceleration (CPU 내장 암호 가속) 활용
  • 매우 트래픽 큰 환경 = TLS termination proxy (HAProxy 등) 로 분리 검토

운영 환경 권장 설정

환경 TLS mTLS
로컬 개발 X X
같은 머신 (Unix socket) X X
같은 VPC (가상 사설망) + 같은 AZ △ (선택) X
다른 AZ·리전 (공용 네트워크) △ (선택)
인터넷 노출
금융·법적 보장

여기서 정말 중요한 자리 — VPC 안이라고 안전한 게 아님. 다른 사용자의 워크로드와 같은 물리 호스트 또는 클라우드 백본 네트워크 도청 가능성완전 안전한 망은 없음. 의심스러우면 TLS 활성.

한계·실무 함정

1. 빌드에 TLS 미포함

위에서 언급. 반드시 TLS 포함 빌드 확인.

> redis-cli INFO server | grep tls
tls_enabled:1

2. 인증서 만료

Let's Encrypt 같은 90일 인증서 사용 시 자동 갱신 + Redis reload. 만료 후 클라이언트 연결 거부.

3. CA 인증서 분리·관리

서버 CA + 클라이언트 CA 분리하면 권한 분리 유리. 단순 환경은 한 CA.

4. 비TLS 포트 남겨 두면 우회 가능

port 6379 평문 + tls-port 6380 TLS 동시 운영 시 방화벽으로 6379 차단 안 하면 평문 우회 접근. 운영 환경 = port 0 으로 평문 완전 비활성.

5. 클라이언트 라이브러리 TLS 지원 확인

오래된 클라이언트는 TLS 미지원 또는 mTLS 미지원. 도입 전 라이브러리 버전 확인.

6. Replication TLS 안 켜면 평문 복제

위에서 강조. tls-replication yes 필수.

시험 직전 한 번 더 — Redis TLS 함정 압축 노트

  • Redis TLS = Redis 6+ 부터 옵션
  • 빌드 = make BUILD_TLS=yes (기본 빌드에 미포함)
  • 포함 빌드 확인 = INFO server | grep tls_enabled
  • 설정 = tls-cert-file·tls-key-file·tls-ca-cert-file (+ 선택 tls-dh-params-file)
  • tls-port 6379 = TLS 전용 포트
  • port 0 = 평문 완전 비활성 (운영 환경 표준)
  • mTLS = tls-auth-clients yes (기본값) → 클라이언트 인증서 요구
  • mTLS = 비밀번호 + 인증서 이중 인증
  • tls-replication yes = master-replica 통신 TLS (별도 옵션)
  • tls-cluster yes = cluster bus 통신 TLS
  • 클라이언트 - Sentinel TLS = sentinel.conf 별도 설정
  • 클라이언트 — Python ssl=True + ssl_ca_certs / Java spring.data.redis.ssl.enabled=true
  • mTLS 클라이언트 = ssl_certfile + ssl_keyfile
  • 프로토콜 권장 = TLSv1.2 + TLSv1.3 (이전 차단)
  • 암호 슈트 = 현대 AEAD (ECDHE-*-GCM-SHA256 등)
  • 성능 부담 = 평문 대비 ~15~30% 감소
  • 완화 = Connection pool 필수 + AES-NI 활용 + TLS termination proxy
  • 환경별 — 로컬/같은 머신 X / 같은 VPC △ / 다른 AZ ◯ / 인터넷 ◯ / 금융 ◯
  • VPC 안도 안전 X — 의심스러우면 TLS 활성
  • 함정 — 빌드에 TLS 미포함 → 첫 도입 시 확인
  • 함정 — 인증서 만료 → 자동 갱신 + reload
  • 함정 — 평문 포트 남겨 두면 우회 → port 0
  • 함정 — Replication TLS 별도 옵션 → 안 켜면 평문 복제
  • 함정 — 오래된 클라이언트 mTLS 미지원

공식 문서: Redis TLS 에서 자세한 설정·운영 가이드를 확인할 수 있어요.

시리즈 다른 편 (앞뒤 글 모음)

이전 글:

다음 글:

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

답글 남기기

error: Content is protected !!