5편에서 도메인이 붙었습니다. 그런데 주소창을 보면 ddlabx.com 옆에 “주의 요함”이 붙어 있죠. 크롬이 방문자에게 “이 사이트 안전하지 않다”고 말하고 있는 겁니다. 애드센스를 노리는 블로그에 이건 치명적입니다.
이번 편에서 없앱니다. 명령어 한 줄이면 됩니다. 진짜 어려운 건 발급이 아니라 90일마다 돌아오는 갱신이고, 더 중요한 건 2027년부터 그 90일이 64일로 줄어든다는 사실입니다. 이것부터 알고 시작하는 게 이 글의 핵심입니다.
왜 HTTPS인가 — 자물쇠 아이콘 그 이상
| 이유 | 내용 |
|---|---|
| 보안 | HTTP는 로그인 비밀번호가 평문으로 흐릅니다. 공용 와이파이에서 관리자 로그인하면 그대로 노출됩니다 |
| 신뢰 | 크롬이 “주의 요함”을 띄웁니다. 방문자는 이유를 모른 채 뒤로가기를 누릅니다 |
| 검색 | 구글이 HTTPS를 순위 신호로 씁니다 |
| 광고 | 애드센스 심사에서 신뢰도 항목에 영향을 줍니다 |
| 기능 | HTTP/2 등 최신 기능이 사실상 HTTPS 전용입니다 |
제일 큰 건 첫 줄입니다. 지금 http://ddlabx.com/wp-admin으로 로그인하고 계신다면, 그 비밀번호는 중간의 누군가가 그대로 읽을 수 있습니다.
시작 전 — 이 두 가지가 안 되어 있으면 무조건 실패합니다
Certbot이 인증서를 주는 방식은 HTTP-01 챌린지입니다. Let’s Encrypt 서버가 http://ddlabx.com/.well-known/acme-challenge/...로 직접 찾아와서 특정 파일이 있는지 확인합니다. “이 도메인이 정말 네 서버냐”를 검증하는 거죠.
그래서 두 조건이 필수입니다.
| 조건 | 어느 편에서 했나 | 확인 명령 |
|---|---|---|
| 도메인이 서버 IP를 가리킬 것 | 5편 | dig ddlabx.com +short |
| 80 포트가 열려 있을 것 | 2편 (Nginx Full) | sudo ufw status |
주의 — 도메인 연결(5편)을 건너뛰고 여기부터 하면 100% 실패합니다. Let’s Encrypt가 찾아올 주소가 없으니까요. 순서를 지켜야 하는 이유가 이것입니다. 또한 80 포트를 “HTTPS 쓸 거니까 이제 필요 없겠지” 하고 닫으면 갱신이 조용히 실패합니다. 80은 계속 열어두세요.
Certbot 설치 — apt냐 snap이냐
여기서 갈립니다. Let’s Encrypt 공식 문서는 snap을 권하고, 우분투 저장소에도 certbot이 있습니다.
| apt (우분투 저장소) | snap (공식 권장) | |
|---|---|---|
| 설치 | apt install certbot python3-certbot-nginx | snapd 통해 설치 |
| 버전 | 우분투 릴리스 시점에 고정 | 항상 최신 |
| 메모리 | 가벼움 | snapd 상주 (2GB 서버에선 체감) |
| 업데이트 | apt와 함께 | 자동 |
| 관리 편의 | 다른 패키지와 동일하게 | 별도 체계 |
저는 apt를 골랐습니다. 2편에서 PPA를 안 쓴 것과 같은 이유예요 — 관리 창구를 하나로 유지하는 게 개인 서버에선 이득입니다. 다만 아래 “2027년” 항목을 읽고 나면 snap 쪽 논거도 이해가 되실 겁니다. 둘 다 정답이 있는 선택은 아닙니다.
sudo apt install certbot python3-certbot-nginx -y
certbot --version
인증서 발급 — 한 줄
sudo certbot --nginx -d ddlabx.com -d www.ddlabx.com
-d를 두 번 쓴 게 중요합니다. www와 non-www는 인증서 입장에서 다른 이름입니다. 하나만 넣으면 다른 쪽에서 경고가 뜹니다. 5편에서 A 레코드를 두 줄 넣은 것과 정확히 같은 이유입니다.
질문이 몇 개 나옵니다.
| 질문 | 답 | 왜 |
|---|---|---|
| 이메일 주소 | 실제로 쓰는 주소 | 만료 임박 경고가 여기로 옵니다. 자동 갱신이 고장 났을 때의 마지막 알림입니다 |
| 약관 동의 | Y | 필수 |
| EFF 뉴스레터 | 취향 | 무관 |
| HTTP → HTTPS 리다이렉트 | 2 (Redirect) | 안 하면 두 주소가 공존해 SEO가 갈립니다 |
Congratulations!이 뜨면 끝입니다. 브라우저를 새로고침하면 자물쇠가 붙어 있습니다.
Certbot이 내 설정 파일에 무슨 짓을 했나
“알아서 해줬다”로 넘어가면 나중에 고장 났을 때 손을 못 댑니다. 2편에서 직접 쓴 서버 블록을 열어보세요.
sudo cat /etc/nginx/sites-available/ddlabx
# managed by Certbot 주석이 붙은 줄들이 새로 생겼습니다.
| 추가된 것 | 역할 |
|---|---|
listen 443 ssl; | HTTPS 포트를 듣기 시작 |
ssl_certificate /etc/letsencrypt/live/ddlabx.com/fullchain.pem; | 인증서 본체 + 중간 인증서 |
ssl_certificate_key .../privkey.pem; | 개인키 — 절대 유출 금지 |
include .../options-ssl-nginx.conf; | 안전한 암호 스위트 기본값 |
return 301 https://$host$request_uri; | 80으로 온 요청을 443으로 넘김 |
주목할 건 리다이렉트를 처리하는 80 포트 server 블록이 그대로 남아 있다는 점입니다. 이게 갱신 때 Let’s Encrypt가 찾아오는 통로이기도 합니다. 80을 닫으면 안 되는 이유가 여기 또 있습니다.
sudo nginx -t
자동 갱신 — 진짜 중요한 건 여기부터
Let’s Encrypt 인증서는 90일짜리입니다. 유료 인증서(1년)에 비해 짧죠. 이건 불편이 아니라 의도된 설계입니다.
| 이유 | 설명 |
|---|---|
| 자동화 강제 | 90일마다 손으로 하는 건 불가능하니 모두가 자동화하게 됨 |
| 피해 최소화 | 개인키가 유출돼도 악용 기간이 최대 90일 |
| 폐기 효율 | 인증서 폐기 목록을 짧게 유지 |
apt로 설치하면 갱신 타이머가 자동으로 등록됩니다. 별도 cron을 만들 필요가 없어요.
systemctl list-timers | grep certbot
systemctl status certbot.timer
이 타이머는 하루 두 번 돌면서 “만료까지 30일 미만이면 갱신”을 판단합니다. 매번 발급받는 게 아니라 필요할 때만 움직이니 부담이 없습니다.
그런데 “등록됐으니 되겠지”가 제일 위험합니다. 갱신은 89일 뒤에 처음 시도되고, 그때 실패하면 사이트가 인증서 만료로 통째로 경고 화면이 됩니다. 그래서 지금 리허설을 합니다.
sudo certbot renew --dry-run
이 명령은 실제 발급 없이 전 과정을 그대로 시연합니다. 실서버 인증서를 건드리지 않고, 발급 횟수 제한에도 안 걸립니다. Congratulations, all simulated renewals succeeded가 뜨면 90일 뒤에도 안전하다는 뜻입니다.
주의 — 이 한 줄을 안 돌리고 넘어가는 게 SSL 사고의 1순위 원인입니다. 발급은 됐는데 갱신 경로가 막혀 있는 상태를 3개월 동안 모르고 지냅니다. 지금 30초 쓰세요.
2027년, 90일이 64일이 됩니다
여기가 다른 글에 없는 부분입니다. Let’s Encrypt가 인증서 유효기간을 단축합니다. 2025년 12월 공식 발표로, CA/Browser Forum 기본 요구사항에 따른 업계 전체의 변경입니다. Let’s Encrypt만의 정책이 아니라 모든 공인 인증기관이 같은 방향으로 갑니다.
| 시점 | 무슨 일 | 내게 미치는 영향 |
|---|---|---|
| 2026년 5월 13일 | tlsserver 프로파일이 45일 발급 시작 | 없음 — 선택(opt-in) 방식입니다 |
| 2027년 2월 10일 | 기본 classic 프로파일이 64일로 전환 | 여기서부터 자동 적용 |
| 2028년 2월 16일 | classic이 45일로 추가 단축 | 갱신 빈도가 다시 두 배 |
날짜가 지난 뒤 다음 갱신부터 짧은 인증서를 받게 됩니다. 그럼 뭘 해야 하나 — 대부분은 아무것도 안 해도 됩니다. Let’s Encrypt도 자동 발급을 쓰는 사용자는 변경이 불필요하다고 안내합니다. Certbot 타이머는 “60일마다”가 아니라 “남은 기간이 30일 미만이면”으로 판단하기 때문에, 인증서가 짧아지면 알아서 더 자주 갱신합니다.
문제가 되는 건 기간을 하드코딩한 경우입니다.
| 갱신 방식 | 2027년 이후 |
|---|---|
| Certbot 기본 타이머 (남은 기간 기준) | 안전 — 손댈 것 없음 |
| “60일마다 갱신” 같은 고정 주기 cron | 위험 — 64일 인증서에 부적합 |
| 수동 갱신 | 권장되지 않음. 더 자주 해야 함 |
즉 직접 cron을 짜서 “N일마다”로 돌리고 있다면 지금 지우고 certbot 타이머에 맡기세요. 그리고 갱신 시점을 인증기관이 알려주는 ARI라는 방식을 Let’s Encrypt가 권장하고 있으니, Certbot을 최신으로 유지하는 것도 의미가 있습니다. 아까 snap 쪽 논거가 여기서 살아납니다.
참고 — 이 글을 읽는 시점이 2027년 2월 이후라면 sudo certbot certificates로 실제 만료일을 확인해 보세요. 90일이 아니라 64일 뒤로 찍혀 있을 겁니다. 놀랄 일이 아니라 예정된 변화입니다.
발급 횟수 제한 — 실패했을 때 함정
Let’s Encrypt에는 발급 제한이 있습니다. 무료 서비스를 모두가 쓸 수 있게 하기 위한 장치인데, 설정이 안 돼서 계속 재시도할 때 여기 걸립니다.
| 제한 | 내용 |
|---|---|
| 동일 도메인 조합 중복 발급 | 주 5회 — 디버깅하며 반복 실행하면 여기 걸립니다 |
| 등록 도메인당 발급 | 주 50개 |
| 갱신 | 등록 도메인당 제한에서 면제 |
그래서 안 될 때 무작정 재시도하면 안 됩니다. 실패하면 로그를 보고 원인을 고친 뒤에 다시 하세요. 3편에서 배운 것과 같은 원칙입니다.
sudo tail -30 /var/log/letsencrypt/letsencrypt.log
테스트가 필요하면 --dry-run이나 --staging을 쓰세요. 제한에 안 걸립니다.
안 될 때 — 증상별 원인
| 메시지·증상 | 원인 | 조치 |
|---|---|---|
DNS problem: NXDOMAIN | 도메인이 아직 서버를 안 가리킴 | dig ddlabx.com +short (5편) |
Timeout during connect | 80 포트 막힘 | sudo ufw status + Vultr 방화벽 |
Invalid response ... 404 | 서버 블록 root·server_name 불일치 | grep server_name /etc/nginx/sites-available/ddlabx |
too many certificates | 재시도로 제한 초과 | 기다리기. --dry-run으로 먼저 확인 |
| 자물쇠에 노란 경고 | 혼합 콘텐츠 — 페이지 안에 http 링크 | 아래 항목 참고 |
| 무한 리다이렉트 | WP 주소와 Nginx 리다이렉트 충돌 | WP 설정 → 일반의 주소 확인 |
혼합 콘텐츠는 발급 직후 흔합니다. 페이지는 HTTPS인데 이미지 주소가 http://로 남아 있으면 브라우저가 자물쇠를 완전히 안 채워줍니다. 워드프레스에서 설정 → 일반의 두 주소를 https://로 바꾸고, 기존 글 본문에 박혀 있는 http://ddlabx.com 링크는 DB에서 일괄 치환해야 합니다. 이건 그 자체로 한 편짜리 주제라 따로 다루겠습니다.
자주 묻는 질문
Q. 무료인데 유료 인증서보다 못한가요?
A. 암호화 강도는 완전히 같습니다. 브라우저 자물쇠도 똑같이 채워집니다. 차이는 유효기간(90일 vs 1년), 보증 보험 유무, 기업 실체를 확인하는 OV/EV 인증서 발급 여부입니다. 개인 블로그에는 아무 의미 없는 차이예요. 게다가 유효기간 차이도 업계 전체가 짧아지는 방향이라 곧 무의미해집니다.
Q. 인증서가 만료되면 어떻게 되나요?
A. 방문자에게 빨간 경고 화면이 뜹니다. “주의 요함”과는 차원이 다르게 무섭고, 대부분 그냥 나갑니다. 그래서 certbot renew --dry-run과 발급 시 입력한 이메일이 중요합니다. 만료 전에 Let’s Encrypt가 그 주소로 경고를 보냅니다.
Q. 서버를 옮기면 인증서도 옮기나요?
A. /etc/letsencrypt/를 통째로 복사하는 방법도 있지만, 새 서버에서 새로 발급받는 게 훨씬 깔끔합니다. 무료니까요. 다만 DNS가 새 서버를 가리킨 뒤에 해야 합니다. 순서는 늘 같습니다.
Q. HSTS를 켜라던데요?
A. 브라우저에게 “이 사이트는 앞으로 무조건 HTTPS로만 접속해”라고 기억시키는 헤더입니다. 보안상 좋지만 초보자에게는 권하지 않습니다. 한번 켜면 설정한 기간 동안 브라우저가 기억해서, 나중에 HTTP로 되돌리고 싶어도 방문자 브라우저에서 되돌릴 방법이 없습니다. 사이트가 몇 달 안정적으로 돌아간 뒤에 짧은 기간부터 시작하세요.
Q. 이제 80 포트를 닫아도 되나요?
A. 안 됩니다. 갱신 때 Let’s Encrypt가 80으로 찾아옵니다. 닫으면 갱신이 조용히 실패하고, 89일 뒤에 사이트가 죽습니다. 지금 리다이렉트 블록이 80을 잘 쓰고 있으니 Nginx Full 그대로 두세요.
정리하면
- 발급은 한 줄입니다 —
sudo certbot --nginx -d ddlabx.com -d www.ddlabx.com. www와 non-www 둘 다 넣으세요. - 사전 조건 두 개 — DNS가 서버를 가리킬 것(5편), 80 포트가 열려 있을 것(2편). 하나라도 없으면 무조건 실패합니다.
- 발급 후 반드시
sudo certbot renew --dry-run. 이 30초를 아끼면 89일 뒤에 사이트가 죽습니다. - 80 포트를 닫지 마세요. 갱신 통로입니다.
- 2027년 2월 10일부터 기본 인증서가 64일, 2028년 2월 16일부터 45일이 됩니다. 업계 공통 변경입니다.
- Certbot 기본 타이머는 “남은 기간 30일 미만” 기준이라 그대로 두면 안전합니다. 위험한 건 “N일마다”로 하드코딩한 cron입니다. 있다면 지우세요.
- 안 될 때 재시도를 반복하면 주 5회 중복 발급 제한에 걸립니다.
--dry-run이나--staging으로 시험하세요. - 발급 시 이메일은 실제로 쓰는 주소로. 자동 갱신이 고장 났을 때 유일한 알림입니다.
여기까지가 빈 서버에서 HTTPS 블로그까지의 전 과정입니다. 1편에서 티스토리를 떠난다고 선언하고, 2편에서 LEMP를 올리고, 3편에서 500 오류를 잡고, 4편에서 문을 잠그고, 5편에서 간판을 달고, 이제 자물쇠까지 채웠습니다. 관리형 호스팅 없이 전부 손으로요. 이 과정을 한 번 통과하면 서버가 더 이상 블랙박스가 아니게 됩니다. 그게 이 시리즈의 진짜 목적이었습니다.