Certbot으로 SSL 인증서 발급부터 자동 갱신까지 한 번에

Certbot SSL 인증서 발급부터 자동 갱신까지 한 번에

certbot ssl 인증서 발급이 생각보다 복잡하다고 느끼는 사람이 많다. 처음 서버를 세팅할 때 nginx 설정도 손봐야 하고, 포트도 열어야 하고, 인증서 경로도 신경 써야 하고… 하나씩 따라가다 보면 어느 순간 오류 메시지가 반겨주는 그 기분. 나도 처음엔 그랬다.

그런데 솔직히 말하자면, Certbot은 한 번 제대로 이해하고 나면 그다음부터는 정말 간단하다. Let’s Encrypt 덕분에 무료로 SSL 인증서를 발급받을 수 있고, 90일마다 갱신해야 한다는 것도 자동화만 잘 해두면 전혀 신경 쓸 일이 없다. 이 글에서는 Ubuntu 24.04 기준으로 Certbot 설치부터 nginx 연동, 자동 갱신 설정, 그리고 실제 운영 중에 자주 마주치는 갱신 오류 대처법까지 한 번에 정리한다.

직접 서버를 운영하면서 겪은 경험을 바탕으로 썼기 때문에, 공식 문서에는 잘 안 나와 있는 실전 팁들도 중간중간 넣어뒀다. Nginx와 Certbot 조합으로 처음 HTTPS를 세팅하는 분이라면 이 글 하나로 충분할 거라고 생각한다.

이 글에서 다루는 환경

운영체제: Ubuntu 24.04 LTS
웹서버: Nginx (최신 안정 버전)
인증서: Let’s Encrypt (Certbot 공식 플러그인)
자동 갱신: systemd timer 방식 (cron 병행 설명)
전제 조건: 도메인이 서버 IP로 A레코드 연결되어 있어야 함

서버 보안 강화에 관심 있다면 이전 글인 우분투 서버 보안 설정 가이드도 함께 읽어보길 추천한다. SSL 인증서 설정 이전에 방화벽과 SSH 보안부터 잡아두는 게 순서상 맞다. 이 글에서도 UFW 방화벽이 기본으로 설정되어 있다는 전제 하에 진행하니까 참고해두자.

Certbot이란? Let’s Encrypt와의 관계 이해하기

certbot ssl 인증서 발급을 처음 시도하는 분들이 자주 헷갈리는 게 있다. Certbot이랑 Let’s Encrypt가 같은 건지, 다른 건지. 결론부터 말하자면 다르다. Let’s Encrypt는 무료 SSL 인증서를 발급해주는 인증 기관(CA, Certificate Authority)이고, Certbot은 그 인증서를 자동으로 발급받고 갱신해주는 클라이언트 도구다.

비유하자면 Let’s Encrypt는 여권 발급 기관이고, Certbot은 여권 발급 창구에서 대신 서류를 처리해주는 에이전트 같은 역할이다. 직접 Let’s Encrypt API를 두드려서 인증서를 받을 수도 있긴 한데, 그걸 사람이 일일이 할 필요 없도록 자동화해주는 게 Certbot이다.

Let’s Encrypt

비영리 인증 기관. 무료 DV 인증서 발급. 90일 유효기간 정책 운영.

Certbot

EFF(전자프론티어재단)가 개발한 ACME 클라이언트. 발급·갱신·nginx 설정 자동화.

ACME 프로토콜

도메인 소유권 자동 검증 표준 프로토콜. Certbot이 이 방식으로 Let’s Encrypt와 통신.

90일이라는 유효기간이 짧다고 느낄 수 있는데, 이건 Let’s Encrypt의 철학이다. 짧은 유효기간을 강제해서 자동 갱신 문화를 만들겠다는 의도다. 실제로 한 번 자동 갱신 설정만 해두면 이 90일이 전혀 부담이 안 된다. 오히려 갱신을 까먹어서 인증서가 만료되는 상황을 방지해주는 장치이기도 하다.

DV 인증서 vs OV/EV 인증서

Let’s Encrypt가 발급하는 건 DV(Domain Validation) 인증서다. 도메인 소유권만 확인하는 방식으로, 개인 블로그·개발 서버·소규모 서비스에는 충분하다. 금융기관이나 결제 시스템처럼 조직 신원까지 검증해야 하는 경우에는 OV나 EV 인증서가 필요한데, 그건 유료 CA를 이용해야 한다. 대부분의 일반적인 웹서비스라면 Let’s Encrypt로 충분하다.

사전 준비 – 도메인 연결과 Nginx 기본 설정 확인

Certbot을 실행하기 전에 반드시 확인해야 할 것들이 있다. 이걸 빠뜨리고 certbot을 돌리면 바로 오류가 나는데, 대부분의 초보 오류가 여기서 나온다. 순서대로 체크해보자.

1단계: 도메인 A레코드 확인

Certbot의 HTTP-01 챌린지 방식은 외부에서 해당 도메인으로 접속해서 소유권을 확인한다. 그러니까 도메인이 서버 IP로 정확하게 연결되어 있어야 한다. 확인하는 방법은 간단하다.

터미널 # 도메인 A레코드 확인 dig example.com +short # 또는 nslookup example.com # 결과가 서버 IP와 일치하면 OK

DNS 전파에 시간이 걸리는 경우도 있다. 도메인 등록사에서 A레코드를 방금 바꿨다면 최대 48시간까지 기다려야 할 수 있는데, 대부분은 몇 분~1시간 이내에 반영된다. DNS 전파 확인 도구(whatsmydns.net)에서 글로벌 전파 상황을 빠르게 체크할 수 있다.

2단계: UFW 방화벽에서 80, 443 포트 개방

인증서 발급 과정에서 Let’s Encrypt 서버가 80번 포트로 접근한다. 443은 HTTPS 서비스용이다. 둘 다 열려 있어야 한다.

터미널 # Nginx 프로필 허용 (80 + 443 동시 개방) sudo ufw allow ‘Nginx Full’ # 개별 설정이라면 sudo ufw allow 80/tcp sudo ufw allow 443/tcp # 상태 확인 sudo ufw status
주의사항 이미 ‘Nginx HTTP’만 허용한 상태라면, ‘Nginx Full’ 추가 후 ‘Nginx HTTP’는 삭제하는 게 깔끔하다.
sudo ufw delete allow 'Nginx HTTP'

3단계: Nginx 동작 및 기본 설정 확인

Certbot –nginx 플러그인을 사용할 경우 Nginx가 실행 중이어야 하고, 해당 도메인에 대한 server block이 존재해야 한다. 아직 server block을 만들지 않았다면 지금 만들어두자.

/etc/nginx/sites-available/example.com server { listen 80; server_name example.com www.example.com; root /var/www/example.com; index index.html index.php; location / { try_files $uri $uri/ =404; } }
터미널 # 심볼릭 링크 생성 및 활성화 sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/ # 설정 문법 검사 sudo nginx -t # Nginx 재시작 sudo systemctl reload nginx # Nginx 상태 확인 sudo systemctl status nginx
실무 팁 WordPress를 운영 중이라면 Nginx + PHP 설정이 이미 되어 있을 텐데, 그 server block에 server_name이 정확히 도메인으로 지정되어 있는지 먼저 확인하자. server_name _;처럼 와일드카드로만 잡혀 있으면 Certbot이 해당 도메인을 인식하지 못하고 오류를 낸다. 서버 세팅 전체 과정이 궁금하다면 Nginx + PHP8.3 + MariaDB 설치 가이드를 참고하면 된다.

Certbot 설치 및 SSL 인증서 발급 (certbot –nginx)

사전 준비가 끝났다면 이제 본격적으로 certbot ubuntu 설치를 시작한다. Ubuntu 24.04에서는 snap을 통한 설치가 공식 권장 방법이다. apt로 설치하는 구버전 certbot은 더 이상 업데이트가 잘 안 되기 때문에 snap 방식을 쓰는 게 맞다.

snap core 업데이트

snapd 최신 상태 확인

certbot 설치

snap으로 공식 버전 설치

심볼릭 링크

certbot 명령어 전역 등록

인증서 발급

certbot –nginx 실행

Certbot 설치

터미널 # 기존 apt 버전 certbot 제거 (있다면) sudo apt remove certbot # snap core 최신화 sudo snap install core sudo snap refresh core # certbot 설치 sudo snap install –classic certbot # 전역 명령어 등록 sudo ln -s /snap/bin/certbot /usr/bin/certbot # 설치 확인 certbot –version
왜 snap으로 설치해야 하나?

apt 저장소의 certbot 패키지는 업데이트 속도가 느리고, Ubuntu 버전에 따라 구버전이 설치될 수 있다. Certbot 공식 문서에서도 snap 설치를 권장하고 있으며, snap 버전은 자동으로 최신 상태를 유지한다. Certbot 공식 설치 가이드에서 OS와 웹서버를 선택하면 맞춤 설치 명령어를 확인할 수 있다.

SSL 인증서 발급 – certbot –nginx

설치가 끝났으면 이제 실제로 certbot ssl 인증서 발급을 해보자. –nginx 플러그인을 사용하면 Certbot이 알아서 Nginx 설정 파일을 읽고, 인증서 발급 후 HTTPS 설정까지 자동으로 넣어준다.

터미널 – 인증서 발급 # 단일 도메인 sudo certbot –nginx -d example.com # www 포함 (권장) sudo certbot –nginx -d example.com -d www.example.com # 이메일 미리 지정 (대화형 프롬프트 줄이기) sudo certbot –nginx -d example.com -d www.example.com –email [email protected] –agree-tos –no-eff-email

첫 실행 시 이메일 입력, 이용약관 동의, EFF 뉴스레터 수신 여부를 묻는다. 모두 입력하면 잠시 후 Let’s Encrypt 서버와 통신하면서 도메인 소유권 검증이 진행된다. 성공하면 아래 같은 메시지가 나온다.

Successfully received certificate. Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem Key is saved at: /etc/letsencrypt/live/example.com/privkey.pem This certificate expires on 2025-06-15. Deploying certificate to VirtualHost /etc/nginx/sites-enabled/example.com Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/example.com – – – – – – – – – – – – – – – – – – – – – – – – – Congratulations! You have successfully enabled HTTPS on https://example.com

인증서 발급 오류 시 먼저 확인할 것

주의사항 Connection refused 또는 Timeout 오류: UFW에서 80번 포트가 막혀 있거나, Nginx가 실행 중이지 않은 경우.

No match for domain: Nginx server block에 해당 도메인이 server_name으로 지정되어 있지 않은 경우.

Rate limit exceeded: 단시간에 동일 도메인으로 발급 요청을 여러 번 했을 때. 1주일에 도메인당 5회 제한이 있다. 테스트할 때는 –staging 옵션을 쓰자.
터미널 – 테스트 발급 (실제 발급 전 확인용) # –staging 옵션으로 테스트 (rate limit 걱정 없이) sudo certbot –nginx -d example.com –staging # 테스트 성공 후 실제 발급 sudo certbot –nginx -d example.com
실무 팁 –staging으로 발급한 인증서는 브라우저에서 “신뢰할 수 없는 인증서”로 표시된다. 설정이 제대로 되는지만 확인하는 용도이고, 실제 운영에는 절대 쓰면 안 된다. 테스트가 성공했으면 sudo certbot delete --cert-name example.com으로 테스트 인증서를 지우고 실제 발급을 진행하면 된다.

Nginx SSL 설정 확인 및 443 포트 최적화

certbot –nginx로 발급을 마치면 Nginx 설정 파일이 자동으로 수정된다. 그런데 Certbot이 자동으로 넣어주는 기본 설정이 사실 최소한의 구성이라서, 운영 환경에서는 몇 가지를 더 손봐줘야 한다. nginx ssl 설정을 직접 확인하고 최적화하는 방법을 살펴보자.

Certbot이 자동으로 수정한 Nginx 설정 확인

Certbot 실행 후 server block이 어떻게 바뀌었는지 먼저 확인해보자.
터미널 sudo cat /etc/nginx/sites-enabled/example.com
자동으로 추가된 주요 내용은 대략 아래와 같다.
Nginx 자동 생성 SSL 설정 (예시) server { listen 443 ssl; server_name example.com www.example.com;ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; root /var/www/example.com; index index.html index.php; location / { try_files $uri $uri/ =404; } } server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; # HTTP -> HTTPS 리다이렉트 }

SSL 설정 강화 – 권장 추가 항목

기본 설정으로도 HTTPS는 동작하지만, 보안 등급을 올리고 성능을 개선하려면 아래 항목들을 추가하는 게 좋다. 특히 HSTS와 OCSP Stapling은 실제 운영 서버라면 거의 필수다.
/etc/nginx/sites-available/example.com – 최적화 버전 server { listen 443 ssl http2; server_name example.com www.example.com;ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # HSTS (6개월 캐시, 서브도메인 포함) add_header Strict-Transport-Security “max-age=15768000; includeSubDomains” always; # OCSP Stapling ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; # 보안 헤더 add_header X-Frame-Options “SAMEORIGIN” always; add_header X-Content-Type-Options “nosniff” always; add_header X-XSS-Protection “1; mode=block” always; root /var/www/example.com; index index.html index.php; location / { try_files $uri $uri/ =404; } } server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; }
설정 항목 역할 중요도
http2 HTTP/2 프로토콜 활성화 – 페이지 로딩 속도 향상 권장
HSTS 브라우저가 항상 HTTPS로만 접속하도록 강제 권장
OCSP Stapling 인증서 유효성 검증 속도 향상, 프라이버시 보호 권장
X-Frame-Options 클릭재킹 공격 방지 선택
X-Content-Type-Options MIME 스니핑 방지 선택

SSL 등급 확인

설정을 완료했으면 실제로 SSL 보안 등급이 어떻게 나오는지 확인해볼 수 있다. 위 설정을 그대로 적용했다면 A 이상이 나올 것이다.
터미널 – 설정 적용 및 검증 # Nginx 설정 문법 검사 sudo nginx -t# 설정 반영 sudo systemctl reload nginx # SSL 연결 직접 테스트 openssl s_client -connect example.com:443 -servername example.com < /dev/null 2>&1 | grep -E “subject|issuer|expire”
실무 팁 HSTS를 처음 적용할 때는 max-age를 짧게(예: 300초) 설정하고 테스트한 다음, 문제 없으면 15768000(6개월)로 늘리는 게 안전하다. HSTS를 한 번 적용하면 브라우저 캐시 기간 동안 HTTP로 되돌리기가 어렵기 때문이다. 특히 서브도메인까지 포함하는 includeSubDomains는 모든 서브도메인이 HTTPS로 돌아가고 있다는 확신이 있을 때 추가하자.
인증서 파일 경로 정리 /etc/letsencrypt/live/example.com/fullchain.pem – 서버 인증서 + 중간 인증서 체인 /etc/letsencrypt/live/example.com/privkey.pem – 개인키 /etc/letsencrypt/live/example.com/cert.pem – 서버 인증서만 /etc/letsencrypt/live/example.com/chain.pem – 중간 인증서 체인만 Nginx에서는 ssl_certificate에 fullchain.pem, ssl_certificate_key에 privkey.pem을 사용한다.

Let’s Encrypt 자동 갱신 설정 (systemd timer / cron)

let’s encrypt 자동 갱신은 Certbot을 설치하면 사실 snap이 자동으로 처리해준다. snap 버전 Certbot은 설치 시 systemd timer를 자동으로 등록하는데, 이게 하루에 두 번씩 certbot renew를 실행해서 만료 30일 전부터 갱신을 시도한다. 그러니까 이미 설정이 되어 있다는 이야기다.

하지만 “자동으로 설정됐겠지” 하고 넘어가지 말고, 직접 확인하고 동작 테스트까지 해봐야 한다. 나중에 갱신이 실패했는데 그걸 모르고 있다가 인증서 만료 경고 메일을 받는 상황은 꽤 당황스럽다.

90일 Let’s Encrypt 인증서 유효기간
30일 갱신 시도 시작 시점 (만료 전)
2회 systemd timer 하루 실행 횟수
0원 Let’s Encrypt 인증서 발급 비용

systemd timer 상태 확인

터미널 # certbot timer 상태 확인 sudo systemctl status snap.certbot.renew.timer # 다음 실행 예정 시간 확인 sudo systemctl list-timers | grep certbot # timer 활성화 여부 확인 sudo systemctl is-enabled snap.certbot.renew.timer

정상이라면 Active: active (waiting) 상태로 표시되고, 다음 실행 예정 시간이 나온다. 만약 inactive나 failed 상태라면 아래 명령어로 다시 활성화하자.

터미널 – timer 재활성화 sudo systemctl enable snap.certbot.renew.timer sudo systemctl start snap.certbot.renew.timer

갱신 동작 테스트 (dry-run)

실제 갱신을 실행하지 않고 갱신 과정이 정상 동작하는지 시뮬레이션할 수 있다. –dry-run 옵션을 쓰면 된다.

터미널 # 갱신 시뮬레이션 (실제 갱신 없이 테스트) sudo certbot renew –dry-run # 특정 도메인만 테스트 sudo certbot renew –dry-run –cert-name example.com
certbot renew –dry-run 성공 기준 체크리스트
도메인 A레코드 연결 필수
Nginx 80포트 응답 정상 필수
/.well-known/acme-challenge/ 접근 허용 필수
rate limit 여유 (5회/주) 확인 권장

cron으로 갱신 + Nginx 재시작 자동화

systemd timer가 기본이지만, cron을 추가로 설정해서 갱신 후 Nginx를 재시작하는 hook을 걸어두는 방식도 많이 쓴다. 특히 OCSP Stapling 캐시 갱신까지 확실하게 처리하고 싶다면 권장된다.

터미널 – cron 편집 sudo crontab -e
crontab 추가 내용 # 매일 새벽 3시 30분에 갱신 시도, 성공 시 Nginx 재로드 30 3 * * * /snap/bin/certbot renew –quiet && systemctl reload nginx
실무 팁 Certbot deploy hook 방식을 쓰면 갱신 성공 시에만 Nginx를 재시작하도록 더 정교하게 제어할 수 있다.

/etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh 파일을 만들고 아래 내용을 넣어두면 된다.

#!/bin/bash
systemctl reload nginx


파일 권한도 실행 가능하게 설정: sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

갱신 이력 및 만료일 확인

터미널 # 현재 발급된 인증서 목록 및 만료일 확인 sudo certbot certificates # 갱신 로그 확인 sudo cat /var/log/letsencrypt/letsencrypt.log | tail -50
Day 1 – 인증서 발급

certbot –nginx 실행. 90일 유효기간 시작. /etc/letsencrypt/live/ 에 인증서 저장.

Day 60 – 자동 갱신 시도 시작

만료 30일 전부터 systemd timer가 매일 2회 certbot renew 실행. 갱신 성공 시 새 인증서 자동 적용.

Day 89 – 만료 경고 메일

갱신이 안 됐을 때 Let’s Encrypt에서 등록된 이메일로 만료 임박 경고 발송. 이 시점에 받으면 뭔가 문제가 있다는 신호.

Day 90 – 인증서 만료

갱신 실패 상태라면 이날부터 브라우저에 보안 경고. 자동 갱신이 정상이라면 Day 60~70 사이에 이미 새 인증서로 교체 완료.

갱신 성공 확인 방법

sudo certbot certificates 명령어 실행 후 Expiry Date가 현재로부터 90일 가까이 남아 있다면 갱신이 정상적으로 이뤄진 것이다. 반대로 30일 이하가 남아 있는데 갱신 로그에 오류가 있다면 수동으로 sudo certbot renew를 실행해보자.

SSL 인증서 갱신 오류 원인과 실전 해결법

자동 갱신이 설정되어 있어도 오류가 나는 경우가 꽤 있다. ssl 인증서 갱신 오류의 원인은 대부분 몇 가지로 정해져 있어서, 패턴을 알면 금방 해결할 수 있다. 오류 메시지를 보고 당황하지 말고 하나씩 체크해보자.

오류 로그 먼저 확인하기

터미널 – 갱신 오류 로그 확인 # Certbot 로그 전체 보기 sudo journalctl -u snap.certbot.renew.service # 최근 50줄만 보기 sudo tail -50 /var/log/letsencrypt/letsencrypt.log # 오류 부분만 필터 sudo grep -i “error\|failed\|problem” /var/log/letsencrypt/letsencrypt.log
오류 유형 1: Connection refused
80번 포트가 막혀 있거나 Nginx가 내려가 있을 때. UFW 상태 확인 후 Nginx 재시작.
오류 유형 2: DNS problem
도메인 A레코드가 서버 IP와 다를 때. DNS 전파 대기 또는 레코드 재확인 필요.
오류 유형 3: Rate limit exceeded
단기간 5회 이상 발급 시도. 1주일 기다리거나 –staging으로 테스트.
오류 유형 4: Permission denied
/etc/letsencrypt/ 접근 권한 문제. sudo로 실행하거나 폴더 권한 확인.

가장 흔한 오류 1: 80포트 차단 문제

Nginx가 443을 잘 서비스하고 있어도 갱신 시점에 80포트가 막혀 있으면 챌린지 검증이 실패한다. 특히 방화벽 규칙을 수정하다가 80포트를 실수로 닫는 경우가 있다.

터미널 – 80포트 점검 및 복구 # UFW 상태 확인 sudo ufw status # 80포트 열려 있지 않다면 sudo ufw allow 80/tcp # Nginx 상태 확인 sudo systemctl status nginx # Nginx가 내려가 있다면 sudo systemctl start nginx # 80포트 실제 응답 테스트 curl -I http://example.com

가장 흔한 오류 2: acme-challenge 경로 차단

WordPress나 다른 CMS를 사용 중인 경우, .htaccess나 Nginx 설정에서 /.well-known/ 경로를 의도치 않게 차단하는 경우가 있다. Certbot은 이 경로에 검증 파일을 두고 Let’s Encrypt 서버가 접근하도록 해서 소유권을 증명한다.

/etc/nginx/sites-available/example.com – acme-challenge 허용 추가 server { listen 80; server_name example.com www.example.com; # acme-challenge 경로는 리다이렉트 전에 처리 location ^~ /.well-known/acme-challenge/ { root /var/www/example.com; allow all; } location / { return 301 https://$host$request_uri; } }
주의사항 Nginx에서 모든 트래픽을 HTTPS로 리다이렉트할 때, acme-challenge 경로가 리다이렉트 전에 처리되도록 위치를 주의해야 한다. location ^~ /.well-known/를 return 301 지시어보다 위에 두거나, 별도 server 블록에서 처리해야 한다.

수동 갱신 및 강제 갱신

터미널 # 일반 갱신 시도 (만료 30일 이하일 때만 갱신) sudo certbot renew # 강제 갱신 (만료 기간 무관) sudo certbot renew –force-renewal # 특정 도메인만 갱신 sudo certbot renew –cert-name example.com # 갱신 후 Nginx 재시작 sudo certbot renew && sudo systemctl reload nginx
갱신 오류 발생 시 점검 순서
  • sudo ufw status – 80, 443 포트 모두 열려 있는지 확인
  • sudo systemctl status nginx – Nginx 실행 중인지 확인
  • dig example.com +short – DNS A레코드가 서버 IP와 일치하는지 확인
  • curl -I http://example.com/.well-known/acme-challenge/test – 경로 접근 가능 여부 확인
  • sudo certbot renew –dry-run – 갱신 시뮬레이션으로 오류 메시지 확인
  • sudo tail -100 /var/log/letsencrypt/letsencrypt.log – 상세 오류 로그 확인
  • 위 모두 정상인데도 실패 시 sudo certbot renew –force-renewal 시도
실무 팁 갱신 실패를 이메일로 즉시 받아보고 싶다면 /etc/letsencrypt/cli.ini 파일에 post-hook = systemctl reload nginx를 추가하면 갱신 성공 시 Nginx가 자동으로 재로드된다. 갱신 실패 알림은 Let’s Encrypt 계정 이메일로 자동 발송되므로, 처음 certbot 설치 시 입력한 이메일 주소가 실제로 수신 가능한 메일인지 확인해두자.

FAQ – 자주 묻는 질문

certbot –nginx와 certbot certonly의 차이가 뭔가?
–nginx 플러그인은 인증서 발급 + Nginx 설정 자동 수정을 한 번에 해준다. certonly는 인증서만 발급하고 웹서버 설정은 건드리지 않는다. Nginx 설정을 직접 관리하고 싶거나, Apache 또는 다른 방식으로 운영 중일 때 certonly를 쓴다. 처음 세팅한다면 –nginx가 훨씬 편하다.
와일드카드 인증서(*.example.com)도 Certbot으로 발급 가능한가?
가능하다. 단, 와일드카드 인증서는 HTTP-01 챌린지가 아닌 DNS-01 챌린지 방식을 써야 한다. 도메인의 DNS에 TXT 레코드를 추가하는 방식이라 수동으로 하면 번거롭다. Cloudflare, Route53 같은 DNS 공급자라면 Certbot 플러그인으로 자동화할 수 있다. 예시: sudo certbot certonly --dns-cloudflare -d "*.example.com" -d "example.com"
인증서를 삭제하거나 도메인을 바꾸려면 어떻게 하나?
인증서 삭제는 sudo certbot delete --cert-name example.com으로 한다. 도메인을 추가하거나 변경하려면 기존 인증서를 삭제한 후 새로 발급하거나, –expand 옵션으로 기존 인증서에 도메인을 추가할 수 있다. sudo certbot --nginx --expand -d example.com -d newdomain.com
서버를 옮기거나 재설치할 때 인증서도 이전할 수 있나?
/etc/letsencrypt/ 폴더 전체를 새 서버로 복사하면 인증서 이전이 가능하다. 단, 새 서버에 Certbot이 설치되어 있어야 하고, 파일 권한도 그대로 유지해야 한다. 현실적으로는 새 서버에서 처음부터 다시 발급하는 게 더 간단하다. 어차피 무료니까.
갱신이 성공했는지 어떻게 확인하나?
sudo certbot certificates로 현재 인증서 만료일을 확인한다. 만료일이 갱신 전보다 90일에 가까워졌다면 정상적으로 갱신된 것이다. 또는 openssl s_client -connect example.com:443 < /dev/null 2>&1 | grep -i expire 명령으로 실제 연결된 인증서 만료일을 직접 확인할 수 있다.
Let’s Encrypt 인증서 발급 횟수에 제한이 있나?
있다. 동일 도메인 기준으로 1주일에 최대 5개의 인증서를 발급할 수 있다. 개발 테스트할 때 자꾸 발급 시도를 반복하면 이 제한에 걸린다. 그래서 테스트할 때는 항상 –staging 옵션을 쓰는 게 맞다. 만약 이미 제한에 걸렸다면 7일을 기다려야 한다.

전체 핵심 정리

설치 및 발급 핵심
  • snap으로 certbot 설치 (apt 버전 비권장)
  • 발급 전 DNS A레코드 + UFW 80포트 필수 확인
  • certbot –nginx로 발급 + Nginx 설정 자동화
  • 테스트는 반드시 –staging 옵션 사용
  • 발급 성공 후 HTTPS 리다이렉트 자동 적용됨
자동 갱신 핵심
  • snap 설치 시 systemd timer 자동 등록됨
  • 만료 30일 전부터 하루 2회 갱신 시도
  • dry-run으로 갱신 동작 사전 검증 필수
  • deploy hook으로 갱신 후 Nginx 자동 재로드
  • 갱신 실패 시 Let’s Encrypt 이메일로 알림 발송
갱신 오류 대응
  • 먼저 letsencrypt.log 확인으로 원인 파악
  • 80포트 차단 여부 + Nginx 실행 상태 체크
  • acme-challenge 경로 Nginx 설정 확인
  • DNS 변경 후 충분한 전파 시간 대기
  • rate limit 걸리면 7일 대기 후 재시도
Certbot, 한 번만 제대로 세팅하면 그다음은 자동이다
처음에 복잡해 보여도 결국 certbot –nginx 한 줄로 발급이 되고, 자동 갱신은 snap이 알아서 처리해준다. 중요한 건 처음 세팅할 때 dry-run으로 갱신까지 테스트해보고, 로그 위치를 알아두는 것이다. 서버 보안 설정을 더 강화하고 싶다면 UFW + Fail2ban 자동 IP 차단 설정이나 우분투 서버 보안 기초 설정 가이드도 함께 적용해두면 좋다. SSL까지 올렸으면 이제 진짜 서버 하나 제대로 운영할 준비가 된 것이다.