본문 바로가기

Linux

[Linux] 무료 SSL 인증서 발급 및 적용

 

SSL 이란?

 

웹 브라우저와 웹 서버 사이의 통신을 암호화하여 민감한 정보(개인정보, 결제 정보 등)를

보호하고 웹사이트의 신뢰성을 확인하는 Secure Sockets Layer(보안 소켓 계층) 이다.

현재는 보안이 강화된 TSL로 대체되었지만, 여전히 SSL/TLS 기술로 통칭되며,

HTTPS로 시작하는 웹사이트의 기본이 된다.

 

즉, SSL 인증서 덕분에 HTTP 보다 보안적 관점에서 더욱 뛰어난 HTTPS로 사용 가능하다.

따라서 HTTP로 만들었던 내 프로젝트를 SSL 인증서를 발급받은 후

HTTP → HTTPS 로 보안적 업그레이드를 하려고 한다.

 

그리고 가장 큰 불편함이었던, 브라우저에서 HTTP:// 로 들어간다면,

"안전하지 않음" 경고 태그가 가장 먼저 나타났기 때문에 가장 불편했다.

 


 

SSL 인증서 발급처 선택

 

SSL인증서를 발급받기 위해서 여럿 찾아본 결과 유료가 있었고, 무료가 있었다.

유료나 무료나 둘 다 공개키 기반으로 암호화가 되어있어서 암호화 강도는 동일하다.

다만, 보통 유료로 되어있는 SSL은 인증 수준이 차이가 난다.

 

DV, OV, EV 가 있는데 이 3개의 차이는

DV (Domain Validation) : "도메인의 소유자" 만 증명

OV (Organiztion Validation) : 법인 등록 정보와 회사명 확인 즉, 인증서에 회사 이름 표시

EV (Extended Validation) : 심층 검증 즉, 브라우저 주소창에 회사명 강조 표시

처럼 나누어져 있다.

 

또한 보통 유료로 가게된다면, 와일드카드 인증서란 것이 추가적으로 있는데,

단일 인증서 하나로 여러 하위 도메인을 보호할 수 있는 SSL 인증서이다.

즉 ".tistory.com" 과 같이 지정을 한다면 하위 도메인인

"Shop.tistory.com" , "Index.tistory.com" 등 여러 하위 도메인에서도

하나의 인증서로 관리할 수 있게 된다.

 

하지만 나는 단일 도메인인 myFCseoul.com 만 필요로 하고,

범인 등록도 되어있지 않고, 또한 회사도 없고 단순 개인 프로젝트에서

SSL 인증서를 등록해보는게 목표였기 때문에

DV 인증 등급만 적용하면 된다고 판단하였다.

 

따라서 DV 인증 등급만 적용할 수 있고, 또한 가격이 무료인 Let's Encrypt를 선택했다.

 


 

SSL 인증서 발급 과정 및 적용

 

1. 인증서 발급받기 (Let's Encrypt + Certbot)

⤷ EC2 서버에서 Certbot 컨테이너 실행 후 myfcseoul.com, www.myfcseoul.com  두 도메인에 대해

   무료 SSL 인증서 발급

⤷ HTTP-01 챌린지 방식 사용

   - Let's Encrypt 서버가 http://myfcseoul.com/.well-known/acme-challeng/로로 접근

   - EC2에서 80번 포트를 열어두고, Nginx가 이 경로만 예외 처리해 Certbot이 만든 파일을 내려줌

   - 검증이 완료된다면 인증서 (fullchain.pem, privkey.pem) 을 저장

docker run -it --rm \
  -v /home/ec2-user/myFCseoul/certbot/conf:/etc/letsencrypt \
  -v /home/ec2-user/myFCseoul/certbot/www:/var/www/certbot \
  certbot/certbot certonly --webroot \
  -w /var/www/certbot \
  -d myfcseoul.com -d www.myfcseoul.com

Certbot을 Docker로 실행함으로 사용하려는 두 도메인에 대해 검증을 받는다.

 

2. Nginx 설정 수정하기

server {
    listen 80;
    server_name 52.79.233.194 myfcseoul.com www.myfcseoul.com;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/certbot;
        default_type "text/plain";
        try_files $uri =404;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

80포트에서 모든 요청을 HTTPS로 리다이렉트 하되,

./well-known/acme-challenge/ 경로는 예외로 두어서 인증서 갱신이 가능하도록 하였다.

 

server {
    listen 443 ssl http2;
    server_name myfcseoul.com www.myfcseoul.com;

    ssl_certificate     /etc/letsencrypt/live/myfcseoul.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/myfcseoul.com/privkey.pem;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

443포트에서 HTTP/2를 활성화 하고, 인증서 경로를 설정해주었다.

 

그리고 기존에 80포트를 이용했던 WebSocket 프록시, API 프록시, OAuth2 엔드포인트 등등의 웹 서비스들을

443 포트로 모든 웹 서비스가 이루어 지도록 옮겨준 후 Nginx컨테이너 재시작했다.

 

3. 인증서 자동 갱신 설정

⤷ 인증서는 최대 90일짜리 이므로, 자동 갱신이 필요하다 따라서 EC2 환경에서 cron을 이용해서 자동 갱신하도록 설정 필요하다.

 

배시셸로 스크립트 실행하며, set -e, -u, -o pipefail 로 안전모드설정해주었다.

즉, 명령어 실패 시 즉시 종료, 선언되지 않은 변수를 쓰면 에러, 파이프라인에서 한쪽이라도 실패하면

전체 실패로 처리했다.

 

docer run --rm certbot/certbot 으로 Certbot 공식 이미지 실행하였고,

conf 는 인증서/키 파일 보관 위치이고,

www는 ACME 챌린지 파일 저장 위치이다.

renew 는 실제 인증서 갱신 시도이고, 만료 임박 시에만 새로 발급이 된다.

--webroot -w /var/www/certbot 으로 HTTP-01 방식, 지정 경로를 통해 검증하게끔 했다.

결과적으로, 만료까지 30일 이상 남아있으면 아무 일도 하지 않고 종료되게끔 했다.

앞서 만들었던 renew_certs.sh를 하루 2회 (03:22, 15:22) 에 반복하게 만들었고,

로그는 renew.log에 저장되도록 하였다.

 

로그를 확인해보니 2025-12-10이 만료일이라 아직 많이 남아있어 스킵된 것을 확인했다.

그리고 9월14일 18:22:07 은 nginx -s reload 명령이 실행된 흔적도 보았다.

인증서가 갱신되지 않았더라도, reload자체에는 문제가 없기 때문에 그대로 실행되었다.

그리고 동시에 Nginx에서  listen 443 ssl http2; 라는 문법이 구식이라는 경고를 확인했다.

server {
    listen 443 ssl;
    http2 on;

따라서 최신 문법인 listen 443 ssl; http2 on; 로 수정하였다.

 

그렇게 정상적으로 https:// 으로 응답하는 것까지 확인했다.

'Linux' 카테고리의 다른 글

[Linux] 리눅스에서 Swap 적용 해 보기  (1) 2025.07.29

GitHub