이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • TLS는 어떤 구간을 보호하고 어떤 애플리케이션 보안 문제를 해결하지 못하는가?
  • 인증서, private key, chain, HSTS, 만료 알림은 운영에서 어떻게 관리해야 하는가?
  • 내부 서비스 통신에서 mTLS를 검토해야 하는 기준은 무엇인가?

개요

TLS는 client와 server 사이의 전송 구간에서 도청, 변조, 일부 위조를 막기 위한 프로토콜이다. HTTPS는 TLS 위에서 HTTP를 보내는 대표적인 사용 방식이다.

TLS가 있다고 해서 인증, 권한 검사, 입력 검증, 저장 데이터 암호화가 자동으로 해결되지는 않는다. TLS는 네트워크 경로를 보호하지만 서버에 도착한 요청이 올바른 권한인지 판단하지 않는다.

운영에서 TLS 문제는 보안 사고이면서 장애다. 인증서 만료, 중간 인증서 누락, 잘못된 SAN, 약한 protocol/cipher 허용, private key 유출은 모두 서비스 중단 또는 중간자 공격 위험으로 이어질 수 있다.

이 문서의 핵심은 “HTTPS 적용”이 아니라 “인증서와 key의 발급, 배포, 갱신, 폐기를 자동화하고 검증한다”는 것이다.

공격 시나리오

  • 공격자는 공용 Wi-Fi나 사내 proxy 지점에서 HTTP 트래픽을 가로채 session cookie를 훔친다.
  • HSTS가 없으면 사용자가 처음 HTTP로 접속할 때 downgrade 또는 SSL stripping 공격을 시도한다.
  • 만료된 인증서로 서비스가 중단되면 운영자가 임시로 검증을 끄거나 우회 설정을 넣는다.
  • private key가 container image나 backup에 남으면 공격자는 같은 도메인으로 위장할 수 있다.
  • 내부 서비스가 평문 HTTP로 통신하면 내부망 접근자가 token과 개인정보를 볼 수 있다.
  • client가 인증서 검증을 끄면 공격자 proxy가 API 응답을 변조할 수 있다.

취약한 요청/응답 예시

GET /login HTTP/1.1
Host: app.example.com
Cookie: SESSION=abc123
httpClient:
  tls:
    trustAll: true
    hostnameVerification: false
level=WARN event=tls_certificate_expired domain=app.example.com expiredAt=2026-06-29T00:00:00Z action=manual_override

문제는 전송 구간 보호가 없거나 인증서 검증을 꺼 두고, 만료 대응이 수동 override로 흐른다는 점이다.

주제별 핵심 판단

  • TLS는 전송 중 기밀성과 무결성을 제공한다.
  • 인증서는 서버 identity를 증명하고 private key는 그 identity의 핵심 secret이다.
  • 인증서 chain과 SAN이 올바르지 않으면 client 검증이 실패한다.
  • HSTS는 브라우저가 HTTP로 접속하지 않도록 돕는다.
  • TLS 1.2 이상, 가능하면 TLS 1.3을 기준으로 약한 protocol과 cipher를 제거한다.
  • 내부 통신도 민감 데이터가 오가면 TLS 또는 mTLS를 검토한다.
  • 인증서 자동 갱신과 만료 모니터링은 배포 파이프라인의 일부다.

개선된 요청/응답 예시

HTTP/1.1 200 OK
Strict-Transport-Security: max-age=31536000; includeSubDomains
Set-Cookie: SESSION=abc123; Secure; HttpOnly; SameSite=Lax
level=INFO event=tls_certificate_renewed result=allowed domain=app.example.com issuer=letsencrypt notAfter=2026-09-28T00:00:00Z automation=acme traceId=4db73e21

브라우저에는 HSTS와 Secure cookie를 제공하고, 운영에는 인증서 자동 갱신과 만료 알림을 둔다.

방어 설계

  • 모든 public endpoint는 HTTPS로만 제공하고 HTTP는 HTTPS로 redirect한다.
  • HSTS는 subdomain 영향과 preload 여부를 검토한 뒤 적용한다.
  • session cookie는 Secure, HttpOnly, SameSite 속성을 가진다.
  • TLS termination 위치를 명확히 하고 reverse proxy와 application 사이 구간도 보호한다.
  • 인증서 private key는 secret manager, HSM, KMS, ingress controller secret 등 제한된 저장소에서 관리한다.
  • 인증서 만료, chain 오류, hostname mismatch를 외부 synthetic monitoring으로 감시한다.
  • 내부 service-to-service 통신은 데이터 민감도와 네트워크 신뢰 수준에 따라 mTLS를 적용한다.
  • 인증서 교체와 key compromise 대응 runbook을 만든다.

Spring/HTTP 예시

@Bean
SecurityFilterChain tlsAwareSecurity(HttpSecurity http) throws Exception {
    return http
        .requiresChannel(channel -> channel
            .anyRequest().requiresSecure())
        .headers(headers -> headers
            .httpStrictTransportSecurity(hsts -> hsts
                .includeSubDomains(true)
                .maxAgeInSeconds(31536000)))
        .build();
}
server:
  forward-headers-strategy: framework

reverse proxy 뒤의 Spring 애플리케이션은 X-Forwarded-Proto 처리를 정확히 해야 한다. 그렇지 않으면 HTTPS 사용자를 HTTP로 잘못 판단하거나 redirect loop가 생길 수 있다.

운영 로그와 감사 지점

level=WARN event=tls_certificate_expiring result=review_required domain=app.example.com daysRemaining=14 issuer=letsencrypt traceId=4db73e21
level=ERROR event=tls_private_key_exposure result=incident domain=app.example.com location=container-image action=rotate_certificate traceId=4db73e21
  • 인증서 만료일, issuer, SAN, chain 상태를 모니터링한다.
  • private key 접근과 배포 이벤트를 감사 로그로 남긴다.
  • HTTP 요청이 들어오면 redirect 비율과 원인을 추적한다.
  • TLS handshake 실패율과 protocol/cipher 분포를 관찰한다.
  • key compromise 시 새 key pair 발급, 인증서 폐기, 배포, cache 영향 확인까지 추적한다.

실전 판단 기준

  • TLS termination이 load balancer에서 끝나면 내부 구간 보호를 별도로 확인해야 한다.
  • HSTS는 강력하지만 잘못 적용하면 하위 도메인 복구가 어렵다.
  • 인증서 자동 갱신은 갱신 성공뿐 아니라 실제 reload 여부까지 확인해야 한다.
  • client에서 hostname verification을 끄는 것은 테스트 편의가 운영 취약점으로 남기 쉽다.
  • mTLS는 내부 신뢰 경계를 강화하지만 인증서 발급/폐기 운영 비용이 따른다.
  • TLS는 권한 검사를 대체하지 않는다. HTTPS 요청도 공격 요청일 수 있다.

테스트 포인트

  • HTTP 접속이 HTTPS로 redirect되고 session cookie가 Secure인지 확인한다.
  • HSTS header가 의도한 domain과 max-age로 나가는지 확인한다.
  • 인증서 chain, SAN, 만료일을 외부에서 검증한다.
  • TLS 1.0/1.1과 약한 cipher가 비활성화되어 있는지 확인한다.
  • reverse proxy 뒤에서 scheme 인식과 redirect가 정상인지 확인한다.
  • 인증서 갱신 후 서비스 reload가 실제로 되었는지 확인한다.
  • 내부 API client가 인증서 검증을 끄지 않았는지 확인한다.

위험 신호!

  • 운영 client에 trustAll 또는 hostnameVerification=false가 있다.
  • 인증서 만료 알림이 수동 캘린더뿐이다.
  • private key가 git, image, backup에 들어 있다.
  • TLS termination 이후 내부 구간이 민감 데이터를 평문으로 보낸다.
  • HSTS 적용 범위와 하위 도메인 영향을 아무도 모른다.
  • 만료 사고 때 임시로 HTTP를 열자는 runbook이 있다.

확인 질문

확인 질문

  • TLS가 해결하는 문제는 무엇인가?
    • 전송 구간의 도청과 변조를 줄이고 서버 identity를 검증하도록 돕는다.
  • TLS가 해결하지 못하는 문제는 무엇인가?
    • 애플리케이션 권한 검사, 입력 검증, 저장 데이터 보호, 비밀번호 저장 정책은 해결하지 못한다.
  • 인증서 운영에서 가장 중요한 자동화는 무엇인가?
    • 발급, 배포, reload, 만료 모니터링, 폐기와 key compromise 대응 자동화다.

참고 문서