본문으로 건너뛰기
자물쇠 아이콘과 디지털 보안 방패가 서버를 보호하는 이미지

# HTTPS는 선택이 아닌 필수: Let's Encrypt로 평생 무료 SSL 인증서 발급받기

Table of Contents

홈서버를 구축하고 외부에서 접속할 때, 주소창 옆에 뜬 ‘주의 요함(Not Secure)‘이라는 빨간 글씨를 본 적이 있을 것입니다. 이 경고 문구는 단순히 보기 싫은 것을 넘어, 내 서버가 해커들의 먹잇감이 될 수 있다는 심각한 경고입니다.

우리가 흔히 쓰는 HTTP 프로토콜은 데이터를 암호화하지 않고 날것 그대로 전송합니다. 카페 와이파이 같은 공용 네트워크에서 해커가 마음만 먹으면, 로그인할 때 입력한 아이디와 비밀번호를 낚아채는 것은 식은 죽 먹기입니다. 이를 방지하기 위해 데이터를 암호화하여 전송하는 기술이 바로 **HTTPS(SSL/TLS)**입니다.

과거에는 SSL 인증서를 발급받으려면 매년 수십만 원의 비용을 지불해야 했습니다. 하지만 Let’s Encrypt의 등장으로 이제는 누구나 무료로, 그것도 자동으로 갱신되는 인증서를 사용할 수 있게 되었습니다.

이번 글에서는 웹 보안의 기본인 HTTPS의 중요성을 알아보고, Certbot 도구를 사용하여 내 서버에 무료 SSL 인증서를 적용하는 방법을 아주 상세하게, 단계별로 알아보겠습니다.

1. HTTP vs HTTPS: 왜 자물쇠가 필요한가?

엽서와 편지 봉투

HTTP와 HTTPS의 차이는 ‘엽서’와 ‘편지 봉투’에 비유할 수 있습니다.

  • HTTP (엽서): 우체부, 배달원, 심지어 우편함을 지나가는 이웃까지 엽서에 적힌 내용을 볼 수 있습니다. “비밀번호: 1234”라고 적어서 보내면 배달 경로에 있는 모든 사람이 그 비밀번호를 알게 됩니다.
  • HTTPS (편지 봉투): 내용은 편지 봉투 안에 밀봉되어 있습니다. 겉면에는 ‘보내는 사람’과 ‘받는 사람’만 적혀 있습니다. 배달원은 봉투를 목적지까지 배달만 할 뿐, 그 안의 내용을 뜯어볼 수 없습니다.

패킷 스니핑의 공포

실제로 네트워크 패킷 분석 도구인 ‘와이어샤크(Wireshark)‘를 이용해 HTTP 통신을 감청해 보면 충격적인 결과를 볼 수 있습니다. 사용자가 입력 폼에 적은 아이디, 비밀번호, 주소 등의 정보가 평문(Plain Text) 그대로 노출됩니다. 반면 HTTPS를 적용하면 이 모든 데이터가 외계어 같은 난수표로 암호화되어 전송되므로, 해커가 패킷을 가로채더라도 내용을 해독할 수 없습니다.

2. Let’s Encrypt: 보안의 민주화

Let’s Encrypt는 “전 세계 모든 웹사이트를 HTTPS로 만들자”는 목표를 가진 비영리 인증 기관(CA)입니다. 모질라, 시스코, 크롬 등 거대 IT 기업들의 후원을 받아 운영되며, 다음과 같은 혁신적인 특징을 가지고 있습니다.

  1. 완전 무료: 발급 비용도, 갱신 비용도 없습니다.
  2. 자동화: 복잡한 서류 제출 없이 소프트웨어 명령만으로 즉시 발급됩니다.
  3. 오픈소스: 발급 도구와 프로토콜이 모두 공개되어 있습니다.

단, 보안을 위해 인증서의 유효 기간이 90일로 짧게 설정되어 있습니다. “3개월마다 갱신해야 한다니 너무 귀찮은 거 아닌가요?”라고 생각할 수 있습니다. 하지만 걱정하지 마세요. 우리에게는 이 과정을 알아서 처리해 주는 Certbot이라는 봇이 있습니다.

3. 실전: Certbot으로 Nginx에 SSL 적용하기

이제 직접 서버에 접속하여 인증서를 발급받아 보겠습니다. 이 가이드는 가장 보편적인 우분투(Ubuntu) 22.04/24.04 LTSNginx 웹 서버 환경을 기준으로 합니다.

준비물 확인

시작하기 전에 다음 사항들을 확인해 주세요.

  1. 도메인: myserver.com과 같은 개인 도메인이 있어야 합니다. (DuckDNS 무료 도메인도 가능)
  2. 포트 포워딩: 공유기에서 80번 포트(HTTP)와 443번 포트(HTTPS)가 서버 IP로 포워딩되어 있어야 합니다.
  3. Nginx 설치: sudo apt install nginx 명령어로 웹 서버가 설치되어 있어야 합니다.

1단계: Certbot 설치

과거에는 apt 패키지 매니저를 썼지만, 최근에는 snap을 이용한 설치가 권장됩니다. 항상 최신 버전을 유지할 수 있기 때문입니다.

# 1. 스냅(snapd)이 최신인지 확인
sudo snap install core; sudo snap refresh core

# 2. 기존에 설치된 certbot이 있다면 제거 (충돌 방지)
sudo apt-get remove certbot

# 3. Certbot 설치
sudo snap install --classic certbot

# 4. 바로가기 링크 생성 (어디서든 certbot 명령어를 쓰기 위해)
sudo ln -s /snap/bin/certbot /usr/bin/certbot

2단계: Nginx 설정 파일 확인

Certbot이 자동으로 설정을 고쳐주려면, Nginx가 내 도메인을 알고 있어야 합니다. 설정 파일을 열어 server_name 부분을 확인합니다.

# 설정 파일 열기 (보통 default 파일 사용)
sudo nano /etc/nginx/sites-available/default

파일 내용 중 server_name 옆에 본인의 도메인을 적어줍니다.

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;

    server_name example.com www.example.com; # 여기를 수정하세요!

    location / {
        try_files $uri $uri/ =404;
    }
}

수정 후 Ctrl+O로 저장하고 Ctrl+X로 빠져나옵니다. 그리고 sudo nginx -t 명령어로 설정에 오타가 없는지 확인한 뒤, sudo systemctl reload nginx로 설정을 적용합니다.

3단계: 인증서 발급 및 적용

이제 대망의 발급 시간입니다. 아래 명령어 한 줄이면 됩니다.

sudo certbot --nginx

이 명령어를 입력하면 몇 가지 질문이 나옵니다.

  1. 이메일 입력: 긴급 보안 공지나 갱신 실패 알림을 받을 이메일을 입력합니다.
  2. 약관 동의: Y를 입력하여 동의합니다.
  3. 이메일 공유: EFF 재단에 이메일을 공유할지 묻습니다. N을 해도 무관합니다.
  4. 도메인 선택: Nginx 설정에서 읽어온 도메인 목록이 뜹니다. 인증서를 적용할 도메인 번호를 선택합니다. (예: 1번과 2번 모두 적용하려면 1 2 입력 후 엔터)

잠시 기다리면 “Congratulations!”라는 메시지와 함께 인증서 발급이 완료됩니다. 이제 웹 브라우저에서 https://내도메인으로 접속해 보세요. 주소창 옆에 예쁜 자물쇠 아이콘이 보일 것입니다.

4단계: 자동 갱신 테스트

앞서 말씀드린 대로 Let’s Encrypt 인증서는 90일짜리입니다. Certbot을 설치하면 자동으로 갱신을 위한 타이머(Systemd timer)가 등록됩니다. 하루에 두 번씩 만료일이 다가왔는지 체크합니다.

이 기능이 제대로 작동하는지 확인하기 위해 ‘리허설’을 해볼 수 있습니다.

sudo certbot renew --dry-run

--dry-run 옵션은 실제로 인증서를 갱신하지 않고, 갱신 과정에 문제가 없는지 시뮬레이션만 수행합니다. “Congratulations, all simulated renewals succeeded”라는 메시지가 뜬다면, 이제 평생 인증서 갱신 걱정은 안 해도 됩니다.

4. 고급: 도메인 소유권 확인 방식 (Challenge Types)

Certbot이 “이 도메인이 정말 네꺼 맞아?”라고 확인하는 과정에는 두 가지 방식이 있습니다. 우리가 방금 한 것은 HTTP-01 방식입니다.

HTTP-01 챌린지 (기본값)

  • 원리: Let’s Encrypt 서버가 내 도메인의 특정 경로(http://내도메인/.well-known/acme-challenge/랜덤파일)에 접속을 시도합니다. 내 서버가 그 파일을 올바르게 보여주면 소유권을 인정받습니다.
  • 장점: 설정이 가장 간편합니다. --nginx 옵션이 알아서 다 해줍니다.
  • 단점: 80번 포트(HTTP)가 반드시 열려 있어야 합니다. 인터넷 회선 문제로 80번이 막혀있다면 사용할 수 없습니다. 와일드카드 인증서(*.example.com) 발급이 불가능합니다.

DNS-01 챌린지

  • 원리: 도메인의 DNS 레코드에 특정 텍스트(TXT 레코드)를 추가하여 소유권을 증명합니다. “네가 도메인 관리자라면 DNS를 수정할 수 있겠지?”라고 묻는 것입니다.
  • 장점: 서버의 포트를 열지 않아도 인증서를 받을 수 있습니다. 즉, 외부 접속이 불가능한 내부망 서버도 HTTPS를 쓸 수 있습니다. 모든 서브 도메인을 커버하는 와일드카드 인증서 발급이 가능합니다.
  • 단점: Cloudflare, AWS Route53 같은 DNS 제공 업체의 API 키가 필요하며 설정이 다소 복잡합니다.

5. SSL 보안 등급 확인하기

인증서를 적용했다고 끝이 아닙니다. 서버의 보안 설정이 얼마나 튼튼한지 성적표를 받아볼 수 있습니다. Qualys SSL Labs (https://www.ssllabs.com/ssltest/) 사이트에 접속하여 본인의 도메인을 입력해 보세요.

A등급 이상을 받는 것이 목표입니다. 만약 B나 C등급이 나왔다면, 구형 프로토콜(TLS 1.0, 1.1)을 비활성화하고 최신 TLS 1.2, 1.3만 허용하도록 Nginx 설정을 수정해야 합니다. 다행히 Certbot이 자동으로 설정해 준 값들은 대부분 최신 보안 표준을 따르므로 A등급을 받을 수 있을 것입니다.

6. 자주 묻는 질문 (FAQ)

Q. IP 주소로도 인증서를 받을 수 있나요? A. 불가능합니다. Let’s Encrypt는 ‘도메인 이름’에 대해서만 인증서를 발급합니다. IP 주소(123.45.67.89)에 대한 SSL 인증서는 매우 비싼 유료 서비스에서만 제한적으로 제공합니다. DuckDNS 같은 무료 DDNS를 활용하세요.

Q. 80번 포트가 막혀있어요. (ISP 차단) A. 한국의 일부 가정용 인터넷(ISP)은 웹 서버 운영을 막기 위해 80번 포트를 차단하는 경우가 있습니다. 이 경우 HTTP-01 챌린지를 사용할 수 없습니다. DNS-01 챌린지 방식을 사용해야 합니다.

Q. 인증서 발급 횟수 제한이 있나요? A. 네, 있습니다. 동일한 도메인에 대해 일주일에 5번까지만 중복 발급이 가능합니다. 설정이 꼬여서 계속 재발급 시도를 하다가 이 제한(Rate Limit)에 걸리면 꼼짝없이 1주일을 기다려야 합니다. 테스트할 때는 반드시 --dry-run이나 --staging 옵션을 사용하여 실제 발급 횟수를 아끼세요.

7. 마치며: 보안은 습관입니다

이제 여러분의 서버는 HTTPS라는 튼튼한 방패를 얻었습니다. 브라우저 주소창의 자물쇠 아이콘은 단순한 장식이 아닙니다. 나와 내 가족의 소중한 데이터를 지키겠다는 약속이자 증명입니다.

하지만 서버가 늘어나고 관리해야 할 컨테이너가 많아지면, 각각의 컨테이너마다 Certbot을 설치하고 관리하는 것은 매우 비효율적입니다. “도커 컨테이너가 10개면 인증서도 10번 받아야 하나요?” 아닙니다. 우리에게는 **리버스 프록시(Reverse Proxy)**라는 훌륭한 해결책이 있습니다.

다음 포스팅에서는 이 모든 인증서 관리와 도메인 연결을 웹 화면에서 클릭 몇 번으로 해결해 주는 **“Nginx Proxy Manager로 쉽게 리버스 프록시 설정하기”**에 대해 알아보겠습니다. 터미널 명령어 없이 마우스 클릭만으로 SSL을 적용하는 신세계를 경험하게 될 것입니다.

이 글 공유하기:
다음 글: 외부 접속의 정석: DDNS와 포트포워딩 완벽 가이드
My avatar

글을 마치며

이 글이 도움이 되었기를 바랍니다. 궁금한 점이나 의견이 있다면 댓글로 남겨주세요.

더 많은 기술 인사이트와 개발 경험을 공유하고 있으니, 다른 포스트도 확인해보세요.

유럽살며 여행하며 코딩하는 노마드의 여정을 함께 나누며, 함께 성장하는 개발자 커뮤니티를 만들어가요! 🚀


홈서버 마스터 클래스 시리즈