SSL 종료
SSL Termination
로드밸런서에서 SSL 복호화. 백엔드 부하 감소.
SSL Termination
로드밸런서에서 SSL 복호화. 백엔드 부하 감소.
SSL 종료(SSL Termination, 또는 TLS Termination)는 로드밸런서나 리버스 프록시에서 암호화된 HTTPS 연결을 복호화하고, 백엔드 서버와는 평문 HTTP로 통신하는 아키텍처 패턴입니다. 클라이언트 → 로드밸런서 구간만 암호화되고, 로드밸런서 → 백엔드 서버 구간은 암호화되지 않습니다.
SSL/TLS 암호화와 복호화는 CPU 집약적인 작업입니다. 특히 TLS 핸드셰이크 과정에서 RSA 2048비트 키 교환은 단일 연결당 수 밀리초의 CPU 시간을 소모합니다. SSL 종료를 적용하면 이 부하가 전용 로드밸런서로 집중되어, 백엔드 서버는 비즈니스 로직에만 집중할 수 있습니다. AWS ALB에서는 초당 수만 개의 TLS 연결을 처리할 수 있습니다.
인증서 관리도 대폭 간소화됩니다. SSL 종료 없이는 모든 백엔드 서버에 인증서를 설치하고 갱신해야 하지만, SSL 종료를 사용하면 로드밸런서 한 곳에서만 인증서를 관리하면 됩니다. Let's Encrypt 자동 갱신이나 AWS Certificate Manager 같은 서비스와 결합하면 인증서 만료로 인한 장애 위험을 크게 줄일 수 있습니다.
보안 관점에서 SSL 종료는 트레이드오프가 있습니다. 내부 네트워크 구간이 평문으로 노출되므로, 신뢰할 수 있는 프라이빗 네트워크(VPC) 내에서만 사용해야 합니다. 금융, 의료 등 규제가 엄격한 환경에서는 end-to-end 암호화를 요구하는 경우가 있어, SSL Passthrough나 Re-encryption을 고려해야 할 수 있습니다.
# Nginx SSL 종료 설정
# /etc/nginx/conf.d/ssl-termination.conf
upstream backend_servers {
server 10.0.1.10:8080; # 백엔드는 HTTP (8080)
server 10.0.1.11:8080;
server 10.0.1.12:8080;
keepalive 32;
}
server {
listen 443 ssl http2;
server_name example.com;
# SSL 인증서 (Let's Encrypt 또는 상용 인증서)
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# 최신 TLS 보안 설정
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# OCSP Stapling (인증서 유효성 검증 가속화)
ssl_stapling on;
ssl_stapling_verify on;
# 백엔드로 HTTP 평문 전달
location / {
proxy_pass http://backend_servers;
proxy_http_version 1.1;
proxy_set_header Connection "";
# 원본 클라이언트 정보 전달
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; # https
}
}
# HTTP → HTTPS 리다이렉트
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
# HAProxy SSL 종료 설정
# /etc/haproxy/haproxy.cfg
global
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
ssl-default-bind-options ssl-min-ver TLSv1.2
tune.ssl.default-dh-param 2048
maxconn 50000
defaults
mode http
timeout connect 5s
timeout client 30s
timeout server 30s
option httplog
# HTTPS 프론트엔드 (SSL 종료 지점)
frontend https_front
bind *:443 ssl crt /etc/haproxy/certs/example.com.pem
# HSTS 헤더 추가
http-response set-header Strict-Transport-Security "max-age=31536000"
# 원본 정보 헤더 추가
http-request set-header X-Forwarded-Proto https
http-request set-header X-Real-IP %[src]
default_backend http_back
# HTTP 리다이렉트
frontend http_front
bind *:80
redirect scheme https code 301
# 백엔드 (평문 HTTP)
backend http_back
balance roundrobin
option httpchk GET /health
server web1 10.0.1.10:8080 check
server web2 10.0.1.11:8080 check
server web3 10.0.1.12:8080 check
# AWS ALB SSL 종료 - Terraform 설정
# main.tf
# ACM 인증서 (자동 갱신)
resource "aws_acm_certificate" "main" {
domain_name = "example.com"
validation_method = "DNS"
lifecycle {
create_before_destroy = true
}
}
# Application Load Balancer
resource "aws_lb" "main" {
name = "main-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = var.public_subnets
}
# HTTPS 리스너 (SSL 종료)
resource "aws_lb_listener" "https" {
load_balancer_arn = aws_lb.main.arn
port = 443
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
certificate_arn = aws_acm_certificate.main.arn
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.main.arn
}
}
# HTTP → HTTPS 리다이렉트
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = 80
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
# 타겟 그룹 (백엔드는 HTTP)
resource "aws_lb_target_group" "main" {
name = "main-tg"
port = 8080 # 백엔드는 평문 HTTP
protocol = "HTTP" # SSL 없음
vpc_id = var.vpc_id
health_check {
path = "/health"
healthy_threshold = 2
unhealthy_threshold = 3
}
}
"SSL 종료를 ALB에서 처리하면 백엔드 EC2의 CPU 부하를 20-30% 줄일 수 있습니다. 인증서 관리도 ACM에서 자동 갱신되니까 운영 부담이 크게 줄어요. 다만 ALB와 백엔드 간 통신은 평문이니까 VPC 내부에서만 트래픽이 흐르도록 보안 그룹 설정을 확실히 해야 합니다."
"규제 요건상 end-to-end 암호화가 필요하다면 SSL Passthrough나 Re-encryption을 써야 합니다. Passthrough는 로드밸런서가 암호화를 건드리지 않고 그대로 전달하는 방식이고, Re-encryption은 로드밸런서에서 복호화 후 다시 암호화해서 백엔드로 보내는 방식입니다. 성능과 보안 사이의 트레이드오프를 고려해서 선택하시면 됩니다."
"백엔드에서 X-Forwarded-Proto 헤더를 확인해보세요. SSL 종료 후 프록시가 이 헤더를 설정해줘야 앱에서 HTTPS 요청인지 알 수 있습니다. 이 헤더가 없으면 앱이 HTTP로 인식해서 무한 리다이렉트 루프가 발생할 수 있어요."
SSL 종료 후 백엔드 구간이 평문이므로, 반드시 VPC/프라이빗 네트워크 내에서만 통신해야 합니다. 퍼블릭 네트워크에서 평문 통신은 중간자 공격(MITM) 위험이 있습니다.
SSL 종료 후 X-Forwarded-Proto, X-Forwarded-For 헤더를 설정하지 않으면 백엔드에서 원본 클라이언트 IP와 프로토콜을 알 수 없습니다. 로깅, 보안 정책, HTTPS 리다이렉트 로직이 오작동합니다.
SSL 종료 지점의 인증서가 만료되면 전체 서비스가 다운됩니다. ACM 자동 갱신을 사용하거나, certbot 자동화와 함께 만료 30일 전 알림을 설정하세요.
TLS 1.2 이상만 허용, HSTS 헤더 설정, 강력한 암호화 스위트 사용. AWS라면 ELBSecurityPolicy-TLS13-1-2-2021-06 이상의 정책을 적용하고, CloudWatch로 SSL 핸드셰이크 오류를 모니터링하세요.