들어가며
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로 인증서 상태를 확인하는 것이 좋습니다. 😊
참고 자료:
'개발 & IT > 백엔드' 카테고리의 다른 글
nginx SSL 설정 중 만난 DNS 캐시 트러블슈팅 (0) | 2025.10.14 |
---|---|
apt autoremove란? 리눅스 패키지 관리의 숨은 조력자 (0) | 2025.10.10 |
MySQL vs PostgreSQL, 뭘 선택해야 할까? 완벽 비교 가이드 (0) | 2025.09.29 |
Laravel Queue Worker 완벽 가이드: 비동기 작업 처리의 핵심 (2) | 2025.09.22 |
📱 Framework7로 만든 앱을 Android APK로 패키징하는 방법 (1) | 2025.06.18 |