development/Network

SSL 인증서 ERR_CERT_DATE_INVALID 오류 해결

root@soni 2025. 8. 16. 19:13

안녕하세요! 오늘은 갑자기 발생한 SSL 인증서 오류를 해결한 경험을 공유해드리려고 합니다.

개발 중이던 웹사이트에 접속하려는데 갑자기 ERR_CERT_DATE_INVALID 오류가 뜨면서 접속이 안 되더라구요. 

Let's Encrypt를 사용하고 있어서 자동 갱신이 잘 되고 있다고 생각했는데... 뭔가 이상했습니다.


문제 발견

먼저 OpenSSL로 실제 서버가 제공하는 인증서를 확인해봤어요.

echo | openssl s_client -connect ai-server.projectbuildup.io:443 -servername ai-server.projectbuildup.io 2>/dev/null | openssl x509 -noout -dates

결과가 이랬습니다:

 
notBefore=Aug  7 00:56:17 2025 GMT
notAfter=Nov  5 00:56:16 2025 GMT

어? 그런데 인증서는 8월 7일에 새로 발급되어서 11월 5일까지 유효했습니다..🤨

그럼 서버 파일은 어땠을까요?

sudo openssl x509 -in /etc/letsencrypt/live/ai-server.projectbuildup.io/fullchain.pem -noout -dates
 
notBefore=May 15 12:10:20 2025 GMT
notAfter=Aug 13 12:10:19 2025 GMT

여기서 문제를 찾았습니다! 💡


원인 분석

상황을 정리해보니:

  • 실제 서비스: 8월 7일 발급된 새 인증서 사용 
  • 서버 파일: 8월 13일에 만료된 옛날 인증서 

Let's Encrypt 자동 갱신이 부분적으로만 성공한 상황이었습니다.

  1. 1단계 성공: 새 인증서 발급 (8월 7일)
  2. 2단계 실패: 파일 시스템 연동 실패

심볼릭 링크를 확인해보니 여전히 cert2.pem (만료된 파일)을 가리키고 있었어요.

sudo ls -la /etc/letsencrypt/live/ai-server.projectbuildup.io/

해결 과정

문제를 이해했으니 해결해봅시다!

certbot renew --force-renewal 명령어를 사용했는데, 이 명령어는 단순히 인증서만 갱신하는 게 아니라,

  1. 새 인증서 발급
  2. 심볼릭 링크 자동 업데이트
  3. 웹서버 자동 재시작
  4. 파일 시스템과 실제 서비스 동기화

모든 과정을 다시 실행해줍니다! 아래 두 줄의 명령어로요!

sudo certbot renew --force-renewal --cert-name ai-server.projectbuildup.io
sudo systemctl reload nginx

결과:

Congratulations, all renewals succeeded: 
  /etc/letsencrypt/live/ai-server.projectbuildup.io/fullchain.pem (success)

해결 완료!

갱신 후 다시 확인해보니:

sudo openssl x509 -in /etc/letsencrypt/live/ai-server.projectbuildup.io/fullchain.pem -noout -dates
 
notBefore=Aug 16 02:05:00 2025 GMT
notAfter=Nov 14 02:04:59 2025 GMT

이제 파일 시스템과 실제 서비스가 완전히 일치합니다! 

심볼릭 링크도 정상적으로 업데이트되었어요:

lrwxrwxrwx cert.pem -> cert3.pem  # 이전: cert2.pem

배운 점

-> Let's Encrypt 갱신 타이밍

궁금했던 건데, 왜 8월 13일 만료인데 8월 7일에 미리 갱신됐을까요?

Let's Encrypt는 안전을 위해 만료 30일 전부터 갱신을 시도합니다. 이번 경우는 만료 6일 전 갱신으로 정상적인 타이밍이었어요.

미리 갱신하는 이유:

  • 안전성: 갱신 실패 시 재시도할 시간 확보
  • 안정성: 만료 직전 급한 갱신 방지
  • 분산: 모든 인증서가 동시 갱신되는 것 방지

-> 자동 갱신 vs 수동 복구

이번 --force-renewal은 한 번만 하면 되는 복구 작업입니다.

다음 갱신(11월 14일 → 2월경)에는 일반적인 자동 갱신이 정상 작동할 것으로 예상됩니다:

기존 (문제 상황):

자동갱신 실행 → 새 인증서 발급 ✅ → 파일 연동 실패 ❌

복구 후 (정상 상황):

자동갱신 실행 → 새 인증서 발급 ✅ → 파일 연동 성공 ✅

예방법

앞으로는 이런 문제를 미리 감지할 수 있도록:

1. 정기 점검

# 월 1회 실행
sudo certbot certificates

2. 모니터링 스크립트

#!/bin/bash
# 30일 전 자동 경고
openssl x509 -in /etc/letsencrypt/live/domain/fullchain.pem \
  -noout -checkend $((30*24*3600)) || \
  echo "SSL 만료 경고!" | mail -s "SSL Alert" admin@domain.com

3. 로그 확인

sudo tail -f /var/log/letsencrypt/letsencrypt.log

처음에는 당황스러웠지만, 차근차근 원인을 분석해보니 해결책을 찾을 수 있었습니다.

핵심 포인트는

1. SSL 오류 발생 시 실제 서비스 vs 파일 시스템 인증서 비교하기

2. certbot renew --force-renewal로 갱신 프로세스 전체 리셋

3. 정기적인 모니터링으로 문제 사전 감지

비슷한 문제를 겪고 계신 분들께 도움이 되었으면 좋겠습니다! 😊


참고 명령어 모음

# 실제 서비스 인증서 확인
echo | openssl s_client -connect domain:443 -servername domain 2>/dev/null | openssl x509 -noout -dates

# 서버 파일 인증서 확인  
sudo openssl x509 -in /etc/letsencrypt/live/domain/fullchain.pem -noout -dates

# 강제 갱신
sudo certbot renew --force-renewal --cert-name domain

# 인증서 목록 확인
sudo certbot certificates

# 갱신 테스트
sudo certbot renew --dry-run

궁금한 점이나 비슷한 경험이 있으시면 댓글로 공유해주세요!