Nginx+certbot으로 https 요청 설정하기

·2024년 4월 19일
0
post-thumbnail

Nginx + certbot

let’s encrypt의 인증서를 온전하게 설정하기 위해서는 다음의 두 가지 환경이 구성되어야 한다.

  1. 현재 nginx가 오류 없이 정상적으로 운영되고 있어야 한다.
  2. certbot 및 python-certbot-nginx 가 설치되어 있어야 한다.

Nginx 문법 확인

nginx의 경우, 설정 사항을 반영하는 경우, 문법 오류가 없는지를 확인할 필요가 있다. 만약 문법 오류가 존재하는 경우, 제대로 실행되지 못하고 에러를 반환하기 때문에, nginx에 새로운 설정을 반영할 때 마다 문법 확인을 통해 오류가 없는지 확인할 필요가 있다.

(sudo) nginx -t

해당 커맨드를 입력했을 때, 터미널에 아래처럼 ok 출력이 떠야 설정에 오류가 없는 것이다.

순서 정리

아래의 순서는 도메인과 서버를 마련하고, 도메인에 현재 서버의 public ip를 등록했다고 가정한다.

현재 설계는 ubuntu 환경을 기반으로 작성했다.

  • nginx 설치 → nginx running 확인 → certbot 설정 → nginx 설정 → (시간대 확인) → 인증서 자동 갱신 설정

Nginx 설치

(sudo) apt-get install nginx
(sudo) apt-get install python3-certbot-nginx

Nginx Running 확인

(sudo) service nginx status
(sudo) service nginx start # 보통 설치하면 바로 실행이 되는 상황이라 반영하지 않아도 될 듯

아래와 같이 출력되고 있다면 정상적으로 실행되고 있는 것이다.

Let’s Encrypt로 SSL 발급하기

sudo certbot --nginx  -d <도메인 이름> # ex) abcdef.com

나타나는 y/n 선택지 에 모두 y 를 해주자. 중간에 email 을 등록할 것이냐고도 물어보는데 등록해주자. 추후 SSL 만료 시 인증서 재인증 알림을 email 로 보내준다.

/etc/letsencrpyt/live/도메인 아래에 README 외 4개의 .pem 키가 형성되었다면 정상적으로 SSL 이 발급된 것이다.

Nginx 설정 파일 구성

/etc/nginx/nginx.conf

Nginx에 관련한 메인설정파일로 Nginx 설정에 관한 블록들이 작성되어 있다. 이 파일에서 sites-enabled 폴더나 conf.d 에 있는 파일들을 include하여 설정들을 가져와 반영한다.

/etc/nginx/sites-available

가상 서버 환경들에 대한 설정 파일들이 위치하는 디렉토리이다. 실제 가상 서버가 돌던 안 돌던 가상 서버와 관련된 설정 파일들은 여기에 놓도록 한다.

/etc/nginx/sites-enabled

site-available 에 있는 가상 서버 파일들 중에서 실행시키고 싶은 파일을 symbolic link 로 연결한 폴더이다. 이 폴더에 위치한 가상서버 환경 파일들을 읽어서 실제 서버를 세팅한다.

symbolic link : 리눅스의 파일의 한 종류로, 컴퓨터의 다른 파일이나 폴더를 가리킨다. symlink 라 불리기도 하며, 윈도우 운영체제의 바로가기 와 유사하다.

/etc/nginx/conf.d

site-enabled 와 동일하게 설정 파일이 위치하는 디렉토리이다. 보통, sites-* 디렉토리의 경우, 설정을 추상화하고 좀 더 체계적으로 스크립트를 관리하기 위한 용도로 많이 사용한다.

Nginx 파일 설정하기

결과적으로, sites-avaiable 을 사용해도 되고, conf.d 경로에 설정을 반영해도 된다. nginx v1.18 기준으로 두가지 방식 모두 기본 반영이 되도록 설정이 되어있다.

나의 경우, 사이드 프로젝트이므로, 간단하게 처리하고자 conf.d 경로를 활용하여 설정을 반영했다.

/etc/nginx/conf.d/defalut.conf 를 생성하여 다음 설정을 반영한다. (꼭, default 라고 쓸 필요는 없다. .conf 로 포맷된 파일이면 된다. )

server {
    listen 443 ssl;
    server_name <도메인 이름>

    location / {
        proxy_pass http://127.0.0.1:<웹서버가 사용하는 포트>;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
    }

    # 아래 부분은 Let's encrypt를 통해 SSL 인증을 받은 키를 사용한다.
    ssl_certificate /etc/letsencrypt/live/<SSL 발급받은 도메인 이름>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<SSL 발급받은 도메인 이름>/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}

# http로 들어온 요청은 https로 리다이렉트 되도록 설정한다.
server {
    listen 80;
    location / {
        return 301 <도메인 이름>$request_uri;
    }
}

nginx 문법 오류 확인 후 재실행

(sudo) nginx -t
(sudo) service nginx reload

https 테스트

아래의 홈페이지에 현재 반영한 도메인을 입력하여, https 요청 시 SSL 인증이 정상적으로 동작하는지 확인할 수 있다.

https 테스트

SSL 인증서 자동 갱신 반영하기

let's encrypt 를 활용한 인증서는 기본적으로 90 일의 유효기간을 가지며, 해당 기간이 지나기 전에 새로운 인증서를 발급받아야 한다. 직접 접근하여 재발급받기 보다는 스케줄링을 활용하여 일정기간 마다 시스템이 알아서 새로운 인증서를 발급하도록 하자.

let's encrypt의 인증서는 만료기간 1달전 부터 갱신이 반영된다. 만약 만료기간이 1개월 이상 남았다면, 갱신을 시도하더라도 이루어지지 않는다. --dry-run 이라는 테스트 인증이 방법이 있으니, 만료기간이 1개월 이상 남았다면 테스트 인증이 정상적으로 되는지만 확인하자.

인증서 유효시간 확인

certbot 을 통해 인증서를 발급받았다면 명령어를 통해 현재 남은 유효기간을 확인할 수 있다.

(sudo) certbot certificates

인증서 자동 갱신

crontab 을 활용할 것이다. crontab 설정은 계졍마다 다르게 설정할 수 있으므로, 기본 ubuntu 계정에 적용할 것을 권장한다. (sudo 명령어와 함께 쓰지 말것)

crontab 설정

명령어를 입력하면, 어떤 입력기를 사용할 것인지 물어보는데 나의 경우 vim 을 선택했다.

crontab -e

이후 가장 아래에 다음의 명령어를 추가한다.

## 매일 새벽 3시에 재발급 명령을 실행 후 nginx 재시작
0 3 * * * certbot renew --renew-hook="sudo systemctl restart nginx"

crontab 설정사항 확인

cron 에 설정한 정보가 제대로 반영이 되었다면 명령어 입력 시 이미지와 같이 설정사항이 출력되어야 한다.

crontab -l

crontab 변경사항 반영

sudo service cron restart

시간대 맞추기

crontab 으로 설정한 시간은, 기본적으로 시스템 시간대를 기준으로 실행이 이루어진다. 만약, 시스템 사용자가 설정하고 싶은 시간은 한국 시간 기준 새벽 3시였으나, 시스템 시간이 미국 기준이라면 미국 시간의 새벽 3시를 기준으로 명령어가 실행될 수 있다는 것이다.

만약 사용하고 있는 서버 컴퓨터의 시간대가 의도한 시간과 다르다면, 이를 맞추는 작업이 필요하다.

시스템의 시간대는 해당 클라우드 환경의 지역시간으로 기본설정되는 경우가 많다. 예를들어 AWS 의 서울 지역을 선택하여 ec2 를 실행했다면, 기본 시간대는 Asia/Seoul 일 것이다.

시간대 확인

ubuntu 기준 시스템 시간대를 확인하는 명령어는 다음과 같다.

timedatectl

시간대 변경

sudo timedatectl set-timezone {지역} #Asia/Seoul



참고
웹서버에 HTTPS 적용하기 (Let’s Encrypt, Nginx, AWS EC2)
certbot 으로 let's encrypt 인증서 발급받기
[Ubuntu 22.04] 시간대 변경 (UTC -> KST)

profile
새로운 것에 관심이 많고, 프로젝트 설계 및 최적화를 좋아합니다.

2개의 댓글

comment-user-thumbnail
2024년 4월 20일

깔끔한 정리 잘 봤습니다 :) 심볼릭 링크 설명 중 [ 폴더리르 ] 에서 오타 있습니다!

1개의 답글