インフラ

S3のオブジェクトをIP制限して公開する方法(ポリシーの設定)

こんにちは、ちゃりおです。

今回は、S3のオブジェクトをIP制限して公開する方法です。
署名付きURLで共有するほうがいいと思いますが、使う機会があったのでIP制限の方法を紹介します。

Contents

最終的なアクセスポリシー

最終的には、以下のようになりました。
オブジェクトの取得を特定IPからのみ許可していきます。

{
    "Version": "2012-10-17",
    "Id": "Policy1609839852365",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<バケット名>/*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "IPアドレス1",
                        "IPアドレス2",
                    ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<バケット名>/*"
        }
    ]
}
ちゃりお
ちゃりお
設定の流れを詳しく、解説します。

S3のオブジェクトのIP制限 設定の流れ

やることは、主に3つです。

  • ブロックパブリックをオフにする
  • オブジェクトを公開する
  • アクセスポリシーでIPアドレスの制限をする

ブロックパブリックアクセスをオフにする

オブジェクトを公開したいため、「ブロックパブリックアクセス」はオフにします。

s3 ブロックパブリック

オブジェクトを公開する

ブロックパブリックアクセスをオフにしただけでは、オブジェクトへアクセスできません。

% curl https://access-test-210109.s3-ap-northeast-1.amazonaws.com/test.html

AccessDeniedAccess Denied27D4761180B7B2D92tS91AtBrzhD/4Z4GkilV1VeBsfmojTht6PJ5qXnWMx+NFxlJnfOUNktsqJQEKQwq5qcFHG8TDU=% 

IP制限をする前に、オブジェクトをパブリックから読み込めるかテストします。
テスト用のファイルを作って、S3にアップロードします。

その後オブジェクトにパブリックから読み込みができるように、aclの設定を変更します。
(マネジメントコンソールからだと、オブジェクトを選択してアクションで「公開」を選びます)

# パブリックから読み込みめるようにACL変更
aws s3api put-object-acl --bucket access-test-210109 --key test.html --acl public-read

変更後に試してみると、パブリックからオブジェクトの読み込みが成功しました。

% curl https://access-test-210109.s3-ap-northeast-1.amazonaws.com/test.html
hello

アクセスポリシーでIPアドレスの制限をする

IPアドレスの制限を行います。

参考 Amazon S3 バケットにアクセスできる VPC エンドポイントまたは IP アドレスを指定するにはどうすればよいですか?

{
    "Version": "2012-10-17",
    "Id": "Policy1609839852365",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::バケット名/*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": "<IPアドレス>"
                }
            }
        }
    ]
}

ポリシーを設定すると、IPアドレスでの制限ができました。

# 許可IPの場合
% curl https://access-test-210109.s3-ap-northeast-1.amazonaws.com/test.html
hello
# 許可IP以外の場合
% curl https://access-test-210109.s3-ap-northeast-1.amazonaws.com/test.html

AccessDeniedAccess Denied95DD99096EA76A9BirXLMnxkgFCpxflhXjgqKfahUMV2JzHhGCCAa3JYYevPGWFTaJT5bQ19HQB9QO5qCOGDrAMwbpY=%

(オプション)新規アップロードしたファイルも公開するように設定する

現状だと新規にアップロードした場合、「オブジェクトの公開」の操作を行う必要があります。

毎回やるのも面倒なので、バケット内のオブジェクト全体に対してパブリックからの読み込みを許可します。

{
    "Version": "2012-10-17",
    "Id": "Policy1609839852365",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<バケット名>/*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "",
                        "",
                    ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::<バケット名>/*"
        }
    ]
}
ちゃりお
ちゃりお
拒否のほうが優先度が高いため、「指定したIPアドレス以外を拒否」→「バケット内のすべてのオブジェクト読み込みを許可」の順でポリシーが適用されます。

まとめ

S3のオブジェクトの公開・IPアドレスの制限についてでした。

S3は権限の制御がいろいろあり、なかなかややこしいです。
以下は、今回設定を変更した設定です。

  • ブロックパブリックアクセス
  • バケットポリシー
  • ACL

ざっくり明示的な拒否が最優先、許可>デフォルトの順で適用されることを覚えておくといいかと思います。

AWS公式 ポリシーの評価論理
Qiita S3のアクセスコントロールまとめ

S3ウェブサイトホスティングでHTTP,HTTPSのリダイレクトサーバを作るこんにちは、ちゃりおです。 サイトのドメイン変更とかで、リダイレクトサーバが必要なことがあると思います。 「Route53 + Clo...
AWSの勉強を始めるならSAAを取得してみるのがおすすめな理由こんにちは、ちゃりおです。 「AWS使えるようになりたけど、何から始めればよいかわからない」 という方向けの記事です。 AWSソリュ...
fluentd
[fluentd]s3にログを出力するとき、パスにホスト名を含める(プラグイン不要)s3にログを吐くとき、ホスト名をパスに含めたいときがありました。 今までは、ホスト名をtd-agent.confにベタがきしていました。...