Ubuntu10.04でdpkgを使って、Nginxにモジュールを追加する

前回の記事で、Nginxにサードパーティモジュールを追加してコンパイルしてインストールする手順を書きましたが、Ubuntu(Debian)の作法に乗っ取ってdpkgを使うと、もっと簡単にモジュール追加ができるのでその手順もメモしておきます。

dpkg-devのインストール、Nginxのコンパイルに必要なライブラリのインストール、Nginxのソースの取得まで

$ sudo apt-get install dpkg-dev
$ sudo apt-get update
$ sudo apt-get build-dep nginx
$ apt-get source nginx
$ cd nginx-0.7.65

追加するモジュールは、AWS Authを追加したいのでgitをコマンドを入れて、モジュールのソースコードを取得

$ sudo apt-get install git-core
$ git clone https://github.com/anomalizer/ngx_aws_auth.git

モジュールをconfigureに指定

$ vi debian/rules 
..
    ./configure --conf-path=/etc/nginx/nginx.conf \
        --error-log-path=/var/log/nginx/error.log \
        --pid-path=/var/run/nginx.pid \
        --lock-path=/var/lock/nginx.lock \
        --http-log-path=/var/log/nginx/access.log \
        --http-client-body-temp-path=/var/lib/nginx/body \
        --http-proxy-temp-path=/var/lib/nginx/proxy \
        --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
        --with-debug \
        --with-http_stub_status_module \
        --with-http_flv_module \
        --with-http_ssl_module \
        --with-http_dav_module \
        --with-http_gzip_static_module \
        --with-http_realip_module \
        --with-mail \
        --with-mail_ssl_module \
        --with-ipv6 \
        --add-module=$(CURDIR)/modules/nginx-upstream-fair \
        --add-module=$(CURDIR)/anomalizer-ngx_aws_auth-37adfc3/
        --add-module=$(CURDIR)/ngx_aws_auth \
            $(CONFIGURE_OPTS)
...

コンパイルして、パッケージを作成

$ dpkg-buildpackage -b
...
gcc -c -Wall -g -O2   -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs -I src/http -I src/http/modules -I src/mail \
        -o objs/addon/anomalizer-ngx_aws_auth-37adfc3/ngx_http_aws_auth.o \
        /root/nginx-0.7.65/anomalizer-ngx_aws_auth-37adfc3//ngx_http_aws_auth.c
gcc -c -Wall -g -O2  -I src/core -I src/event -I src/event/modules -I src/os/unix -I objs \
        -o objs/ngx_modules.o \
        objs/ngx_modules.c
gcc -o objs/nginx \
    objs/src/core/nginx.o \
    objs/src/core/ngx_log.o \
    objs/src/core/ngx_palloc.o \
    objs/src/core/ngx_array.o \
    objs/src/core/ngx_list.o \
    objs/src/core/ngx_hash.o \
    objs/src/core/ngx_buf.o \
    objs/src/core/ngx_queue.o \
    objs/src/core/ngx_output_chain.o \
    objs/src/core/ngx_string.o \
    objs/src/core/ngx_parse.o \
    objs/src/core/ngx_inet.o \
    objs/src/core/ngx_file.o \
    objs/src/core/ngx_crc32.o \
    objs/src/core/ngx_rbtree.o \
    objs/src/core/ngx_radix_tree.o \
    objs/src/core/ngx_slab.o \
    objs/src/core/ngx_times.o \
    objs/src/core/ngx_shmtx.o \
    objs/src/core/ngx_connection.o \
    objs/src/core/ngx_cycle.o \
    objs/src/core/ngx_spinlock.o \
    objs/src/core/ngx_cpuinfo.o \
    objs/src/core/ngx_conf_file.o \
    objs/src/core/ngx_resolver.o \
    objs/src/core/ngx_open_file_cache.o \
    objs/src/event/ngx_event.o \
    objs/src/event/ngx_event_timer.o \
    objs/src/event/ngx_event_posted.o \
    objs/src/event/ngx_event_busy_lock.o \
    objs/src/event/ngx_event_accept.o \
    objs/src/event/ngx_event_connect.o \
    objs/src/event/ngx_event_pipe.o \
    objs/src/os/unix/ngx_time.o \
    objs/src/os/unix/ngx_errno.o \
    objs/src/os/unix/ngx_alloc.o \
    objs/src/os/unix/ngx_files.o \
    objs/src/os/unix/ngx_socket.o \
    objs/src/os/unix/ngx_recv.o \
    objs/src/os/unix/ngx_readv_chain.o \
    objs/src/os/unix/ngx_udp_recv.o \
    objs/src/os/unix/ngx_send.o \
    objs/src/os/unix/ngx_writev_chain.o \
    objs/src/os/unix/ngx_channel.o \
    objs/src/os/unix/ngx_shmem.o \
    objs/src/os/unix/ngx_process.o \
    objs/src/os/unix/ngx_daemon.o \
    objs/src/os/unix/ngx_setproctitle.o \
    objs/src/os/unix/ngx_posix_init.o \
    objs/src/os/unix/ngx_user.o \
    objs/src/os/unix/ngx_process_cycle.o \
    objs/src/os/unix/ngx_linux_init.o \
    objs/src/event/modules/ngx_epoll_module.o \
    objs/src/os/unix/ngx_linux_sendfile_chain.o \
    objs/src/event/ngx_event_openssl.o \
    objs/src/core/ngx_regex.o \
    objs/src/http/ngx_http.o \
    objs/src/http/ngx_http_core_module.o \
    objs/src/http/ngx_http_special_response.o \
    objs/src/http/ngx_http_request.o \
    objs/src/http/ngx_http_parse.o \
    objs/src/http/ngx_http_header_filter_module.o \
    objs/src/http/ngx_http_write_filter_module.o \
    objs/src/http/ngx_http_copy_filter_module.o \
    objs/src/http/modules/ngx_http_log_module.o \
    objs/src/http/ngx_http_request_body.o \
    objs/src/http/ngx_http_variables.o \
    objs/src/http/ngx_http_script.o \
    objs/src/http/ngx_http_upstream.o \
    objs/src/http/ngx_http_upstream_round_robin.o \
    objs/src/http/ngx_http_parse_time.o \
    objs/src/http/modules/ngx_http_static_module.o \
    objs/src/http/modules/ngx_http_index_module.o \
    objs/src/http/modules/ngx_http_chunked_filter_module.o \
    objs/src/http/modules/ngx_http_range_filter_module.o \
    objs/src/http/modules/ngx_http_headers_filter_module.o \
    objs/src/http/modules/ngx_http_not_modified_filter_module.o \
    objs/src/http/ngx_http_busy_lock.o \
    objs/src/http/ngx_http_file_cache.o \
    objs/src/http/modules/ngx_http_gzip_filter_module.o \
    objs/src/http/ngx_http_postpone_filter_module.o \
    objs/src/http/modules/ngx_http_charset_filter_module.o \
    objs/src/http/modules/ngx_http_ssi_filter_module.o \
    objs/src/http/modules/ngx_http_userid_filter_module.o \
    objs/src/http/modules/ngx_http_gzip_static_module.o \
    objs/src/http/modules/ngx_http_dav_module.o \
    objs/src/http/modules/ngx_http_autoindex_module.o \
    objs/src/http/modules/ngx_http_auth_basic_module.o \
    objs/src/http/modules/ngx_http_access_module.o \
    objs/src/http/modules/ngx_http_limit_zone_module.o \
    objs/src/http/modules/ngx_http_limit_req_module.o \
    objs/src/http/modules/ngx_http_realip_module.o \
    objs/src/http/modules/ngx_http_geo_module.o \
    objs/src/http/modules/ngx_http_map_module.o \
    objs/src/http/modules/ngx_http_referer_module.o \
    objs/src/http/modules/ngx_http_rewrite_module.o \
    objs/src/http/modules/ngx_http_ssl_module.o \
    objs/src/http/modules/ngx_http_proxy_module.o \
    objs/src/http/modules/ngx_http_fastcgi_module.o \
    objs/src/http/modules/ngx_http_memcached_module.o \
    objs/src/http/modules/ngx_http_empty_gif_module.o \
    objs/src/http/modules/ngx_http_browser_module.o \
    objs/src/http/modules/ngx_http_flv_module.o \
    objs/src/http/modules/ngx_http_upstream_ip_hash_module.o \
    objs/src/http/modules/ngx_http_stub_status_module.o \
    objs/src/mail/ngx_mail.o \
    objs/src/mail/ngx_mail_core_module.o \
    objs/src/mail/ngx_mail_handler.o \
    objs/src/mail/ngx_mail_parse.o \
    objs/src/mail/ngx_mail_ssl_module.o \
    objs/src/mail/ngx_mail_pop3_module.o \
    objs/src/mail/ngx_mail_pop3_handler.o \
    objs/src/mail/ngx_mail_imap_module.o \
    objs/src/mail/ngx_mail_imap_handler.o \
    objs/src/mail/ngx_mail_smtp_module.o \
    objs/src/mail/ngx_mail_smtp_handler.o \
    objs/src/mail/ngx_mail_auth_http_module.o \
    objs/src/mail/ngx_mail_proxy_module.o \
    objs/addon/nginx-upstream-fair/ngx_http_upstream_fair_module.o \
    objs/addon/anomalizer-ngx_aws_auth-37adfc3/ngx_http_aws_auth.o \
    objs/ngx_modules.o \
    -lcrypt -lssl -lpcre -lssl -lcrypto -lz
...

debパッケージをインストール

$ cd ..
$ sudo dpkg -i nginx_0.7.65-1ubuntu2.3_amd64.deb 

サーバー再起動

$sudo  service nginx restart

非常に簡単です。

参考にしたサイト:

Nginx AWS auth on Ubuntu 10.04

S3に保存されたファイルを直接S3にアクセスさせたくない場合のNginxの設定です。

通常は、素直にクラウドフロントを利用すればいいような気もしますが、調べてみたのでメモしておきます。

Nginxから認証付きでS3にアクセスするにはサードパーティのモジュールAWS Authを利用します。
モジュールは以下のリンクからダウンロードできます。

http://wiki.nginx.org/3rdPartyModulesJa

インストール

モジュールを追加してNginxをコンパイルするために必要な
unzipとgccを含むbuild-essentialをあらかじめインストールしておきます。

$ sudo apt-get update

2012.11.03現在では、apt-get updateしておかないとリポジトリのパスが変わっていてgccのインストールに失敗します

$ sudo apt-get install unzip gcc build-essential
$ sudo apt-get install libpcre3 libpcre3-dev
$ sudo apt-get install zlib1g-dev
$ sudo apt-get install openssl libssl-dev

Nginxのソースをダウンロードして解凍しておきます。

$ wget http://nginx.org/download/nginx-1.2.4.tar.gz
$ tar xvfz nginx-1.2.4.tar.gz 
$ cd nginx-1.2.4

次にAWS Authモジュールをダウンロードします。

$ wget https://github.com/anomalizer/ngx_aws_auth/zipball/master
$ mv master aws-auth.zip
$ unzip aws-auth.zip

configureしてmake

$./configure --sbin-path=/usr/sbin \
        --conf-path=/etc/nginx/nginx.conf \
        --error-log-path=/var/log/nginx/error.log \
        --pid-path=/var/run/nginx.pid \
        --lock-path=/var/lock/nginx.lock \
        --http-log-path=/var/log/nginx/access.log \
        --http-client-body-temp-path=/var/lib/nginx/body \
        --http-proxy-temp-path=/var/lib/nginx/proxy \
        --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
        --with-debug \
        --with-http_stub_status_module \
        --with-http_flv_module \
        --with-http_ssl_module \
        --with-http_dav_module \
        --with-http_gzip_static_module \
        --with-http_realip_module \
        --with-mail \
        --with-mail_ssl_module \
        --with-ipv6 \
        --add-module=./anomalizer-ngx_aws_auth-37adfc3

...
configuring additional modules
adding module in ./anomalizer-ngx_aws_auth-37adfc3/
 + ngx_http_aws_auth was configured
checking for PCRE library ... found
checking for PCRE JIT support ... not found
checking for system md library ... not found
checking for system md5 library ... not found
checking for OpenSSL md5 crypto library ... not found
checking for sha1 in system md library ... not found
checking for OpenSSL sha1 crypto library ... not found
checking for zlib library ... found
creating objs/Makefile

Configuration summary
  + using system PCRE library
  + using system OpenSSL library
  + md5: using OpenSSL library
  + sha1: using OpenSSL library
  + using system zlib library

  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/sbin"
  nginx configuration prefix: "/etc/nginx"
  nginx configuration file: "/etc/nginx/nginx.conf"
  nginx pid file: "/var/run/nginx.pid"
  nginx error log file: "/var/log/nginx/error.log"
  nginx http access log file: "/var/log/nginx/access.log"
  nginx http client request body temporary files: "/var/lib/nginx/body"
  nginx http proxy temporary files: "/var/lib/nginx/proxy"
  nginx http fastcgi temporary files: "/var/lib/nginx/fastcgi"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

$ make
...
	objs/src/http/modules/ngx_http_browser_module.o \
	objs/src/http/modules/ngx_http_upstream_ip_hash_module.o \
	objs/src/http/modules/ngx_http_upstream_least_conn_module.o \
	objs/src/http/modules/ngx_http_upstream_keepalive_module.o \
	objs/addon/anomalizer-ngx_aws_auth-37adfc3/ngx_http_aws_auth.o \
	objs/ngx_modules.o \
	-lpthread -lcrypt -lssl -lpcre -lcrypto -lcrypto -lz
make[1]: Leaving directory `/home/hrendoh/nginx-1.2.2'
make -f objs/Makefile manpage
make[1]: Entering directory `/home/hrendoh/nginx-1.2.2'
sed -e "s|%%PREFIX%%|/usr/local/nginx|" \
		-e "s|%%PID_PATH%%|/var/run/nginx.pid|" \
		-e "s|%%CONF_PATH%%|/etc/nginx/nginx.conf|" \
		-e "s|%%ERROR_LOG_PATH%%|/var/log/nginx/error.log|" \
		< man/nginx.8 > objs/nginx.8
make[1]: Leaving directory `/home/hrendoh/nginx-1.2.2'
...

インストール

$ sudo make install

設定

こんな感じです

location /s/attachment/ {
  proxy_pass http://<バケット名>.s3.amazonaws.com/;
  aws_access_key xxxxxxxxxxxxxxxx;
  aws_secret_key xxxxxxxxxxxxxxxx
  s3_bucket <バケット名>;
  chop_prefix /s/attachment;
		
  proxy_set_header Authorization $s3_auth_token;
  proxy_set_header x-amz-date $aws_date;
}

tarを使ってディレクトリごとファイルをコピー

Macの場合、mvコピー先に同名のディレクトリがあると-f付けてもはじかれるので重宝するかも(可能なオプションあるんですかね?)

カレントディレクトリの全てファイルおよびディレクトリをターゲッットディレクトリ(target_dir)にコピー

$ tar cf - * | ( cd /target_dir; tar xfp -)

カレントディレクトリの指定したディレクトリ(source_dir)をターゲッットディレクトリ(target_dir)にコピー

$ tar cvf - ./source_dir | (cd /target_dir; tar xvfp -)

参考: Copy files and directories recursively with tar

ニフティクラウドでrsyncを利用したバックアップを行った場合 Disk200とDisk40どちらを使うべきか?

クラウド上でサービスを提供する場合データの安全性については、ハード面のHAはサービスが提供しているため*1、アプリケーションの障害や人為的ミスによるデータ損傷に対応するためのバックアップが最低限必要になります。

co-meetingは、データベース以外のデータのバックアップは、シンプルに追加ディスクにrsyncで差分バックアップを数日間保持しています。
co-meetingは、ニフティクラウド上でサービスを提供していますが、ニフティクラウドはストレージに3x3重の冗長性を持たせているのでそこは信頼してバックアップファイルをS3など外部サービスに保存することは行っていません*2。
また、バックアップの仕組みにはLVMのスナップショットも検討していますが、LVMの運用経験が無いため、今のところ復旧がよりシンプルで確実なrsyncを採用しています*3

では、本題。

ニフティクラウドで利用可能なストレージは以下の物があります。

rsyncは、毎時cronで実行していますが、差分のみのコピーとはいえコマンドの実行時間が短いに超したことはありません。
コストを考えなければ、Disk200を迷わず選びましょう。
ただ、Disk200は10500円/100Gbytesと結構いいお値段がします。
それに対して、Disk40は4100円/100Gbytesとお手頃価格です。

コマンドの実行は、CPU、ネットワーク、ディレクトリ/ファイルの構造にも影響されるので単純にディスクのスピードだけでは比較できません。
そこで、各ストレージに対してコマンドを実行して計測してみました。

*1:復旧できないレベルのストレージ障害を起こしたサービスもいくつかあるので他のクラウドにもデータはバックアップしたいところですが、それはコストとの兼ね合いになります

*2:元々はs3syncを使っていましたがデータ量が増えて来たため厳しくなってきました、Enterprise版は再度検討する予定です

*3:ニフティクラウドが、ディスクのスナップショット機能を提供してくれればこれらの仕組みも必要なくなりますが、追加ディスクいついては厳しそうですかね

続きを読む

SSH越しのファイル操作まとめ

サーバー間でファイルをやり取りしたい場合にいつもコマンドを検索しなおしてしまうのでssh越しにファイルをコピーするコマンドをまとめてみました。

また、この記事を書いている途中に同様の内容をまとめているブログを見つけたのでリンクを貼っておきます。

前準備

キーファイルの権限変更

コピー後は権限を設定し直しておく

$ chmod 600 keyfile.pem
パスワード無しのキーファイルを作成しておく

ここで紹介するコマンドを使用するシェルをcronに登録する場合はパスフレーズ無しのキーファイルを用意しておく必要があります。

$ openssl rsa -in keyfile.pem > keyfile-nopass.pem
Enter pass phrase for keyfile.pem:
writing RSA key

cronで使用する場合は、以下に紹介するコマンドのkeyfileをkeyfile-nopass.pemに置き換えてください。
各コマンドの確認は、ubuntu10.04で行っています。

続きを読む

WebSocket(node + socket.io)をstunnel + HAProxyでプロキシする - その3 - stunnelのセットアップ

以下の図のような、stunnelとHAProxyを使ってnode.jsとnginxを1つにまとめる構成のサーバー構築手順をまとめています。

その1ではHAProxyのインストール、その2ではプロキシの設定例についてまとめました。
OSに依存する箇所はUbuntu 10.04を例に説明しています。

今回は、最後にHAProxyの前にstunnelを建ててSSLでWebサービスにアクセスできるようにして行きます。

stunnelのインストール (パッケージインストール)

stunnelのインストール手順については、主に以下のブログを参考にしました:
https://www.siamnet.org/Wiki/Ubuntu-SettingUpStunnel

stunnelはaptでインストールできます*1。

$ sudo apt-get install stunnel4

/etc/default/stunnel4の「ENABLED」の値を「0」から「1」に変更します。

#ENABLED=0
ENABLED=1

*1:クライアントIPアドレスを、X-Forwareded-ForヘッダをHAProxyからアプリケーションに送信する場合は、HAPorxyプロジェクトが用意しているパッチをあててソースからインストールする必要があります

続きを読む

WebSocket(node + socket.io)をstunnel + HAProxyでプロキシする - その2 - HAProxyの設定

Nginxとnode.jsをHAProxy+stunnelでまとめる方法についてまとめています。

サーバーの構成は以下のようになります。

前回の記事はHAProxyのインストールまで紹介しました。
http://d.hatena.ne.jp/hrendoh/20120328/1332917793

今回は、HAProxyでNginxとnode.jsのサーバーに振り分ける設定方法と、各種パラメータについて実際の設定例を基にまとめてみます。

設定のリファレンスは、公式サイトのDocumentページにリンクがあるテキストのものと、Google codeにも同じ内容のものがまとまっています。

Google codeのドキュメントの方が見やすいのでお薦めです。

haproxy.cfgの設定

HAProxyの設定は /etc/haproxy/haproxy.cfg に記述します。
今回の例は、以下のようになります。

続きを読む