読者です 読者をやめる 読者になる 読者になる

tk3.log

こちはら、メモやいろいろを残していきます

ngx_mruby as proxy for Amazon S3 private files

Summary

ngx_mruby を使って、プライベートな S3 にアクセスできるようにします。

Operation verification

  • Ubuntu
  • ngx_mruby
    • qtkmz/mruby-digest-ffi
      • HMAC-SHA1 を使うために使用します
      • iij/mruby-digest でもできるかもしれませんが、試していません
    • iij/mruby-pack
      • Base64 を使うために使用します

Configuration

build_config.rb

MRuby::Build.new do |conf|
  ...(省略)...
  conf.gem :github => 'iij/mruby-pack'
  conf.gem :github => 'qtkmz/mruby-digest-ffi'

  ...(省略)...
end

nginx.conf

location ~* ^/s3/(.*) {
  set $bucket '<bucket-name>';
  set $aws_access '<access-key>';
  set $url_full "$1";
  mruby_set $aws_signature "./aws_signature.rb";
  mruby_set $aws_now "./aws_now.rb";

  resolver               8.8.8.8 valid=300s;
  resolver_timeout       10s;
  proxy_http_version     1.1;
  proxy_set_header       Host $bucket.s3.amazonaws.com;
  proxy_set_header       x-amz-date $aws_now;
  proxy_set_header       Authorization "AWS $aws_access:$aws_signature";
  proxy_buffering        off;
  proxy_intercept_errors on;
  rewrite .* /$url_full break;
  proxy_pass             http://<bucket-name>.s3-ap-northeast-1.amazonaws.com;
}

aws_now.rb

[Time.new.utc.to_s.split(" ")].map{|s| "#{s[0]}, #{s[2]}-#{s[1]}-#{s[5][2,2]} #{s[3]} GMT"}[0]

aws_signature.rb

bucket = '<bucket-name>'
aws_secret = '<aws-secret>'

req = Nginx::Request.new

method = req.method
now = [Time.new.utc.to_s.split(" ")].map{|s| "#{s[0]}, #{s[2]}-#{s[1]}-#{s[5][2,2]} #{s[3]} GMT"}[0]

string_to_sign = "#{method}\n\n\n\nx-amz-date:#{now}\n/#{bucket}/#{req.var.url_full}"

h = Digest::HMAC.new aws_secret, Digest::SHA1
h.update string_to_sign

[h.digest].pack("m")

References