LoginSignup
4
0

More than 5 years have passed since last update.

APIGateway + Lambdaで、IP制限付き署名付きS3バケットURLの発行と配信を行う

Posted at

背景

APIGateway + Lambda 経由でユーザからデータを送られてきたデータをS3に保存する。このデータに、「時間制限付き」で「社内IPからのみ」、URLでアクセスできるようにしたい。

実現手法

署名付きURL + Policy で実現する

署名付きURL付きをLambda関数内で発行する。このURLには有効期限を設定することができる。
また権限は、 Lambda Function に設定されているユーザロールと同様のものとなるため、このユーザロールのポリシーに社内IPからのみのアクセス制限をかける。

ポリシー例

  • バケット:mybucket
  • アクセス可能に設定したいIP: 203.0.113.0/24 (社内IPが固定であれば、 ***.***.***.***/32 のような形になる)
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Resource": "arn:aws:s3:::mybucket/*",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject"
            ]
        },
        {
            "Resource": "arn:aws:s3:::mybucket/*",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "203.0.113.0/24"
                }
            }
        }
    ]
}

Action ごとに Condition を設定することで個別にIPアクセス制限を設定する。
当該バケットへのデータの送信はどのIPからでも可能、データへのアクセスは指定されたIPからのみ可能とする。
このPolicyをLambda関数のユーザロールにアタッチする。

Lambda 関数例(抜粋)


fileObj = ... # 受信したファイルオブジェ
key = ... # S3 key
bucket.put_object(
  Body = fileObj,
  Key = key
)

# この s3_url がアクセス可能なURLになる
# これは何らかの方法でアクセスしたい人に通知する
s3_url = s3_client.generate_presigned_url(
  ClientMethod = "get_object",
  Params = {"Bucket": "mybucket", "Key": key},
  ExpiresIn = 3600, # 3600秒
  HttpMethod = "GET"
)

Lambda関数内での、各サービスへのアクセス権限及び、発行した署名付きURLはLambda関数の持つポリシーと同様になるため、put_objectはどのIPからでも可能、URLアクセスであるget_objectはポリシーに設定されているIPからのみとなる。
また3,600秒のみURLアクセスが可能である。

4
0
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
4
0