LoginSignup
5
3

More than 5 years have passed since last update.

S3をバックエンドにしてbasic認証をかける方法

Posted at

前提

要件

  • 実際はこのClientとEBの間にCloudFrontをはさみます
  • 特定のpathだけBasic認証をかけたいという要望があり、基本的にはCF -> S3な構成なのですが、一部EBを経由させてここでBasic認証をかけるという狙い(この記事を書いた時点では、CFを介しての検証はしてないですが、CFを介したBasic認証の事例はたくさんあったので大丈夫という想定)

課題

最初は単純に、Basic認証とS3の認証をそれぞれクリアすればよいと思って以下のような設定にしました。
s3_auth.luaの中で、S3へアクセスするためのAuthorization Headerの値を生成してます。

...
location ~ ^/(.*)$ {
      auth_basic "Restricted";
      auth_basic_user_file /usr/local/nginx/conf/.htpasswd;
      rewrite_by_lua_file '/usr/local/nginx/lua/s3_auth.lua';
      proxy_hide_header x-amz-id-2;
      proxy_hide_header x-amz-request-id;
      proxy_intercept_errors on;
      proxy_pass http://$bucket.s3.amazonaws.com/$1;
    }
...

参考までにs3_auth.luaはこんな感じ

local date = ngx.http_time(ngx.time())
local string_to_sign = ngx.req.get_method() .. "\n\n\n" .. date .. "\n/" .. ngx.var.bucket .. "/" .. ngx.var.full_filename
ngx.req.set_header("Date", date)
local digest = ngx.hmac_sha1(ngx.var.secret_key, string_to_sign)
local signature = ngx.encode_base64(digest)
ngx.req.set_header("Authorization", "AWS " .. ngx.var.access_key .. ":" .. signature)
ngx.req.clear_header("x-amz-cf-id")

これだと、S3用のAuthorization Headerに書き換えてしまいBasic認証が通らなくなってしまうという罠にハマってしまいました。
内部的にproxyさせてあげることで、Basic認証とS3への認証を別々に扱うことができました。

...
    location ~ ^/(.*)$ {
      auth_basic "Restricted";
      auth_basic_user_file /usr/local/nginx/conf/.htpasswd;
      proxy_hide_header x-amz-id-2;
      proxy_hide_header x-amz-request-id;
      proxy_intercept_errors on;
      proxy_pass http://127.0.0.1:8081/$1;
    }
  }

  server {
    listen 8081 default_server;
    sendfile      on;
    tcp_nopush    on;
    send_timeout 120;
    access_log off;

    set_by_lua $bucket 'return os.getenv("BUCKET")';
    set_by_lua $access_key 'return os.getenv("AWS_ACCESS_KEY")';
    set_by_lua $secret_key 'return os.getenv("AWS_SECRET_KEY")';


    location ~ ^/(.+)$ {
      set $full_filename $1;
      rewrite_by_lua_file '/usr/local/nginx/lua/s3_auth.lua';
      proxy_hide_header x-amz-id-2;
      proxy_hide_header x-amz-request-id;
      proxy_hide_header Cache-Control;
      proxy_set_header Host $bucket.s3.amazonaws.com;
      proxy_pass http://$bucket.s3.amazonaws.com/$1;
      error_page 415 /50x.html;
    }
... 
5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3