Raspberry Piにリバースプロキシを導入する

Raspberry PiにNode.jsを入れて動かしていましたが、Raspberry Piにリバースプロキシを導入して、サブドメイン名でApacheとNode.jsの切り替えをしてみます。リバースプロキシにはWebSocketを透過するnode-http-proxyを導入します。できるだけ手順をそのまま書いたつもりですが、何か不必要な部分があったり、間違ってる箇所があるかもしれません。ネットワーク周りは勉強中なので備忘録代わりに書き残しています。(そもそもリバースプロキシ自体初めて知った...)

f:id:tomo_watanabe:20130127203110p:plain

Apachをインストールして、デフォルト80でリッスンするのを8080でリッスンするように変更します。リバースプロキシは80をリッスンして、サブドメイン名によってApacheの8080とNode.jsが動いている3000へ振り分けるようにします。

Apacheのインストール

$ sudo apt-get install apache2

きちんと動作しているか、Rasberry Piにアクセスして確認します(ここでは192.168.0.7になっています)

f:id:tomo_watanabe:20130127200517p:plain

Raspberry Piのデフォルトのランレベル

$ less /etc/inittab

で見てみると

# The default runlevel.
id:2:initdefault:

Apacheをインストールすると自動起動になるようなので確認します。

$ ls /etc/rc2.d/
K01lightdm     README       S01motd     S01triggerhappy  S03dbus            S03pulseaudio  S05plymouth
K05nfs-common  S01bootlogs  S01rsyslog  S02apache2       S03dphys-swapfile  S03rsync       S05rc.local
K05rpcbind     S01ifplugd   S01sudo     S03cron          S03ntp             S03ssh         S05rmnologin

"S02apache2"というのがあるので、起動時にapacheが自動起動します。自動起動させたくない場合は

$ sudo update-rc.d apache2 remove

とします。自動起動に再設定するには

$ sudo update-rc.d apache2 defaults

Apacheのリッスンポートを8080に変更

デフォルトでApacheは80をリッスンするので、これを8080に変更します。viやemacsのエディタでルートユーザ権限で編集します。

$ sudo emacs /etc/apache2/apache2.conf

// 以下を追記
<VirtualHost *:8080>
 DocumentRoot /var/www/
 ServerName web.raspberry.pi
</VirtualHost>

$ sudo emacs /etc/apache2/ports.conf

// 以下を修正
NameVirtualHost *:8080  <-- 80から8080
Listen 8080 <-- 80から8080

修正したら、Apacheを再起動して8080で接続できるか確認します。

$ sudo service apache2 restart

// 80ではエラー
$curl http://localhost:80
curl: (7) couldn't connect to host

// 8080で接続OK
$ curl http://localhost:8080
<html><body><h1>It works!</h1>
<p>This is the default web page for this server.</p>
<p>The web server software is running but no content has been added, yet.</p>
</body></html>

f:id:tomo_watanabe:20130127200601p:plain

これでApacheは8080で接続できるようになりました。

リバースプロキシのインストール

今回はWebSocketに対応したリバースプロキシを導入したいので、node-http-proxyをインストールします。グローバルでインストールします。参考サイト

$ npm install -g http-proxy

どこかに作業用ディレクトリを作成して、グローバルインストールしたモジュールのリンクを作成します

$ mkdir reverse_proxy
$ cd reverse_proxy
$ npm link http-proxy
/home/pi/work/reverse_proxy/node_modules/http-proxy -> /home/pi/.nvm/v0.8.16/lib/node_modules/http-proxy

proxy.jsを作成します。

/**
 * node-http-proxy
 */

var port = 80;
var httpProxy = require('http-proxy');

var options = {
    hostnameOnly: true,
    router: {
        'web.raspberry.pi': '127.0.0.1:8080',
        'node.raspberry.pi':'127.0.0.1:3000'
    }
};

var proxyServer = httpProxy.createServer(options);
proxyServer.listen(port);
console.log('It Works!');

これで、

  • web.raspberry.pi → Apache
  • node.raspberry.pi → Node.js

へ振り分けできるようになるはずです。

hostsファイルの追記

今回はローカルネットワークで動作させるので、クライアントのブラウザの設定とhostsファイルの書き換えが必要になります。

hostsファイルにはRaspberryPiのIPアドレスと設定したいサブドメインとセットで追記します。ブラウザの設定にも下記のアドレスの場合はプロキシ設定を行わない等の設定が必要になります

# hostsファイルに下記のようにRaspberryPiのIPを追加
192.168.0.7 web.raspberry.pi
192.168.0.7 node.raspberry.pi

リバースプロキシの起動

80ポートをリッスンするにはスーパユーザじゃないとできないので、

$ sudo node proxy.js
sudo: node: command not found

nodeコマンドが無いと怒られてしまいます。仕方ないのでちょっと強引に起動させますw

$ sudo su
# source /home/pi/.nvm/nvm.sh
# nvm use v0.8.16
Now using node v0.8.16
# node proxy.js 

この状態でクライアントブラウザから"web.raspberry.pi"へアクセスしてみて"It Works"と出れば、無事リバースプロキシとして動作しています。

Apache(8080)へアクセス

f:id:tomo_watanabe:20130127200822p:plain

では以前に動かしたNode.jsのプログラムをポート3000で動作させて、最終的にリバースプロキシとしての動作を確認します。

Node.js(3000)へアクセス

f:id:tomo_watanabe:20130127200829p:plain

まとめ

Raspberry Piでリバースプロキシを動かしてみました。Apache上ではPukiWikiを動かしたり、Node.js側で動作するプログラムの設定を変更したりということができるかもしれません。ルーターとかでは、設定を特定のアドレスで行ったりしていますが、あんな感じでしょうか。Linuxの組込み機器系ではよくありそうな構成なのかもしれません(組込みLinuxの開発経験ナシ)今回のWebSocketを透過するリバースプロキシは、リアルタイムWebデバイスとしての実装には有効な気がします。