웹 서버·WAS 용어 사전
TLSTLS termination · SSL 종료 · 재암호화 · 패스스루

TLS 종단

암호화를 어디서 푸느냐. 내부 신뢰 여부와 L7 기능 필요 여부로 결정한다.

암호화를 어디서 푸느냐의 문제. 이 지점이 구조를 결정한다.

클라이언트 ══암호화══> [ 여기서 푼다 ] ──평문──> 애플리케이션
                          ↑
                     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를 넘기지 않으면 애플리케이션이 깨진다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — TLS 종단과 HTTP/2·3