Node.jsでつくるリバースプロキシ

Node.js勉強会@関西 第0回

Node.jsでつくるリバースプロキシ

自己紹介

Node.jsでつくるリバースプロキシ

Node.jsでリバースプロキシを立てた経緯と設定などを紹介したいと思います。

そもそも、リバースプロキシって?

リバースプロキシ

リバースプロキシ(英: Reverse proxy)または逆プロキシは、特定のサーバへの要求を必ず経由するように設置されたプロキシサーバ。一般的なプロキシとは異なり不特定多数のサーバを対象としない。リバースプロキシは、不特定多数のクライアントから寄せられる要求に対して、応答を肩代わりすることにより特定のサーバの負担を軽減したり、アクセスを制限することにより特定のサーバのセキュリティを高めたりする目的に用いられる。

ウィキペディア(Wikipedia)

とある開発サーバの現状

いろんな言語のアプリケーションサーバが・・・

とある開発サーバの現状

ポート番号入力するとか・・・無いですよね

URLを一元化

セキュリティー的に見ても色々よろしくないのでURL(ポート)を一元化する

いろんな言語のアプリケーションサーバがアクセスしやすくなる!

とある開発サーバの改善

でも???なんでNode.jsなの?

リバースプロキシ、Apacheとかじゃだめ???

Node.jsでリバースプロキシを提供するモジュールの機能を見てみましょう。

node-http-proxy (http-proxy)

主な機能(公式から抜粋)

WebSocektが扱える。そこが大きなポイントでした。

WebSocketも通せるプロキシサーバが欲しい!

node.jsでWebSocketが使えるリバースプロキシとして動作させる

node-http-proxy インストール

インストール npm (node package manager)を利用

$ curl http://npmjs.org/install.sh | sh
$ npm install http-proxy -g

node-http-proxy ポートフォワーディング

8000番 → 9000番 ポートフォワード

var http = require('http'),
httpProxy = require('http-proxy');
//
// Create your proxy server
//
httpProxy.createServer(9000, 'localhost').listen(8000);

//
// Create your target server
//
http.createServer(function (req, res) {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.write('request successfully proxied!' + '\n' + JSON.stringify(req.headers, true, 2));
  res.end();
}).listen(9000);

node-http-proxy ポートフォワーディング

var options = {
  hostnameOnly: true,
  router: {
    'foo.com': '127.0.0.1:8001',
    'bar.com': '127.0.0.1:8002'
  }
}

var proxyServer = httpProxy.createServer(options);
proxyServer.listen(80);

プロキシサーバ実装

$ node server.js

server.js

var http = require('http'),
    httpProxy = require('http-proxy')
    opts = require('opts');

//opts nodeコマンド 引数定義
opts.parse([
  {
    'short': 'p',  
    'long': 'port',
    'description': 'HTTP port',
    'value': true,
    'required': false
  }
]);

//
// port
//
var port = opts.get("port") || 80;

var httpPort = 8000;
var socketPort = 18080;

//
// インスタンス生成
//
var proxy = new httpProxy.HttpProxy({
    target: {
      host: 'localhost',
      port: httpPort
    }});
var webSocketProxy = new httpProxy.HttpProxy({
    target: {
      host: 'localhost',
      port: socketPort
    }});

//
// HTTPリクエスト処理
//
var server = http.createServer(function ( req, res ) {
  proxy.proxyRequest( req, res );
});

//
// WebSocketリクエスト処理
//
server.on( 'upgrade', function( req, socket, head ) {
  webSocketProxy.proxyWebSocketRequest( req, socket, head );
});

server.listen(port);

foreverを使ったnodejsのデーモン化

プロキシサーバとしてデーモン化させる

インストール

$ curl http://npmjs.org/install.sh | sh

$ npm install forever -g

実行

プロセスがnode.jsをサーバとして永続化(forever)させる

$ forever start server.js
info:   Running action: start
info:   Forever processing file: server.js 

nodeコマンドで実行する場合は -c オブションをつける

$ forever start -c node server.js

後は起動時にシェルスクリプトで実行するようにすればOK

まとめ

参考

nodejitsu ( http-proxy / forever )
http://nodejitsu.com/
https://github.com/nodejitsu
http-proxy ( node-http-proxy ) [npm]
https://github.com/nodejitsu/node-http-proxy
forever [npm]
https://github.com/nodejitsu/forever
opts [npm]
http://joey.mazzarelli.com/2010/04/09/javascript-command-line-options-for-node-js/
https://bitbucket.org/mazzarelli/js-opts/wiki/Home

ご清聴ありがとうございました

〜 お疲れ様でした 〜

Special thanks! mukiSlide is made by Yusuke Nakanishi (@hogenishi)