背景
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アクセスが可能である。