Nginx 이용해 Https 적용하기

junhyeong·2024년 7월 23일
1

AWS 프리티어를 사용해 뽀모도로 서비스를 운영하던 중, ELB 로드밸러서 사용으로 인해 비용문제가 발생했습니다. 이를 해결하기 위해 Nginx를 이용하여 ELB 로드밸런서의 역할을 대체하려고 합니다.

문제 배경

Https를 적용하고 리다이렉트를 하기 위해서 로드밸런서를 사용하면 가용영역이 2개 이상 필요합니다. 이로 인해 VPC 비용이 발생하게 되는데, AWS에서는 2024년 2월부터 VPC 비용을 부과하기 시작하여 프리티어 사용자들에게도 비용이 나오기 시작했습니다.

(총 12.40달러)

nginx란?

Nginx는 경량 웹 서버로서 HTTP 웹 서버, 로드 밸런서, 리버스 프록시 서버 등 다양한 역할을 수행할 수 있습니다.

이를 활용하여 AWS의 ELB 로드밸런서를 대체할 수 있습니다.

nginx 설정하기

준비 사항

  • 도메인 구입
  • ec2 생성 및 어플리케이션 배포중인 상태

1. Nginx 설치

  1. 패키지 목록 업데이트
sudo apt update
  1. Nginx 설치
sudo apt install nginx
  1. Nginx 상태 확인
sudo systemctl status nginx

2. Nginx 설정하기

  1. nginx설정파일이 위치한 /etc/nginx 경로로 이동
cd /etc/nginx/conf.d
  1. 설정파일 생성
sudo vi default.conf
  1. 설정 파일 작성
server {
    server_name [도메인];  # 도메인 설정
    location / { # 처리할 URL 경로 설정
        proxy_set_header X-Real-IP $remote_addr;  # 원본 클라이언트의 IP 주소를 전달
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  # 원본 클라이언트와 프록시를 거친 IP 주소들을 전달
        proxy_set_header Host $http_host;  # 원본 요청의 호스트 헤더를 전달
        proxy_pass http://127.0.0.1:8080;  # 애플리케이션이 실행 중인 포트
    }
}
  • server_name [도메인];: 이 지시자는 서버 블록에 대한 도메인 이름을 설정합니다. 클라이언트 요청의 호스트 헤더와 일치하는 서버 블록을 선택하는 데 사용됩니다.
  • location / {}: 이 블록은 기본 URL 경로에 대한 설정을 정의합니다. 모든 요청을 프록시 서버로 전달하는 역할을 합니다.
  • proxy_set_header X-Real-IP $remote_addr;: 클라이언트의 실제 IP 주소를 백엔드 서버에 전달합니다.
  • proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;: 프록시 서버를 거친 모든 클라이언트 IP 주소를 백엔드 서버에 전달합니다.
  • proxy_set_header Host $http_host;: 클라이언트의 요청 호스트 헤더를 백엔드 서버에 전달합니다.
  • proxy_pass http://127.0.0.1:8080;: 모든 요청을 로컬 호스트의 8080 포트에서 실행 중인 애플리케이션으로 전달합니다.
  1. nginx 재시작

nginx 설정을 적용하기 위해 nginx를 재시작해줍니다

sudo systemctl restart nginx

3. Https 적용 및 리다이렉트 설정

인증서를 무료로 발급해주고 있고 SSL 인증서 설치 및 환경설정을 편리하게 해주는 Certbots를 제공해주는 Let’s Encrypt라는 기관을 이용해서 인증서를 발급받고 적용해보겠습니다.

일일히 모든 설정을 하기에는 시간이 너무 오래 걸리기 때문에 certbot을 이용하여 인증서 설정을 해볼 것입니다.

  1. certbot을 설치하기 위한 snap 설치
sudo apt update
sudo apt install snapd
  1. certbot 설치
sudo snap install --classic certbot
  1. 인증서 발급
sudo certbot --nginx

여기서 이메일 입력 및 약관동의 후 인증서를 발급받고 싶은 도메인을 선택하면 해당 도메인에 대한 인증서가 발급됩니다.

(도메인이 여러개인 경우 1,2,3의 형식으로 선택)
인증서 발급이 완료되면 https가 적용된 걸 확인할 수 있습니다.

4. 인증서 갱신 자동화

Let’s Encrypt에서 발급해주는 인증서는 무료 인증서로 3개월의 유효기간을 가지고 있습니다.

하지만 3개월마다 주기적으로 인증서를 발급해주기는 어렵기 때문에 crontab과 certbot을 이용하여 인증서를 자동 갱신하도록 설정해보겠습니다.

  1. 서버 시간 확인
timedatectl

만약 UTC로 설정되어 있고 한국 기준으로 맞춰주고 싶다면 다음 명령어를 입력합니다.

sudo timedatectl set-timezone Asia/Seoul

스케쥴링을 위해 crontab에 작업을 등록합니다.

  1. crontab 열기
sudo crontab -e 

해당 명령어를 입력하면 아래와 같이 선택할 수 있는 항목이 나옵니다. 사용하기 가장 쉬운 nano 를 사용할 것이기 때문에 1을 입력한 후 Enter 키를 누릅니다.

no crontab for ubuntu - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed

Choose 1-4 [1]:
  1. 명령어 추가

마지막줄에 다음 명령어를 추가하고 저장하면 매월 1일 오전 3시에 인증서가 갱신됩니다.

0 3 1 * * /usr/bin/certbot renew --renew-hook="sudo systemctl restart nginx"
  1. 파일 저장 및 종료

crontab 편집기에서 파일을 저장하고 종료합니다. Ctrl + O를 누른 후 Enter를 눌러 파일을 저장하고, Ctrl + X를 눌러 편집기를 종료합니다.

  1. crontab 작업 확인

다음 명령어를 사용하여 crontab에 작업이 올바르게 추가되었는지 확인합니다

crontab -l

crontab 파일에 추가된 내용이 보이면, 설정이 성공적으로 완료된 것입니다.

웹소켓 연결시 주의사항

웹소켓을 사용하는 경우, 웹소켓 연결을 프록시할 별도의 location 블록을 추가로 설정해야 합니다.

server {
        server_name [도메인];
        location / {
            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;
		        proxy_pass http://127.0.0.1:[포트번호]; 
        }

        location [웹소켓 연결 url] {  # 웹소켓 연결 경로 설정
        proxy_pass http://127.0.0.1:[포트번호];  # 웹소켓 연결할 포트
        proxy_set_header Upgrade $http_upgrade;  # 웹소켓 프로토콜로 업그레이드 요청
        proxy_set_header Connection "upgrade";  # 업그레이드 요청을 명시적으로 표시
        proxy_http_version 1.1;  # HTTP/1.1을 사용하여 웹소켓 연결 유지
    }
}
  • proxy_set_header Upgrade $http_upgrade;: 클라이언트가 HTTP 프로토콜에서 웹소켓 프로토콜로 업그레이드를 요청할 때 사용됩니다. $http_upgrade 변수는 클라이언트 요청의 Upgrade 헤더 값을 사용합니다.

  • proxy_set_header Connection "upgrade": Connection 헤더는 업그레이드 요청을 명시적으로 표시합니다. 웹소켓 프로토콜로의 업그레이드를 처리하는 데 필요합니다.

  • proxy_http_version 1.1: 웹소켓 연결을 위해 HTTP/1.1을 사용하도록 설정합니다. HTTP/1.1은 연결을 유지하기 위한 지속적인 연결 기능을 제공하므로, 웹소켓 통신에 필수적입니다.

최종 금액

Nginx를 사용하여 HTTPS 적용 및 리다이렉트를 설정함으로써 ELB 로드밸런서 사용에 따른 추가 비용을 절감할 수 있습니다. Nginx 자체는 무료이며, EC2 인스턴스와 도메인 비용 외 추가 비용이 발생하지 않습니다. 이를 통해 로드밸런서의 비용 문제를 해결하고, AWS 프리티어 범위 내에서 비용 효율적으로 서비스를 운영할 수 있습니다.

참고

profile
매일매일이 성장하는 하루가 될 수 있도록!

0개의 댓글