mruby_nginx_module を使用して,Riak CS や Amazon S3 のオブジェクトをブラウザから取得する

Riak CS や Amazon S3 に置いたファイルを非公開にした状態で,Nginx を介した場合にのみ,アクセス元のユーザは Access Key ID も Secret Access Key も使用せずに,非公開設定のファイルを取得します.

構成

Nginx 側で,Amazon S3 API の Authorization ヘッダを計算/追加して,プロキシします.

f:id:Hexa:20131221152615p:plain

環境準備

# git clone https://github.com/cubicdaiya/mruby_nginx_module.git
# cd mruby_nginx_module
# git submodule update --init
# cd mruby
# make
# cd
# git clone https://github.com/simpl/ngx_devel_kit.git
# curl -O http://nginx.org/download/nginx-1.4.4.tar.gz
# tar zxvf nginx-1.4.4.tar.gz
# cd nginx-1.4.4
# ./configure --prefix=/opt/nginx/1.4.4 --add-module=../mruby_nginx_module --add-module=../ngx_devel_kit --with-http_ssl_module
# make && make install
nginx.conf の設定
        location / {
                if ( $request_method != GET ) {  return 400; }
                set $aws_access_key_id "aws_access_key_id";
                set $aws_secret_access_key "aws_secret_access_key";
                set $bucket_name "bucket";
                set $base_url "example.com";
                mruby_set_code $date "Nginx::Time.http_time(Nginx::Time.time)";
                mruby_set_code $authorization '

                        content_md5 = ""
                        content_type = ""

                        request = Nginx::Request.new
                        var = Nginx::Var.new
                        string_to_sign = request.method + "\n" +
                                         content_md5 + "\n" +
                                         content_type + "\n" +
                                         var.date + "\n" +
                                         "/" + var.bucket_name + request.uri
                        hmac_sha1 = Nginx::Digest.hmac_sha1(string_to_sign, var.aws_secret_access_key)
                        "AWS " + var.aws_access_key_id + ":" + Nginx::Base64.encode(hmac_sha1)
                ';

                proxy_set_header Host $bucket_name.$base_url;
                proxy_set_header Date $date;
                proxy_set_header Authorization $authorization;
                proxy_pass http://$bucket_name.$base_url:80$uri;
        }