OCSP 스테이플링(stapling)은 웹 서버가 자신의 TLS 인증서가 아직 폐기되지 않았다는 증명을 미리 받아 두었다가, TLS 핸드셰이크 때 인증서와 함께 클라이언트에게 붙여(staple) 건네는 최적화 기법이다. 원래는 브라우저가 인증서를 받은 뒤 인증기관(CA)에 "이거 아직 유효해?"라고 직접 물어야 했는데, 그 왕복을 서버가 대신 처리해 없애준다. 접속 지연과 개인정보 노출을 동시에 줄인다.
HTTPS를 붙이면서 인증서 발급까지는 다들 하는데, 폐기 확인(revocation)은 의외로 잘 모른다. 나도 "인증서에 만료일 있는데 폐기는 또 뭐야?" 했었다. 이 둘은 별개다.
왜 폐기 확인이 필요한가
인증서에는 유효기간이 박혀 있다. 하지만 만료 전에 개인키가 유출되면 어떻게 될까? 만료일까지 그 인증서가 계속 유효한 척 악용될 수 있다. 그래서 CA는 "이 인증서는 기간이 남았어도 무효"라고 선언하는 폐기 수단을 둔다. 문제는 클라이언트가 이 폐기 여부를 어떻게 확인하느냐다.
| 방식 | 동작 | 약점 |
|---|---|---|
| CRL | 폐기 목록 전체를 내려받음 | 목록이 거대·갱신 느림 |
| OCSP | 이 인증서 하나만 CA에 질의 | 접속마다 왕복·프라이버시 |
| OCSP 스테이플링 | 서버가 응답을 미리 받아 첨부 | 서버 설정 필요 |
스테이플링 없는 OCSP의 문제
순수 OCSP는 클라이언트가 사이트에 접속할 때마다 CA의 OCSP 응답 서버에 별도로 접속해 확인한다. 여기엔 두 가지 문제가 있다. 첫째, 추가 왕복으로 첫 접속이 느려진다. 둘째, 더 민감한 건 프라이버시다. 사용자가 어떤 사이트에 언제 접속하는지가 CA에게 고스란히 노출된다. CA가 사용자의 브라우징 로그를 갖게 되는 셈이다.
게다가 OCSP 서버가 느리거나 죽으면? 브라우저는 대개 "확인 실패 시 그냥 통과(soft-fail)"로 처리한다. 보안 검사인데 실패하면 넘어가 버리니, 공격자가 OCSP 서버로 가는 길만 막으면 폐기 확인이 무력화된다. 반쪽짜리 방어였다.
스테이플링이 바꾸는 것
스테이플링에서는 서버가 주기적으로(보통 몇 시간마다) CA에서 "내 인증서는 유효함"이라는 서명된 OCSP 응답을 미리 받아 캐시해 둔다. 그리고 클라이언트가 접속하면 그 응답을 인증서에 붙여 함께 보낸다. 응답에는 CA의 서명과 발급 시각이 들어 있어 위조할 수 없다.
[스테이플링 없음]
브라우저 --핸드셰이크--> 서버
브라우저 --폐기확인?--> CA OCSP 서버 ← 추가 왕복 + 프라이버시 노출
[스테이플링]
서버 --미리 확인--> CA (몇 시간 주기, 백그라운드)
브라우저 --핸드셰이크--> 서버 (인증서 + 최신 OCSP 응답 동봉)
← 브라우저는 CA에 직접 안 감
결과적으로 접속은 빨라지고, 사용자의 접속 기록이 CA로 새지 않으며, 서버가 한 번 받은 응답을 여러 방문자에게 재사용하니 CA 부하도 준다. 삼박자다.
Nginx에서 켜기
server {
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# OCSP 스테이플링 활성화
ssl_stapling on;
ssl_stapling_verify on;
# 체인 검증용 신뢰 인증서 (보통 fullchain로 충족)
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
resolver 1.1.1.1 8.8.8.8 valid=300s;
}
확인은 이렇게 한다. openssl s_client -connect example.com:443 -status를 실행해 응답에 OCSP Response Status: successful이 보이면 정상 동작이다. 처음 켠 직후엔 서버가 아직 OCSP 응답을 못 받아 비어 있을 수 있으니, 몇 번 접속 후 다시 확인하자. Caddy는 기본으로 켜져 있어 따로 설정할 게 없다.
참고로 업계는 OCSP의 프라이버시·안정성 문제 때문에 방향을 틀고 있다. Let's Encrypt는 OCSP 서비스를 접고 CRL 기반으로 이동 중이다. 그래도 스테이플링이 왜 나왔고 무엇을 해결했는지는 TLS를 이해하는 핵심 사례로 알아둘 가치가 있다.
자주 묻는 질문
OCSP 스테이플링을 켜면 뭐가 좋아지나요?
첫 TLS 접속에서 폐기 확인을 위한 추가 왕복이 사라져 조금 빨라지고, 사용자의 접속 정보가 CA로 새지 않아 프라이버시가 개선됩니다. 서버가 응답을 캐시해 재사용하므로 CA 쪽 부하도 줄어듭니다.
스테이플링과 그냥 OCSP의 차이가 뭔가요?
일반 OCSP는 브라우저가 접속마다 CA에 직접 폐기 여부를 묻습니다. 스테이플링은 서버가 그 응답을 미리 받아 캐시해 두고 핸드셰이크에 첨부하므로, 브라우저가 CA와 직접 통신할 필요가 없어집니다.
설정했는데 동작하는지 어떻게 확인하나요?
openssl s_client -connect 도메인:443 -status를 실행해 출력에 OCSP Response Status: successful이 나오면 정상입니다. 방금 켰다면 서버가 응답을 캐시하기 전이라 비어 있을 수 있으니 잠시 뒤 다시 시도하세요.
스테이플링이 폐기를 100% 실시간으로 반영하나요?
아닙니다. 서버가 캐시한 OCSP 응답은 발급 후 몇 시간 유효하므로, 그 사이 폐기된 인증서는 캐시가 갱신될 때까지 유효한 것으로 보일 수 있습니다. 즉각적인 무효화가 필요하면 인증서 교체와 짧은 캐시 주기를 병행해야 합니다.

댓글 0