본문 바로가기

개발 & IT/백엔드

Let's Encrypt 인증서 자동 갱신 완벽 가이드

들어가며

Let's Encrypt 인증서는 90일마다 만료되기 때문에 자동 갱신 설정이 필수입니다. 다행히 Ubuntu/Debian에서 certbot을 apt로 설치하면 자동 갱신이 패키지에 포함되어 있습니다.

certbot 패키지에 포함된 자동 갱신 기능

sudo apt install certbot python3-certbot-nginx

이 명령어 하나로 다음이 자동으로 설치되고 활성화됩니다:

1. systemd timer (스케줄러)

# 자동 갱신 타이머 확인
sudo systemctl status certbot.timer
● certbot.timer - Run certbot twice daily
     Loaded: loaded (/usr/lib/systemd/system/certbot.timer; enabled; preset: enabled)
     Active: active (waiting) since Mon 2025-10-13 15:46:58 UTC; 13h ago
    Trigger: Tue 2025-10-14 19:12:41 UTC; 13h left
   Triggers: ● certbot.service

하루에 2번 자동으로 갱신 체크를 실행합니다!

2. certbot.service (갱신 서비스)

# 타이머 설정 파일 확인
cat /usr/lib/systemd/system/certbot.timer
[Unit]
Description=Run certbot twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=12h
Persistent=true

[Install]
WantedBy=timers.target
  • OnCalendar=-- 00,12:00:00*: 매일 자정(00:00)과 정오(12:00)에 실행
  • RandomizedDelaySec=12h: 실행 시간을 무작위로 최대 12시간 분산 (서버 부하 방지)
  • Persistent=true: 서버가 꺼져있다가 켜지면 놓친 작업 실행

3. 똑똑한 갱신 로직

certbot은 단순히 90일마다 갱신하는 게 아닙니다:

  • 인증서를 확인해서 만료 30일 이전이면 갱신 안 함
  • 만료 30일 이내면 갱신 시도
  • 실패하면 다음 실행 때 재시도

즉, 하루 2번 체크하지만 실제로는 필요할 때만 갱신합니다!

자동 갱신 테스트하기

실제로 갱신이 잘 될지 시뮬레이션으로 테스트할 수 있습니다.

sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Account registered.
Simulating renewal of an existing certificate for example.com and 11 more domains
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/example.com/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

--dry-run 옵션:

  • 실제로 인증서를 갱신하지는 않음
  • Let's Encrypt API 호출 제한에 걸리지 않음
  • 갱신 과정을 완전히 시뮬레이션
  • 문제가 있다면 미리 발견 가능

한 가지 빠진 것: nginx 자동 reload

자동 갱신은 완벽하게 설정되어 있지만, 한 가지 문제가 있습니다.

인증서가 갱신되어도 nginx는 자동으로 새 인증서를 읽지 않습니다. nginx를 reload 해야만 새 인증서가 적용됩니다.

해결 방법: Deploy Hook 설정

certbot은 갱신 후 자동으로 실행할 스크립트를 등록할 수 있습니다.

# deploy 훅 디렉토리 확인
ls -la /etc/letsencrypt/renewal-hooks/deploy/
total 8
drwxr-xr-x 2 root root 4096 Oct 14 01:25 .
drwxr-xr-x 5 root root 4096 Oct 14 01:25 ..

디렉토리는 있지만 비어있습니다. nginx reload 스크립트를 만들어봅시다.

# nginx 자동 reload 스크립트 생성
sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

파일 내용:

#!/bin/bash
systemctl reload nginx

실행 권한 부여:

sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

확인:

ls -la /etc/letsencrypt/renewal-hooks/deploy/
total 12
drwxr-xr-x 2 root root 4096 Oct 14 05:30 .
drwxr-xr-x 5 root root 4096 Oct 14 01:25 ..
-rwxr-xr-x 1 root root   32 Oct 14 05:30 reload-nginx.sh

이제 인증서 갱신 시 nginx가 자동으로 reload됩니다.

Renewal Hooks의 종류

certbot은 3가지 시점에 스크립트를 실행할 수 있습니다:

1. pre-hook (갱신 전)

/etc/letsencrypt/renewal-hooks/pre/
  • 갱신 시도 에 실행
  • 예: 서비스 잠시 중지, 80/443 포트 확보

2. post-hook (갱신 후)

/etc/letsencrypt/renewal-hooks/post/
  • 갱신 시도 에 실행 (성공/실패 상관없이)
  • 예: 로그 기록, 알림 발송

3. deploy-hook (갱신 성공 시)

/etc/letsencrypt/renewal-hooks/deploy/
  • 갱신 성공 시에만 실행
  • 예: nginx reload, 서비스 재시작

우리는 deploy-hook을 사용합니다. 갱신이 성공했을 때만 nginx를 reload하기 때문입니다.

수동 갱신이 필요한 경우

자동 갱신은 완벽하지만, 가끔 수동으로 갱신해야 할 때도 있습니다:

전체 인증서 갱신 (만료 30일 이내만)

sudo certbot renew

특정 인증서만 강제 갱신

sudo certbot renew --cert-name example.com --force-renewal

새 도메인 추가

sudo certbot certonly --nginx --expand \
  -d example.com -d www.example.com \
  -d new-domain.com

갱신 실패 시 알림

certbot 설치 시 이메일을 입력했다면, 갱신 실패 시 자동으로 이메일 알림이 발송됩니다.

# 등록된 이메일 확인
sudo certbot show_account

이메일을 변경하고 싶다면:

sudo certbot update_account --email new-email@example.com

자동 갱신이 제대로 작동하는지 모니터링

1. 갱신 로그 확인

sudo cat /var/log/letsencrypt/letsencrypt.log

2. 인증서 만료일 확인

sudo certbot certificates
Certificate Name: example.com
  Domains: example.com www.example.com ...
  Expiry Date: 2026-01-12 01:25:47+00:00 (VALID: 89 days)
  Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem
  Private Key Path: /etc/letsencrypt/live/example.com/privkey.pem

3. 다음 갱신 예정 시간 확인

sudo systemctl list-timers | grep certbot
Tue 2025-10-14 19:12:41 UTC  13h left  Mon 2025-10-13 15:46:58 UTC  13h ago  certbot.timer

예전 방식: cron vs 최신 방식: systemd timer

예전 방식 (cron)

# crontab -e
0 0,12 * * * certbot renew --quiet

단점:

  • 정확히 00:00, 12:00에 실행 (모든 서버가 동시에 Let's Encrypt 서버 호출)
  • 서버가 꺼져있으면 놓친 작업 실행 안 됨
  • 로그 관리가 번거로움

최신 방식 (systemd timer)

# 자동으로 설정됨
systemctl status certbot.timer

장점:

  • ✅ 무작위 지연으로 부하 분산 (RandomizedDelaySec)
  • ✅ 서버 재시작 후 놓친 작업 자동 실행 (Persistent)
  • ✅ systemd 로그와 통합 (journalctl)
  • ✅ 서비스 의존성 관리 가능

현대적인 Linux 시스템에서는 systemd timer가 표준입니다!

요약: 자동 갱신 체크리스트

Let's Encrypt 인증서를 발급한 후 다음을 확인하세요:

  • [ ] certbot.timer가 활성화되어 있는가?
  • sudo systemctl status certbot.timer
  • [ ] 갱신 시뮬레이션이 성공하는가?
  • sudo certbot renew --dry-run
  • [ ] nginx reload 훅이 설정되어 있는가?
  • ls -la /etc/letsencrypt/renewal-hooks/deploy/
  • [ ] 알림 이메일이 등록되어 있는가?
  • sudo certbot show_account

모두 확인되었다면 인증서는 자동으로 갱신됩니다.

결론

Ubuntu/Debian에서 certbot 패키지를 설치하면 자동 갱신이 기본으로 포함되어 있습니다.

certbot 패키지가 자동으로 설정하는 것:

  • ✅ 하루 2번 갱신 체크 (systemd timer)
  • ✅ 만료 30일 전부터 자동 갱신
  • ✅ 실패 시 이메일 알림
  • ✅ 무작위 지연으로 부하 분산

추가로 설정해야 하는 것:

  • ✅ 갱신 성공 시 nginx 자동 reload (deploy hook)

이렇게 설정하면 90일마다 수동으로 인증서를 갱신할 필요가 없습니다.

자동 갱신이 제대로 설정되어 있는지 주기적으로 sudo certbot certificates로 인증서 상태를 확인하는 것이 좋습니다. 😊


참고 자료:

반응형