fos-blog/study
01 / 홈02 / 카테고리03 / 시리즈
01 / 홈02 / 카테고리03 / 시리즈

카테고리

  • AI 페이지로 이동
    • RAG 페이지로 이동
    • langgraph 페이지로 이동
    • agents.md
    • BMAD Method — AI 에이전트로 애자일 개발하는 방법론
    • Claude Code 메모리: CLAUDE.md와 .claude/rules를 규칙으로 쓰는 법
    • Claude Code의 Skill 시스템 - 개발자를 위한 AI 자동화의 새로운 차원
    • Claude Code를 5주 더 쓴 결과 — 스킬·CLAUDE.md를 키워가는 방식
    • Claude Code를 11일 동안 쓴 결과 — 데이터로 본 나의 사용 패턴
    • Claude Code 멀티 에이전트 — Teams
    • AI 에이전트와 디자인의 새 컨벤션 — DESIGN.md, Google Stitch, Claude Design
    • Docling — IBM Research 의 문서 파싱 toolkit 상세 정리
    • 하네스 엔지니어링 실전 — 4인 에이전트 팀으로 코딩 파이프라인 구축하기
    • 하네스 엔지니어링 — 오래 실행되는 AI 에이전트를 위한 설계
    • 멀티모달 LLM (Multimodal Large Language Model)
    • AI 에이전트와 함께 MVP 만들기 — dooray-cli 사례
    • 스킬 문서를 신경망처럼 학습시킨다 — Microsoft SkillOpt 분석
  • ai 페이지로 이동
    • agent 페이지로 이동
    • [초안] AI 제품 백엔드 안정성 — 지연·비용·권한·관측·도구 실패·폴백/재시도/사람 에스컬레이션
    • [초안] LLM 평가 프레임워크: 골든셋, 회귀 테스트, LLM-as-a-judge, 사람 피드백 루프
  • algorithm 페이지로 이동
    • live-coding 페이지로 이동
    • 분산 계산을 위한 알고리즘
  • apartment 페이지로 이동
    • 구리 럭키아파트 24평 인테리어 레퍼런스 모음
  • architecture 페이지로 이동
    • [초안] 시니어 백엔드를 위한 API 설계 실전 스터디 팩 — REST · 멱등성 · 페이지네이션 · 버전 전략
    • [초안] API Versioning과 Backward Compatibility: 시니어 백엔드 관점 정리
    • 캐시 설계 전략 총정리
    • [초안] CJ푸드빌 디지털 채널 면접: 슬롯 도메인 경험을 커머스 도메인 설계 능력으로 번역하기
    • [초안] 커머스 Spring 서비스에 Clean/Hexagonal Architecture를 실용적으로 적용하기
    • [초안] 커머스 도메인 모델링: 주문·재고·노출의 세 축을 분리해서 설계하기
    • 커머스 주문 상태와 데이터 정합성 기본기 — CJ푸드빌 면접 대비
    • [초안] 쿠폰/프로모션 동시성과 정합성 기본기 — 선착순·중복 사용 방지·발급/사용/복구
    • [초안] DDD와 도메인 모델링: 시니어 백엔드 관점의 전술/전략 패턴 실전 가이드
    • [초안] Decorator & Chain of Responsibility — 행동을 체인으로 조립하는 두 가지 방식
    • 디자인 패턴
    • [초안] 분산 아키텍처 완전 정복: Java 백엔드 시니어 인터뷰 대비 실전 가이드
    • [초안] 분산 트랜잭션과 Outbox 패턴 — 왜 2PC를 피하고 어떻게 대신할 것인가
    • 분산 트랜잭션
    • [초안] e-Commerce 주문·결제 도메인 모델링: 상태머신, 멱등성, Outbox/Saga 실전 정리
    • [초안] F&B 쿠폰·프로모션·멤버십·포인트 설계
    • [초안] F&B · e-Commerce 디지털 채널 도메인 한 장 정리 — CJ푸드빌 디지털 채널 백엔드 면접 대비
    • [초안] F&B 주문/매장/픽업 상태머신 설계 — CJ푸드빌 디지털 채널 백엔드 관점
    • [초안] F&B 이커머스 결제·환불·정산 운영 가이드
    • [초안] Hexagonal / Clean Architecture를 Spring 백엔드에 적용하기
    • [초안] 대규모 커머스 트래픽 처리 패턴 — 1,600만 고객과 올영세일을 버티는 설계
    • [초안] 레거시 JSP/jQuery 화면과 신규 API가 공존하는 백엔드 운영 전략
    • [초안] MSA 서비스 간 통신: Redis [Cache-Aside](../database/redis/cache-aside.md) × Kafka 이벤트 하이브리드 설계
    • [초안] Observability 입문: 시니어 백엔드가 장애를 탐지하고 대응하는 방식
    • [초안] Outbox / Inbox Pattern 심화 — 분산 메시징의 정합성 문제를 DB 트랜잭션으로 풀어내기
    • [초안] 결제 도메인 멱등성과 트랜잭션 재시도 기본기
    • [초안] 시니어 백엔드를 위한 Resilience 패턴 실전 가이드 — Timeout, Retry, Circuit Breaker, Bulkhead, Backpressure
    • [초안] REST API 버저닝과 모바일 앱 하위 호환성 — CJ푸드빌 디지털 채널 백엔드 관점
    • [초안] Spring Batch vs Event-Driven — 같은 비동기처럼 보이지만 전혀 다른 두 패러다임
    • [초안] Strategy Pattern — 분기문을 없애는 설계, 시니어 백엔드 인터뷰 핵심 패턴
    • [초안] 시니어 백엔드를 위한 시스템 설계 입문 스터디 팩
    • [초안] 템플릿 메서드 패턴 - 백엔드 처리 골격을 강제하는 가장 오래되고 가장 위험한 패턴
    • [초안] 대규모 트래픽 중 무중단 마이그레이션 — Feature Flag + Shadow Mode 실전
  • database 페이지로 이동
    • mysql 페이지로 이동
    • opensearch 페이지로 이동
    • redis 페이지로 이동
    • 김영한의-실전-데이터베이스-설계 페이지로 이동
    • [초안] DB Connection Pool Saturation과 Thread Pool 격리
    • 커넥션 풀 크기는 얼마나 조정해야 할까?
    • 인덱스 - DB 성능 최적화의 핵심
    • [초안] JPA N+1과 커머스 조회 모델: 주문/메뉴/쿠폰 도메인에서 살아남기
    • [초안] MyBatis 기본기 — XML Mapper, resultMap, 동적 SQL, 운영 패턴 정리
    • [초안] MyBatis와 JPA/Hibernate 트레이드오프 — 레거시 백엔드를 다루는 시니어 관점
    • 역정규화 (Denormalization)
    • 데이터 베이스 정규화
  • devops 페이지로 이동
    • docker 페이지로 이동
    • k8s 페이지로 이동
    • k8s-in-action 페이지로 이동
    • observability 페이지로 이동
    • [초안] 커머스/F&B 채널 장애 첫 5분과 관측성 기본기
    • Envoy Proxy
    • [초안] F&B / e-Commerce 운영 장애 대응과 모니터링 — 백엔드 관점 정리
    • Graceful Shutdown
    • [초안] 시니어 백엔드를 위한 SLO와 Error Budget 기반 장애 대응
  • finance 페이지로 이동
    • industry-cycle 페이지로 이동
    • investing 페이지로 이동
  • http 페이지로 이동
    • HTTP Connection Pool
    • HTTPS는 어떻게 안전한가 — TLS, 인증서, 그리고 termination
  • interview 페이지로 이동
    • [초안] AI 서비스 팀 경험 기반 시니어 백엔드 면접 질문 뱅크 — Spring Batch RAG / gRPC graceful shutdown / 전략 패턴 / 12일 AI 웹툰 MVP
    • [초안] 커머스/F&B 면접 답변집 — 슬롯 도메인 경험을 주문·결제·쿠폰·매장 설계로 매핑하기
    • [초안] F&B / e-Commerce 운영 모니터링과 장애 대응 인터뷰 정리
    • Observability — 면접 답변 프레임
    • [초안] 시니어 Java 백엔드 면접 마스터 플레이북 — 김병태
    • [초안] NSC 슬롯팀 경험 기반 질문 은행 — 도메인 모델링·동시성·성능·AI 협업
  • java 페이지로 이동
    • concurrency 페이지로 이동
    • jdbc 페이지로 이동
    • opentelemetry 페이지로 이동
    • spring 페이지로 이동
    • spring-batch 페이지로 이동
    • 더_자바_코드를_조작하는_다양한_방법 페이지로 이동
    • [초안] Java 동시성 락 정리 — 커머스 메뉴/프로모션 정책 캐시 갱신 관점
    • [초안] JVM 튜닝 실전: 메모리 구조부터 Virtual Threads, GC 튜닝, 프로파일링까지
    • Java의 로깅 환경
    • MDC (Mapped Diagnostic Context)
    • Java StampedLock — 읽기 폭주에도 쓰기가 밀리지 않는 락
    • Virtual Thread와 Project Loom
  • javascript 페이지로 이동
    • typescript 페이지로 이동
    • AbortController
    • Async Iterator와 제너레이터
    • CommonJS와 ECMAScript Modules
    • 제너레이터(Generator)
    • Http Client
    • Node 백엔드 운영 패턴 — Streams 백프레셔, pipe/pipeline, 멱등성 vs 분산 락
    • Node.js
    • npm vs pnpm — 어떤 기준으로 선택했나
    • `setImmediate()`
  • kafka 페이지로 이동
    • [초안] Kafka 기본 개념 — 토픽, 파티션, 오프셋, 복제
    • Kafka를 사용하여 **데이터 정합성**은 어떻게 유지해야 할까?
    • [초안] Kafka 실전 설계: 파티션 전략, 컨슈머 그룹, 전달 보장, 재시도, 순서 보장 트레이드오프
    • 메시지 전송 신뢰성
  • linux 페이지로 이동
    • fsync — 리눅스 파일 동기화 시스템 콜
    • tmux — Terminal Multiplexer
  • network 페이지로 이동
    • L2(스위치)와 L3(라우터)의 역할 차이
    • L4와 VIP(Virtual IP Address)
    • IP Subnet
  • python 페이지로 이동
    • Python async/await — CompletableFuture·Reactor 와 다른 점, 그리고 blocking I/O 함정
    • Python 의존성 관리 — Java Maven/Gradle 사용자가 만나는 첫 충격
    • FastAPI 기초 — Spring Boot 사용자가 빠르게 익히는 법
    • GPU·CUDA·MPS 기초 — 자바 백엔드 개발자가 처음 만나는 그림
    • Multi-process GPU 워크로드 — 자바 ThreadPool 사용자가 만나는 모델 차이
    • Java 개발자를 위한 Python 심화 — OOP·데코레이터·컨텍스트 매니저
    • PyTorch 기초 — 텐서, 디바이스, 그리고 모델 로딩이 무거운 이유
    • Java 개발자를 위한 Python 문법 핵심
    • ML 서비스 성능 분석 워크플로 — 자바 백엔드 트러블슈팅과 다른 점
    • OCR 동작 원리 — Layout · Text · Post-process 3단계
    • Python 서버의 RSS 가 안 줄어드는 이유 — gc.collect 의 한계와 malloc_trim
  • rabbitmq 페이지로 이동
    • [초안] RabbitMQ Basics — 실전 백엔드 관점에서 정리하는 메시지 브로커 기본기
    • [초안] RabbitMQ vs Kafka — 백엔드 메시징 선택 기준과 실전 운영 관점
  • security 페이지로 이동
    • [초안] 시니어 백엔드를 위한 보안 / 인증 스터디 팩 — Spring Security, JWT, OAuth2, OWASP Top 10
    • [초안] Spring Security 6.x OAuth2 + JWT 상용 인증 설계 — Grant 선택, Resource Server, Refresh Rotation, 로그아웃
  • task 페이지로 이동
    • ai-service-team 페이지로 이동
    • nsc-slot 페이지로 이동
    • sb-dev-team 페이지로 이동
    • the-future-company 페이지로 이동
  • testing 페이지로 이동
    • [초안] 시니어 Java 백엔드를 위한 테스트 전략 완전 정리 — 피라미드부터 TestContainers, 마이크로벤치, Contract까지
  • travel 페이지로 이동
    • 오사카 3박 4일 일정표: 우메다 쇼핑, USJ, 난바·도톤보리, 오사카성
  • web 페이지로 이동
    • [초안] HTTP / Cookie / Session / Token 인증 기본기 — 레거시 JSP와 모바일 API가 공존하는 백엔드 관점
FOS-BLOG · FOOTERall systems normal·v0.1 · 2026.04.27·seoul, kr
Ffos-blog/study

개발 학습 기록을 정리하는 블로그입니다. 공부하면서 기록하고, 기록하면서 다시 배웁니다.

visitors
01site
  • Home↗
  • Posts↗
  • Categories↗
  • About↗
02policy
  • 소개/about
  • 개인정보처리방침/privacy
  • 연락처/contact
03categories
  • AI↗
  • Algorithm↗
  • DB↗
  • DevOps↗
  • Java/Spring↗
  • JS/TS↗
  • React↗
  • Next.js↗
  • System↗
04connect
  • GitHub@jon890↗
  • Source repositoryjon890/fos-study↗
  • RSS feed/rss.xml↗
  • Newsletter매주 1 회 · 한 편의 글→
© 2026 FOS Study. All posts MIT-licensed.
built with·Next.js·Tailwind v4·Geist·Pretendard·oklch
fos-blog/http/HTTPS는 어떻게 안전한가 — TLS, 인…
system

HTTPS는 어떻게 안전한가 — TLS, 인증서, 그리고 termination

쿠버네티스 외부 노출 작업을 하다가 "TLS termination을 어디서 할지 정해야 한다"는 얘기가 나왔는데, 정작 나는 TLS가 뭔지부터 흐릿했다. HTTPS의 자물쇠 아이콘은 매일 보면서도 그 안에서 무슨 일이 벌어지는지는 한 번도 제대로 안 들여다봤던 거다. 그래서 HTTP와 HTTPS가 뭐가 다른지부터, TLS가 실제로 무엇을 해주는지까지 정리했...

2026.06.09·5 min read·7 views

쿠버네티스 외부 노출 작업을 하다가 "TLS termination을 어디서 할지 정해야 한다"는 얘기가 나왔는데, 정작 나는 TLS가 뭔지부터 흐릿했다. HTTPS의 자물쇠 아이콘은 매일 보면서도 그 안에서 무슨 일이 벌어지는지는 한 번도 제대로 안 들여다봤던 거다. 그래서 HTTP와 HTTPS가 뭐가 다른지부터, TLS가 실제로 무엇을 해주는지까지 정리했다.

HTTP는 엽서다

HTTP로 주고받는 데이터는 평문이다. 암호화가 전혀 없다. 비유하자면 엽서를 부치는 것과 같다. 우체부도, 중간에 거치는 누구도 내용을 그대로 읽을 수 있다.

문제는 인터넷에서 내 요청이 목적지까지 가는 동안 여러 중간 지점(공유기, ISP, 중간 서버)을 거친다는 점이다. HTTP면 그 중간 어디서든 비밀번호, 카드번호, 응답 내용이 다 보인다. 가로채는 것도, 내용을 몰래 바꾸는 것도 가능하다.

HTTPS = HTTP + TLS

HTTPS는 새로운 프로토콜이 아니다. HTTP를 TLS라는 보안 계층으로 한 번 감싼 것이다.

  • TLS(Transport Layer Security) = 통신을 암호화하고 상대 신원을 확인해주는 기술.
  • 예전엔 SSL이라고 불렀다. SSL이 발전해서 TLS가 됐고, 지금 쓰는 건 전부 TLS다. 그래서 "SSL 인증서"와 "TLS 인증서"는 사실상 같은 말이다. (이름만 SSL이 관습으로 남았다.)

엽서 비유를 이어가면, HTTPS는 봉인된 봉투다. 받는 사람만 뜯어볼 수 있고, 중간에 누가 봉투를 바꿔치기하면 받는 쪽이 알아챈다.

TLS가 풀어주는 두 가지 문제

TLS는 두 개의 다른 문제를 동시에 해결한다. 이 둘을 구분하는 게 중요하다.

  • 도청 방지(암호화) — 내용을 암호로 바꿔서 중간에서 못 읽게 한다.
  • 사칭 방지(신원 확인) — 내가 접속한 서버가 진짜 그 서버가 맞는지 확인한다. 암호화만 하고 신원 확인을 안 하면, 가짜 서버와 "안전하게" 대화하는 꼴이 될 수 있다.

암호화는 다음의 "자물쇠" 얘기로, 신원 확인은 "인증서" 얘기로 이어진다.

두 종류의 자물쇠 — 대칭키와 비대칭키

암호화에는 두 방식이 있다. TLS는 둘을 영리하게 섞어 쓴다.

대칭키 — 잠그는 열쇠와 여는 열쇠가 같다. 빠르다. 문제는 "그 열쇠를 어떻게 상대에게 안전하게 전달하느냐"다. 열쇠를 그냥 보내면 중간에서 가로채니까.

비대칭키 — 열쇠가 한 쌍이다. 공개키(public key)로 잠그면 개인키(private key)로만 열린다. 공개키는 아무에게나 줘도 된다. 누가 공개키로 잠가 보내도, 개인키를 가진 나만 열 수 있으니까. 대신 느리다.

TLS는 이렇게 조합한다.

  1. 처음에 비대칭키로 "이번 대화에서만 쓸 대칭키"를 안전하게 주고받는다. (느리지만 안전한 방식으로 열쇠를 전달)
  2. 그 다음부터는 빠른 대칭키로 실제 데이터를 주고받는다.

느린 비대칭키는 "열쇠를 건네는 순간"에만 쓰고, 빠른 대칭키로 본 통신을 한다. 안전함과 빠름을 둘 다 가져가는 절충이다.

인증서와 CA — 서버의 신분증

암호화는 됐는데, "내가 받은 공개키가 진짜 그 서버의 것"이라는 보장은 누가 해줄까? 여기서 인증서(certificate)가 등장한다.

인증서는 서버의 신분증이다. 안에 서버의 공개키와 "이 공개키는 my-service.com의 것이 맞다"는 보증이 들어 있다. 이 보증을 해주는 게 CA(Certificate Authority, 인증기관)다.

신원 보증의 흐름은 이렇다.

  • CA가 자기 개인키로 인증서에 서명한다. (위조 불가능한 도장을 찍는 셈)
  • 내 브라우저와 운영체제에는 신뢰할 수 있는 CA 목록(Root Store)이 미리 깔려 있다.
  • 서버가 인증서를 보내면, 브라우저는 "이 서명이 내가 아는 CA의 것인가"를 확인한다. 맞으면 신뢰하고, 아니면 "이 사이트는 안전하지 않습니다" 경고를 띄운다.

즉 신뢰의 뿌리는 "브라우저/OS가 미리 믿기로 한 CA들"이다. 그래서 아무 인증서나 만들어 붙인다고 되는 게 아니라, 신뢰받는 CA가 서명한 인증서여야 한다.

handshake — 봉투를 열기 전의 악수

실제 데이터를 주고받기 전에, 클라이언트와 서버는 짧은 협상을 한다. 이걸 TLS handshake라고 한다. 대략 이런 순서다.

  1. 클라이언트가 "TLS로 얘기하자, 내가 지원하는 암호 방식은 이것들이야"라고 인사한다.
  2. 서버가 인증서(공개키 포함)를 보낸다.
  3. 클라이언트가 인증서를 검증한다(CA 서명 확인). 통과하면 비대칭키를 이용해 이번 세션용 대칭키를 안전하게 합의한다.
  4. 이제부터 둘은 대칭키로 암호화해서 실제 HTTP 데이터를 주고받는다.

이 왕복 횟수를 줄이는 게 버전 발전의 핵심이었다. TLS 1.2는 왕복 2번(2-RTT)이 필요했는데, TLS 1.3은 왕복 1번(1-RTT)으로 줄여서 더 빠르고, 더 많은 부분을 암호화한다. 지금 새로 구성한다면 TLS 1.3을 기준으로 보면 된다.

TLS termination — 봉투를 어디서 뜯나

여기가 인프라 작업에서 실제로 결정해야 하는 지점이다. TLS termination은 "암호화된 트래픽을 어디서 풀어서(복호화) 평문으로 바꾸느냐"를 말한다. 인증서는 바로 그 지점에 있어야 한다.

외부 트래픽이 Pod까지 닿는 경로에서 봤듯, 외부 요청은 보통 LoadBalancer → Ingress Controller → Service → Pod를 거친다. 봉투(TLS)를 뜯는 위치는 보통 둘 중 하나다.

  • LoadBalancer에서 종단 — LB에 HTTPS 리스너와 인증서를 두고, LB가 복호화해서 안쪽으로는 평문 HTTP로 보낸다.
  • Ingress Controller에서 종단 — LB는 암호화된 채로 그냥 통과시키고, Controller에 인증서를 등록해 거기서 복호화한다.

어느 쪽이든 "인증서를 누가 들고, 누가 갱신하느냐"가 따라온다. 인증서는 유효기간이 있어서 주기적으로 갱신해야 하는데, 이 운영 부담을 어디에 둘지가 결정의 일부다.

실무에서의 의미 — API Gateway가 하던 일 옮기기

내가 맡은 작업의 맥락은 이랬다. 그동안 외부 HTTPS 처리(봉투 뜯기 + 인증서)는 앞단의 API Gateway가 전부 해주고 있었다. 클라이언트 ↔ API Gateway 구간만 HTTPS였고, 그 안쪽(쿠버네티스 내부)은 평문 HTTP였다. 그래서 클러스터 안의 모든 경로가 HTTP로 되어 있었던 거다.

API Gateway를 걷어내면, 이 봉투 뜯는 역할을 LoadBalancer나 Ingress Controller가 넘겨받아야 한다. "외부로 열었다"는 곧 "인터넷에 평문으로 열면 안 된다"는 뜻이라, TLS termination 위치와 인증서 관리 방식을 반드시 정하고 넘어가야 한다.

테스트 단계에서는 사내 IP만 접근하도록 막아두고 평문 HTTP로 경로부터 검증할 수 있지만, 진짜 외부에 공개하는 순간 TLS는 선택이 아니라 필수가 된다.

정리하면

  • HTTP는 평문(엽서), HTTPS는 HTTP를 TLS로 감싼 것(봉인된 봉투).
  • TLS는 암호화(도청 방지)와 신원 확인(사칭 방지) 두 가지를 한다.
  • 빠른 대칭키로 본 통신을 하되, 그 대칭키를 안전하게 건네는 데만 느린 비대칭키를 쓴다.
  • 인증서는 서버의 신분증이고, 신뢰받는 CA가 서명해야 브라우저가 믿는다.
  • TLS termination은 "암호를 어디서 풀고 인증서를 어디 둘지"의 문제이며, 인프라에서 실제로 결정해야 하는 지점이다.

자물쇠 아이콘 하나에 이렇게 여러 단계가 숨어 있는 줄 몰랐는데, 외부 노출을 직접 다뤄보니 왜 이게 매번 까다로운 결정이 되는지 알 것 같다.

참고 링크

  • What Happens in a TLS Handshake? — Cloudflare
  • Transport Layer Security — Wikipedia
  • 외부 트래픽이 Pod까지 닿는 경로 — TLS termination이 일어나는 위치
on this page
  • 01HTTP는 엽서다
  • 02HTTPS = HTTP + TLS
  • 03TLS가 풀어주는 두 가지 문제
  • 04두 종류의 자물쇠 — 대칭키와 비대칭키
  • 05인증서와 CA — 서버의 신분증
  • 06handshake — 봉투를 열기 전의 악수
  • 07TLS termination — 봉투를 어디서 뜯나
  • 08실무에서의 의미 — API Gateway가 하던 일 옮기기
  • 09정리하면
  • 10참고 링크

이런 글도

  • HTTP Connection Pool
    - 요약 : > HTTP는 TCP/TLS 연결 비용이 크기 때문에, 매 요청마다 새 연결을 생성하면 latency와 CPU 부하가 커진다 > 그래서 Node.js에서는 keep-alive 기반의 connection pool을 사용해 연결을 재사용하는 것이 필수 > 보통 1개의 외부 API 서버에 대해 인스턴스당 10100개의 커넥션 풀을 유지하는 것이 가장...
    📡 system
    system
    2026.01.30

댓글 (0)