암호화를 어디서 푸느냐의 문제. 이 지점이 구조를 결정한다.
클라이언트 ══암호화══> [ 여기서 푼다 ] ──평문──> 애플리케이션
↑
TLS 종단 지점
네 가지 배치
-
① LB 에서 종단
- ALB · CLB 가 인증서를 들고 푼다. 뒤는 평문 HTTP
- 관리가 가장 단순하다. 내부망도 못 믿는 요건이면 부적합
-
② 웹 서버(nginx)에서
- 가장 흔한 구성. 캐시·압축·라우팅을 여기서 다 한다
-
③ 종단 간 암호화 (패스스루)
- LB 는 L4 로 그냥 흘려보낸다
- LB 가 경로·헤더를 못 보므로 L7 기능을 쓸 수 없다
- (경로 기반 라우팅 · 헤더 조작 · WAF · 캐시가 전부 불가)
-
④ 재암호화 (re-encrypt)
- 앞에서 풀고, 뒤로 보낼 때 다시 암호화한다
- L7 기능도 쓰고 내부 구간도 암호화한다. 비용이 두 배
- 규제 요건에서 흔하다
판단 기준 — "내부 구간을 신뢰할 수 있는가" 와 "L7 기능이 필요한가" 의 조합이다. 둘 다 필요하면 ④, 내부를 신뢰하면 ①·②.
종단하면 따라오는 책임
푼 쪽이 아래를 전부 맡게 된다
-
인증서 관리와 갱신
-
프로토콜·암호 스위트 정책 (TLSv1.2/1.3)
-
보안 헤더 (HSTS 등)
-
뒤로 원래 스킴을 알려 주기 (X-Forwarded-Proto)
-
마지막 항목을 빠뜨리면 애플리케이션이 http 로 착각한다
-
https 페이지에서 http 리다이렉트 → 무한 루프 · 혼합 콘텐츠 차단
기본 설정
server {
listen 443 ssl;
http2 on;
ssl_certificate /etc/ssl/fullchain.pem;
ssl_certificate_key /etc/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
}
server {
listen 80;
return 301 https://$host$request_uri;
}
세션 재개
-
ssl_session_cache — 서버가 세션을 기억한다 (서버 쪽 상태)
- 인스턴스가 여럿이면 캐시가 공유되지 않아 적중률이 떨어진다
-
ssl_session_tickets — 세션 정보를 암호화해 클라이언트에게 맡긴다 (서버 무상태)
- 티켓 키를 주기적으로 교체하지 않으면
- 전방향 비밀성이 약해진다
-
키 회전을 자동화하기 어려운 환경이면 tickets off + cache 조합이 안전하다
암호 스위트와 프로토콜 정책
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...;
ssl_prefer_server_ciphers off;
TLS 1.0/1.1 은 폐기됐다 — 켜 두면 취약점 스캔에서 잡힌다 TLS 1.3 은 안전한 스위트만 남겨 놨으므로 ciphers 를 직접 나열할 필요가 없다 prefer_server_ciphers 는 1.3 에서 의미가 없다 (클라이언트 선호를 따른다)
호환성 요건이 있으면 '어떤 클라이언트를 지원해야 하는지' 를 먼저 정한다 막연히 넓게 열어 두는 것이 가장 나쁜 선택이다
보안 헤더의 상속 함정
add_header Strict-Transport-Security "max-age=31536000" always;
always 를 안 붙이면 4xx·5xx 응답에는 헤더가 안 붙는다
그리고 nginx 의 add_header 는 상속이 특이하다 — 하위 블록에서 add_header 를 '하나라도' 쓰면 상위의 것이 전부 사라진다
- 공통 헤더는 별도 파일로 만들어 각 블록에서 include 한다
HSTS 는 되돌리기 어렵다 — max-age 동안 브라우저가 http 접속을 거부한다
- 짧은 값으로 시작해 검증 후 늘린다. preload 는 특히 신중하게
면접 함정
- ❌ "종단 간 암호화가 언제나 낫다" → L7 기능을 통째로 포기하게 된다.
- ❌ "LB에서 풀었으니 뒤는 신경 안 써도 된다" →
X-Forwarded-Proto를 넘기지 않으면 애플리케이션이 깨진다.