Node.js (Express Framework) 앞단에 Nginx 사용하기

InspiredJW 2012.03.17 15:31
본글 출처 : 
http://inspiredjw.com/entry/Nodejs-Express-Framework-앞단에-Nginx-사용하기 [Inspired World]

Node.js의 창시자인 Ryan Dahl에 의하면


 "You just may be hacked when some yet-unknown buffer overflow is discovered. Not that that couldn't happen behind nginx, but somehow having a proxy in front makes me happy". 

"아직 발견되지 않은 버퍼 오버플로우 취약점에 의해서 해킹 당할 수 있습니다. 
Nginx를 앞단에 둠으로써 이런 취약점에 의해서 해킹을 완전히 막아주지는 않지만, 저는 Nginx을 Proxy서버로써 앞단에 두는 것이 좋다고 생각합니다."






좀 의역을 한 부분이 없잖아 있지만, 중요한 포인트는 Nginx를 앞단에 둠으로써 Express가 사용하는 실제 포트를 숨기고 Nginx의 80포트를 통해 Reverse Proxying 을 함으로써 저런 보안 이슈를 방지할수도 있고 Nginx의 우수한 기능 활용할 수 있습니다.

실제 Static File 과 같은 경우에는 Node.js 보다는 Nginx가 훨씬 성능이 뛰어나다고 합니다.




유의 하실 점은 Nginx 1.0.x버전은 HTTP 1.1을 아예 지원하지 않고 (TCP Module 사용 예외)

Nginx 1.1.x버전은 HTTP 1.1을 지원하지만 Websocket은 지원하지 않기 때문에 Socket.IO와 같은 모듈을 사용할 때 Websocket 방식으로 연결을 시도할 경우에는 Nginx를 거쳐서 연결을 시도하지 않고 직접 연결을 하거나 TCP Module을 사용해야 합니다.



그럼 Nginx 를 Reverse Proxy로 설정하는 방법을 알아볼까요?

Ubuntu 11.04 Natty에서 패키지 인스톨로러를 통해 Nginx를 설치한 경우로 설명하겠습니다.

 

1. ngnix 설치

참고로 Ubuntu에서 nginx 설치는 


sudo apt-get update
sudo apt-get install nginx

하시면 됩니다.



2. nginx 설정 파일 작성

먼저 , nginx 설정파일을 만들어 주어야 합니다. nginx설정파일을 아래의 디렉토리에 만들어주도록 합니다. [example]은 설정파일의 이름으로 확장자는 따로 적어주지 않습니다.






sudo nano /etc/nginx/sites-available/[example]

이렇게 사용하고 싶은 이름 (일반적으로 도메인 이름, 여기선 example) Nginx 설정 파일을 열고


server {
    listen 80;
    server_name example.com; #nginx와 도메인 주소를 연결해 주는 역할을 합니다. 외부에서 example.com으로 들어오는 도메인 주소에서 
요청이 들어오면 로컬에서 오픈되어 있는 아래의 " proxy_pass http://127.0.0.1:3000/; " 를 포워딩해줍니다.

    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_set_header X-NginX-Proxy true;

      proxy_pass http://127.0.0.1:3000/; # server_name example.com;로 들어온 요청을 nginx가 받아, 로컬에서 오픈되어 있는
"proxy_pass http://127.0.0.1:3000/;"를 포워딩해줍니다.
      proxy_redirect off;
    }

    gzip on;
    gzip_comp_level 2;
    gzip_proxied any;
    gzip_min_length  1000;
    gzip_disable     "MSIE [1-6]\."
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
 }

이렇게 입력 해주고 CTRL + X 를 눌러 빠져나오고 Y를 눌러 파일을 저장합니다.




다음에는 /etc/nginx/sites-available에 만든 nginx설정 파일을 /etc/nginx/sites-enabled/ 직하로 옮겨주는 작업을 합니다.


cd /etc/nginx/sites-enabled/ 
ln -s /etc/nginx/sites-available/example example

이렇게 해주게 되면 방금 만든 Nginx 설정파일이 적용됩니다. 설정을 변경한 이후에는 Nginx를 반드시 재시작 해줘야 변경한 것이 적용이 되므로


sudo /etc/init.d/nginx restart
혹은sudo service nginx reload

를 쉘에서 실행하여 재시작을 합니다.




혹시 아직 만든 Node.js 앱이 없다면

테스트용으로


var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(3000, "127.0.0.1");
console.log('Server running at http://127.0.0.1:3000/');

//express 모듈을 사용하고 있다면, app.listen(3000,'127.0.0.1', function(){ });


위와 같이 입력하고 이름을 app.js로 저장합니다.

쉘에서 

node app.js


이렇게 테스트 앱을 실행해주면



http://localhost:3000으로는 직접 연결해서 Hello World 를 볼 수도 있고

nginx설정 파일에서 적어준 server_name example.com;
http://example.com로도 같은 Hello World를 볼 수 있습니다.


실제 Production 에서는 방화벽에서 3000포트를 허용하지 않고 80포트만 Inbound 해주면 Nginx 를 통해서만 앱에 접근할 수 있게 됩니다.




+ Recent posts