들어가기 전에

리버스 프록시 서버란 무엇인가?

내부 어플리케이션과 외부 클라이언트 사이에 자리잡아서 클라이언트의 요청을 적절한 서버로 보내주는 역할을 하는 것입니다. 노드js나 tomcat같은 많은 일반적인 어플리케이션들은 스스로 서버와 같은 역할을 할 수 있긴합니다. 근데 NGINX는 많은 어플리케이션들이 자체적으로 가지지 못한 로드 밸런싱, 보안, 가속화 기능 등 많은 진보된 기능을 갖고 있습니다.

이 가이드에서는 간단한 노드js 앱을 어떻게 NGINX 프록시 서버로 설정(configure)하는지에 대해 보여줄 것입니다.

NGINX 설치하기

이 과정들은 NGINX Inc의 공식 레퍼지토리에서 NGINX Mainline을 우분투에 설치하는 과정입니다. NGINX 어드민 가이드. production 환경을 위한 NGINX 설정에 대한 정보는 여기에서 볼 수 있습니다.

  1. 텍스트 에디터에서 /etc/apt/source.list를 여시고 deb http://nginx.org/packages/mainline/ubuntu/ CODENAME nginx 을 맨 밑에 추가하세요. 이 예제에서 CODENAME을 우분투 릴리즈 코드네임으로 바꾸세요. 예를 들면 우분투 18.04라면 Bionic Beaver라는 이름이 있습니다. 그럼 아래 CODENAMEbionic으로 바꾸세요.

  2. 저장소의 패키지 signing key를 삽입(import)한 뒤에 apt에 추가해주세요.

sudo wget http://nginx.org/keys/nginx_signing.key
sudo apt-key add nginx_signing.key
  1. NGINX를 설치해주세요.
sudo apt update
sudo apt install nginx
  1. NGINX가 가동 중인 것을 확인하고 재시작 시 자동으로 시작 가능하게 만들어주세요.
sudo systemctl start nginx
sudo systemctl enable nginx

노드 js 설치하기

  • 이 부분은 영어 원문과 다르게 가겠습니다. 번역 원문에서는 노드 9.x버전을 설치하기 위해 쉘 파일을 깔고 실행하는데 사실 최신버전으로 해도 상관이 없습니다. 원문이 궁금하신 분들은 여기를 클릭하여 확인해보세요.

  • 원문의 스크립트 실행은 생략하고 노드 js를 그냥 바로 설치해주세요

    sudo apt install nodejs npm

노드 app 설정(configure)하기

  1. 디렉토리를 만들고 example app을 만들어주세요.
make nodeapp && cd nodeapp
  1. 디렉토리 내에서 nodejs 앱을 초기화주세요.
npm init
  1. express js를 설치해주세요.
npm install --save express
  1. app.js파일의 내용을 다음과 같이 바꿔주세요.
// app.js
const express = require('express');
const app = express();

app.get('/', (req, res) => res.send('Hello World!'));
app.listen(3000, () => console.log('Node.js app listening'));
  1. 앱을 실행해주세요
node app.js
  1. 별개의 터미널에서 앱이 제대로 작동하는지 확인하기 위해 curl명령어를 날려봅시다.
    curl localhost:3000

아마 Hello World!라는 화면을 보실 수 있을 겁니다.

NGINX 설정(Congirue)하기

여기에서부터, Node js가 인터넷에 공개될 공인 IP주소에서 접근할 수 있도록 설정할 것입니다. 이 섹션은 NGINX가 공인 IP주소로부터 오는 모든 요청들을 이미 listening하고 있는 서버 localhost에 보내는 설정을 할 것입니다.

NGINX 리버스 프록시 기본 설정

  1. /etc/nginx/conf.d/ 내부 디렉토리에 앱을 위한 설정파일을 만들어주세요. 밑의 내용에서 example.com을 앱의 도메인이나 공인 IP주소로 바꾸어주세요.
# etc/nginx/conf.d/nodeapp.conf
server {
    listen 80;
    listen [::]:80;

    server_name example.com;

    location / {
        proxy_pass http://localhost:3000/;
    }
}

proxy_pass가 지시하는 것이 reverse proxy를 위한 설정입니다. location 블록(여기서는 root / 경로)에 매칭되는 모든 요청을 nodejs앱이 돌아가는 localhost3000번 포트로 넘기는 것입니다.

  1. NGINX의 Welcome 페이지 삭제하기
sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.disabled
  1. 설정 테스트하기
sudo nginx -t
  1. 만일 아무런 에러도 보고되지 않았다면, 새 설정을 로드해주세요.
sudo nginx -s reload
  1. 브라우저에서 아까 서버의 공인아이피로 접속해보세요. "Hello World!" 메시지가 보일 것입니다.

고급 옵션

간단한 앱의 경우, proxy_pass 옵션 정도면 충분합니다. 하지만 더 복잡한 앱은 추가적인 옵션이 필요할 것입니다. 예를 들면, Node.js는 실시간으로 많은 상호작용 요구가 들어올 것입니다. 이것을 감당하기 위해 NGINX의 버퍼링 feature를 비활성화 시켜봅시다.

# /etc/nginx/conf.d/nodeapp.conf
location / {
    proxy_pass http://localhost:3000/;
    proxy_buffering off;
}

프록시화된 요청을 보내기 위해 proxy_set_header 옵션을 이용할 수도 있습니다.

# /etc/nginx/conf.d/nodeapp.conf
location / {
    proxy_pass http://localhost:3000/;
    proxy_set_header X-Real-IP $remote_addr;
}

이 설정은 기존 클라이언트의 IP주소를 프록시 호스트로 보내기 위해 빌트인 변수 $remote_addr을 사용합니다.

Certbot을 이용한 HTTPS 설정하기

리버스 프록시의 장점 하나는 TLS 인증서를 이용한 HTTP 설정이 용이하다는 데에 있습니다. Certbot은 우리가 Let's Encrypt로 부터 빠르게 무료 인증서를 얻을 수 있게 도와주는 봇입니다. 이 가이드에서는 우분투 16.04 버전에 Certbot을 이용할 것입니다. 하지만 공식 사이트에서 모든 배포판에 대한 이해하기 쉬운 설치 방법과 사용 용례를 제공하고 있으니 참고하세요.

Certbot을 통한 인증서 획득 방법을 따라주세요. Certbot은 새 인증서를 사용하기 위해 자동으로 NGINX 설정 파일을 업데이트 할 것입니다.

  1. Certbot을 설치하고 웹 서버 관련(web server-specific) 패키지들을 설치하고 Certbot을 실행해주세요.
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx
sudo certbot --nginx
  1. Certbot이 사이트에 대한 정보를 요청할 것입니다. 응답은 인증서의 일부로 저장될 것입니다.
# sudo certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx

Which names would you like to activate HTTPS for?
-------------------------------------------------------------------------------
1: example.com
2: www.example.com
-------------------------------------------------------------------------------
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):
  1. Certbot은 HTTP 트래픽을 자동으로 HTTPS 트래픽으로 바꾸고 싶은지에 대해서도 물어볼 것입니다. 이 옵션은 선택하길 권장합니다.

  2. 툴이 완료됐을 때, /etc/letsencrypt/live/$domain 디렉토리 내부에 있는 발행된 인증서와 생성된 키들을 저장할 것입니다. ($domain은 Certbot 인증서 생성 과정에서 입력한 도메인입니다.)

알아둬야 할 것 Certbot은 우리의 웹서버 설정이 기본 인증서 디렉토리를 가리키거나 심볼릭(symlink) 링크를 만들기를 권장합니다. 키나 인증서는 다른 디렉토리로 이동할 수 없습니다.

  • 마지막으로, Certbot은 우리의 웹서버가 새로운 인증서를 사용할 수 있도록 우리의 웹서버 설정을 바꿀 것입니다. 그리고 우리가 옵션에서 선택했던대로 HTTP 트래픽을 HTTPS로 바꿀 것입니다.
  1. 만일 방화벽 설정이 있다면, HTTPS 서비스로 가는 incoming, outcoming 연결을 허락하는 방화벽 규칙을 추가할 수 있습니다. 우분투에서는 UFW가 일반적으로 방화벽 규칙을 관리하기 위한 간단한 도구로 쓰입니다. UFW를 설치하고 HTTP와 HTTPS 트래픽을 설정해봅시다.
sudo apt install ufw
sudo systemctl start ufw && sudo systemctl enable ufw
sudo ufw allow http
sudo ufw allow https
sudo ufw enable

다음 단계

일반적인 NGINX 설정에 대해 더 알고 싶으시다면, 여기를 방문해보세요. 리버스 프록시 어플리케이션에 사용되는 NGINX의 실용적인 예제에 대해서는 알스튜디오 서버, Thingsboard 가이드를 참조하세요.

더 많은 정보를 위해서

NGINX 리버스 프록시 공식 문서