본문 바로가기

Back-End/서버

node.js 에서 nginx를 reverse proxy server로 활용하기

환경: aws ec2 ubuntu 20.04 + nginx 1.14.0 + node v8.10.0 + npm 3.5.2

 

node.js 는 크롬의 v8 javascript 엔진에 비동기 이벤트 처리 라이브러리인 libuv를 결합한 런타임 환경입니다.

쉽게 말해서 브라우저에서만 동작하던 javascript 언어를 서버 구축 등 브라우저 밖에서 활용이 가능하도록 지원해주는 하나의 소프트웨어 플랫폼입니다. ( node.js는 컴퓨터 언어나 프레임워크가 아닙니다! )

 

 

그렇다면 reverse proxy server 란 무엇일까요?

reverse proxy server는 proxy server의 한 종류로서, 클라이언트로부터 요청을 받아와 내부망의 서버로 포워드하는 서버를 말합니다. 클라이언트와 서버 간의 중간 매개체 역할을 하는 것이죠. 

reverse proxy server를 이용하면 서버 트래픽 과부하를 방지할 수 있고(load balancing),

ssl 보안적용, 리다이렉션, 방화벽 설정, 도메인 적용 등의 업무를 실서버 대신 수행할 수 있고(web acceleration),

무엇보다 클라이언트에서 실제 서버를 거치지 않기 때문에 보안 측면(security and anonymity)에서도 뛰어납니다. 

 

 

 

 

물론 node.js 를 reverse proxy server 뒤에 숨기지 않고도 바로 서버로 이용할 수 있습니다. 그러나 node.js 를 서버로 이용할 때 발생하는 여러 보안적 이슈 때문에 실제 prod 레벨의 앱 또는 웹을 출시할 때는 reverse proxy server를 거치는 것이 안전하다 할 수 있겠습니다.

 

↓node.js 보안 측면에 대해 더 자세한 내용이 궁금하다 하시는 분은 아래 리포트를 참고해주세요

 

https://medium.com/intrinsic/why-should-i-use-a-reverse-proxy-if-node-js-is-production-ready-5a079408b2ca

 

Why should I use a Reverse Proxy if Node.js is Production-Ready?

There are several reasons why one should not directly expose a Node.js process to the web and should instead hide it behind a reverse proxy.

medium.com

 

 

nginx 설정

 

 우선 nginx, node.js, npm, pm2 가 다 설치되어 있는 환경이라는 전제 하에 진행하겠습니다.

 

nginx 설정 파일에 들어가보도록 합시다.

( default 파일 위치 : /etc/nginx/sites-available/default )

 

 

첫 번째 서버블록 전에 node js 내부 서버망으로 사용할 포트가 포함된 ip 주소를 upstream 블록에 작성합니다.

그 전에 확인하셔야 할 부분이 있습니다.

cd /etc/nginx/nginx.conf 파일 가셔서 http 블록이 이미 있는지 확인합니다.

있으면 저대로 진행하시면 되고, 없는 경우에는 default 파일에서 upstream 블록과 server 블록을 http 블록으로 감싸주셔야 합니다!

upstream 다음에 오는 < nodejs > 이름은 다르게 설정하셔도 상관 없습니다.

저는 127.0.0.1:3000 으로 3000번 포트를 할당할 예정입니다.

max_fails = 0 은 서버 커뮤니케이션 중 에러가 발생했을 때, upstream 안에 작성된 다른 서버로 재연결 시도해볼 횟수입니다.

 

 

 

 

443 포트를 listen하는 첫 번째 서버 블록입니다.

제 경우는 letsencrypt 를 이용해 nginx ssl 설정을 미리 해준 상태입니다. 

해당 ip 주소에 연결된 도메인명이 있을 경우, server_name < domain > 을 위 블러 처리된 부분에 포함해주시면 됩니다.

 

add_header Strict-Transport-Security max-age=500;

해당 브라우저가 https 를 통한 접근만이 가능함을 알리는 헤더입니다. 캐시를 500초 동안 저장하도록 설정했습니다.

 

이제 location 블록 안에 proxy 관련 셋팅을 해줄 차례입니다.

location 다음에 /(슬래시) 는 해당 셋팅을 적용하고 싶은 브라우저의 URI 를 입력하시면 됩니다.

 

proxy_pass http://nodejs;

리다이렉트할 서버 주소입니다. 위 upstream에서 설정한 모듈 이름을 활용하세요. 내부 서버망에서의 주소 호출이기 때문에 https가 아닌 http 입니다!

 

proxy_redirect off;

default, off, redirect replacement 3가지의 value를 가질 수 있습니다.

Location 헤더가 가지는 값을 변경하는 프록시 모듈인데요. default는 proxy_pass가 $host 등의 변수를 값으로 가질 때는 사용할 수 없습니다. off는 혹시나 이전 레벨에서 설정된 proxy_redirect 영향을 삭제시키는 기능을 합니다.

 

proxy_set_header

브라우저 헤더에 저장할 정보들입니다.

 

 

 

 

 

 

80번 포트를 listen하는 두 번째 서버 블록입니다.

저희는 https를 통한 접근만 허용할 것이기 때문에 location 블록에서 redirect 설정 해주시면 됩니다.

 

여기까지 마치면 이제 기본적인 reverse proxy 서버로의 활용을 위한 nginx 환경 구축은 끝났습니다.

 

 

 

nodejs 설정

 

 

/var/www/html 디렉토리 밑에 폴더를 하나 생성 후, 그곳에 node 서버로 구현할 프로젝트의 폴더와 파일을 집어넣으세요.

저는 미리 github에 올려놓은 프로젝트를 clone해 온 상태입니다.

(아직 프로젝트 파일이 없고 테스트 먼저 해보고 싶다면 express default 페이지 같은 거 띄우셔도 됩니다.) 

 

완료하셨으면

netstat -lntp | grep < nodejs 포트번호 >

후에 혹시 이미 해당 포트에서 돌아가는 프로세스가 있는지 확인합니다. 

아직 노드서버를 시작하지 않았기 때문에 있으면 안됩니다!

만약 그대로 진행한다면 pm2 start 이후 listen EADDRINUSE:::3000 에러가 발생할 겁니다.

(pm2 log 파일 default 경로 - /$HOME/.pm2/logs/ )

 

 

 

이미 돌아가는 프로세스를 죽이고 싶다면 해당 프로세스의 pid 번호로 ppid 번호를 찾아 부모 프로세스를 kill 하면 됩니다. 부모 프로세스를 죽이지 않고 자식 프로세스만 중지시키면 다른 pid 번호로 해당 프로세스가 다시 살아나기 때문에

ps -o ppid= < pid 번호 > 로 ppid 를 찾은 후  kill -9 < ppid 번호 > 해주시면 해결됩니다.

 

이제 다시 프로젝트 폴더 경로에서

pm2 start <파일명>

pm2 list

후에 status 가 online으로 되어 있으면 정상 작동한 것입니다.

 

 

 

 

성공!

 

 

 

 

 

reference


 

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect

 

Module ngx_http_proxy_module

Module ngx_http_proxy_module The ngx_http_proxy_module module allows passing requests to another server. Example Configuration location / { proxy_pass http://localhost:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } Directives

nginx.org

stackoverflow.com/questions/59852217/nginx-proxy-pass-or-proxy-redirect

 

NGINX proxy_pass or proxy_redirect

Need help on Nginx proxy_pass. From outside Nginx URL will be hit like this: http://some-IP:8080/v2/platform/general/activity/plan?..... my downstream service looks like this: http://another-IP:...

stackoverflow.com