이 글은 우아한테크코스 백엔드 6기 냥인, 명오에 의해 작성되었습니다.


사전 준비 사항

Nginx 서버 구축(EC2 인스턴스 생성)

먼저 Nginx 서버를 띄울 EC2 인스턴스를 생성합니다. 이 서버는 운영 서버와 마찬가지로 Public Subnet에 위치시킵니다.

  1. EC2 인스턴스에 Nginx 설치

    sudo apt install nginx

  2. Nginx 설치 확인

    Nginx의 버전 체크를 통해 설치가 잘 되었는지 확인합니다.

    sudo nginx -v

  3. Nginx 실행

    sudo service nginx start

    Nginx를 실행한 후 웹 브라우저에서 EC2 인스턴스의 Public IP로 접근하면 아래와 같은 화면을 확인할 수 있습니다.

Domain Name 준비

이제 Nginx 서버에 연결할 도메인을 준비해야 합니다.

팀 크루루는 hosting.kr에서 미리 도메인을 구입해 두었습니다.

아래와 같이 A 레코드를 추가하여, ‘prod’라는 A tag를 가진 도메인을 Nginx 서버의 Public IP에 연결합니다.

추가로 whatsmydns.net에서 DNS의 Propagation을 확인할 수 있습니다. DNS 서버에 새롭게 등록한 도메인이 전파가 되어야 다른 영역 혹은 지역에서도 인증된 접속이 가능합니다.


HTTPS 적용

HTTPS를 적용하기 위해 SSL 인증서를 발급받아야 합니다.

Certbot 설치

Certbot은 Let’s Encrypt를 통해 SSL 인증서를 자동으로 발급하고 관리하는 오픈 소스 소프트웨어입니다.

Nginx가 구동되고 있는 인스턴스 콘솔에 접속하여 아래 명령어를 순차적으로 실행하면 됩니다.

sudo apt update

sudo add-apt-repository ppa:certbot/certbot

sudo apt install python3-certbot-nginx

SSL 인증서 발급

sudo certbot —nginx -d {도메인 네임}

위 명령어를 실행하면 아래와 같이 도메인에 대한 SSL 인증서를 발급 받을 수 있습니다.

리다이렉트 설정

인증서를 발급받았으니, 요청을 https를 통해 발급받은 인증서와 키를 이용하여 인증된 통신을 할 수 있도록 합니다. 이 구성을 위해 nginx의 설정 파일에 적용합니다.

sites-available/default 파일에 아래 서버 블록들을 작성합니다.

  server {
    listen 80;
    server_name {domain_name};
    
    if ($host = {domain_name}) {
        return 301 https://$host$request_uri;
    }

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

server {
    listen 443 ssl;
    server_name {domain_name};

    ssl_certificate {route};
    ssl_certificate_key {route};
    include {security};
    ssl_dhparam {parameter};

    location / {
        proxy_pass http://{prod_server_ip}:{port};
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
  

이 설정은 크루루의 prod 도메인에 대한 HTTP 요청을 HTTPS로 리다이렉션하고, HTTPS 요청을 API 서버가 구동되고 있는 EC2 인스턴스로 리버스 프록싱하는 구성을 가지고 있습니다.

현재 코드는 두 개의 서버 컨텍스트로 이루어져 있는데, 각 서버 컨텍스트에 대해 설명드리겠습니다.

  • 첫 번째 서버 컨텍스트에서는 80 포트에서 오는 요청을 수신합니다. 이 서버 컨텍스트는 domain_name 도메인에 대한 요청을 처리합니다. 요청 도메인 이름이 domain_name과 같으면, HTTPS URL로 리다이렉션합니다. $host는 요청 도메인 이름을, $request_uri는 URI 경로와 쿼리 스트링을 포함합니다.
  • 다음 서버 컨텍스트는 443 포트에서 들어오는 요청을 SSL을 사용하여 수신합니다. 이 서버 컨텍스트 역시 domain_name 도메인에 대한 요청을 처리합니다. 아래의 SSL 관련 4줄 코드는 Certbot에서 HTTPS 인증을 위해 자동으로 생성되는 코드입니다. SSL 인증서, 키 파일의 경로를 지정하고, 보안 설정을 적용하는 역할을 합니다. location 컨텍스트에서는 모든 경로에 대한 요청에 헤더를 설정하고 운영 서버로 전달하는 역할을 합니다. 원본 요청의 Host 헤더, 클라이언트의 IP 주소, 프로토콜 등이 헤더에 포함됩니다.

리버스 프록시 적용 확인

리버스 프록시가 적용되었는지 확인하기 위해 프로덕션 서버로 요청을 보내볼 수 있습니다.

telnet을 사용한 포트 확인

nginx 서버에서 리눅스 명령어를 사용하여 특정 IP 주소의 특정 포트로 ping을 보내고 응답을 확인할 수 있습니다.

telnet {host_name_or_ip} {port}

Curl을 이용한 http 요청

nginx 서버에서 http 요청을 보내, 그 요청이 올바르게 전송되는지 확인할 수 있습니다.

curl http://{ip}:{port}