WebOS Goodies

WebOS の未来を模索する、ゲームプログラマあがりの Web 開発者のブログ。

WebOS Goodies へようこそ! WebOS はインターネットの未来形。あらゆる Web サイトが繋がり、共有し、協力して創り上げる、ひとつの巨大な情報システムです。そこでは、あらゆる情報がネットワーク上に蓄積され、我々はいつでも、どこからでも、多彩なデバイスを使ってそれらにアクセスできます。 WebOS Goodies は、さまざまな情報提供やツール開発を通して、そんな世界の実現に少しでも貢献するべく活動していきます。
Subscribe       

nginx で SSL リバースプロキシを構築

最近あまりネタがないのでが、このままだとまた何週間も投稿なしになりそうなので、以前やった nginx による SSL リバースプロキシの構築方法を備忘録的に書いてみます。開発目的で GAE の dev_appserver.py を SSL 化するために使っただけですが、パッケージシステム等を使わずにソースからビルドし、一般ユーザー権限でインストールする方法にしています。ごく基本的な内容ですが、参考にしていただければ幸いです。

nginx とは

nginx は Tornado などと同様の非同期イベントドリブンモデルを採用した HTTP サーバーです。 BSD に似たライセンスのオープンソースソフトウェアとして公開されています。プロセス・スレッドモデルを採用した Apache などよりも多数のコネクションを効率よく処理できるため、多くの高負荷サイトで採用されています。現在 Apache, IIS に次いで世界で三番目に多く使われている Web サーバーだそうです。

その高速性を生かして高速なリバースプロキシやロードバランサとして使えるほか、 FastCGI のサポートや gzip, XSLT, 画像リサイズ等のフィルタ、IMAP/POP3 プロキシなど、数多くの機能が実装されています。

また、これだけ高機能なわりには設定もシンプルで、今回のような用途にも簡単に使えるのも嬉しいところですね。

インストール

今回もシステムレベルへのインストールはせず、独立した適当なディレクトリ(ここでは ~/nginx と仮定します)にインストールします。 nginx が依存するライブラリは zlib, PCRE, OpenSSL の 3 つ。 Mac OS X Lion の場合 zlib と OpenSSL は入っていますが、 PCRE ライブラリはないので、そちらも ~/nginx 以下にビルド & インストールします。

PCRE のインストール

まずは依存ライブラリである PCRE のインストールです。こちらも configure の --prefix オプションでルートを~/nginx に指定しています。

cd ~/nginx
curl -O ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.30.tar.gz
tar zxvf pcre-8.30.tar.gz
cd pcre-8.30
./configure --prefix=/Users/ユーザー名/nginx
make && make install

nginx のインストール

次は nginx のインストールです。 PCRE と同様に ~/nginx をルートに指定し、さらに --with-pcre オプションで PCRE のソースパッケージの場所を指定します。今回は SSL リバースプロキシの構築が目的なので、 http_ssl モジュールも有効にしています。

cd ~/nginx
curl -O http://nginx.org/download/nginx-1.2.0.tar.gz
tar zxvf nginx-1.2.0.tar.gz
cd nginx-1.2.0
./configure --prefix=/Users/ユーザー名/nginx \
    --with-pcre=/Users/ユーザー名/nginx/pcre-8.30 \
    --with-http_ssl_module
make && make install

以上でインストールは終了です。

SSL リバースプロキシの設定

~/nginx/conf/nginx.conf に設定ファイルのテンプレートが作成されるので、それをもとに SSL リバースプロキシとして動作するように設定していきましょう。

nginx の設定ファイルの構造

設定ファイルを変更する前に、その概要を理解しておきましょう。一般的に nginx.conf は以下のような構造になっています。

# コアモジュールの設定

events {
    # Eventsモジュールの設定
}

http {

    # すべてのドメインに共通の設定

    server {
        listen 80;
        server_name www.example.com;

        # www.example.com全体の設定

        location / {
            # / 以下の URL の設定
        }

        location /foo {
            # /foo 以下の URL の設定
        }
    }

    server {
        listen 80;
        server_name www2.example.com;
        # www2.example.comの設定
    }
}

nginx.conf はブロック(ブロック名 { 〜 } という構造)によって階層化されており、下位のブロックは上位のブロックの設定を継承・上書きします。ブロックの外側には nginx 全体で共通の設定(主に CoreModule のもの)、 events ブロックにはローレベルの通信処理を担う EventsModule の設定、 http ブロックには HTTP サーバーに関わる HttpCoreModule, HttpIndexModule など多くのモジュールの設定を記述します。上記の例では省略していますが、 IMAP/POP3 プロキシを設定する mail ブロックもあります。

http ブロックはさらに http, server, location というブロックに階層化されています。 http ブロックの直下にはすべてのドメインで共通の設定を記述し、さらにドメイン(バージャルホスト)ごとに server ブロックを作ります。同様に、各 server ブロックの直下にはそのドメインで共通の設定を記述し、パスごとの設定は location ブロックを作る、というようになっています。

注意すべきは、それぞれの location ブロックは独立しており、上位のパスが指定された location ブロックの設定を引き継がないという点です。上記の例で言えば、 /foo 以下のパスに適用されるのは location /foo ブロックの設定のみで、 location / ブロックの設定は適用されません。このあたりは Apache と違うところです。

以上をふまえて、 SSL リバースプロキシの設定を記述します。各設定項目の解説は省きますので、 リファレンス を参照してください。

非 SSL HTTP サーバーの設定

今回の目的は SSL リバースプロキシですが、念のため SSL なしのリバースプロキシも設定しておきましょう。 localhost:80 の設定がすでに存在するはずなので、その location / ブロックを以下の内容に書き換えます。

location / {
    proxy_pass http://localhost:8080/;
    proxy_redirect default;
}

基本的にはこれだけでリバースプロキシとして動作します。ただ、 X-Forwarded-For などのヘッダが設定されないので、後ほど http ブロックに設定を追加します。

SSL HTTP サーバーの設定

コメントアウトされてはいますが、 SSL の設定もすでに含まれているので、そのコメントを外して、 location / ブロックの内容を非 SSL と同じ内容に変更しておきます。そして、 ssl_certificate と ssl_certificate_key にそれぞれ証明書と秘密鍵のファイルを指定すれば OK です。

ssl_certificate      /path/to/ssl.crt
ssl_certificate_key  /path/to/ssl.key

これで SSL のリバースプロキシも動作するようになります。

リバースプロキシの設定

すでに一応リバースプロキシとして動作するようになっていますが、一般的なリバースプロキシが追加する X-Forwarded-For などの HTTP ヘッダが出力されません。その設定を行うため、 http ブロックの直下に以下の項目を追加します。

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

これで、適切な HTTP ヘッダが出力されるようになります。

設定ファイル

参考までに、今回使った設定ファイルを掲載しておきます。テンプレートにあったコメントなどは削除してありますので、ご了承ください。

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include           mime.types;
    default_type      application/octet-stream;
    sendfile          on;
    keepalive_timeout 65;

    server {
        listen       80;
        server_name  localhost;

        location / {
            proxy_pass http://localhost:8080/;
            proxy_redirect default;
        }


        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

    server {
        listen       443;
        server_name  localhost;

        ssl                  on;
        ssl_certificate      /Users/ito/lib/ssl/ssl.crt;
        ssl_certificate_key  /Users/ito/lib/ssl/ssl.key;

        ssl_session_timeout  5m;

        ssl_protocols  SSLv2 SSLv3 TLSv1;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers   on;

        location / {
            proxy_pass http://localhost:8080/;
            proxy_redirect default;
        }
    }

    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

nginx の起動

nginx の実行ファイルは ~/nginx/sbin/nginx としてインストールされているはずなので、これを単に実行すれば nginx が起動します。ただし、今回は 80, 443 番ポートを使うので、 sudo で実行する必要があります。

sudo ~/nginx/sbin/nginx

これでリバースプロキシが動作し、 http://localhost/ と https://localhost/ が http://localhost:8080/ に転送されるようになりました。 Web ブラウザで表示して、確認してみてください。

nginx の終了は、 -s オプションでできます。

sudo ~/nginx/sbin/nginx -s stop

だいぶ手抜きではありますが、以上で nginx による SSL リバースプロキシが構築できました。 nginx は軽量でモダンな機能を多数搭載しているので、なかなか使いでがありそうです。 Tornado との相性もよさそうなので、今後も活用していきたいと思っています。

関連記事

この記事にコメントする

Recommendations
Books
「Closure Library」の入門書です。
詳しくはこちらの記事をどうぞ!
Categories
Recent Articles