yuj1osm's tech blog

クラウドやセキュリティなど

Amazon S3アクセスポイントを使用したアクセス制御

Amazon S3アクセスポイントを使用したアクセス制御について紹介します。

Amazon S3アクセスポイントとは

バケットに対して、アクセスポイントという単位でアクセス権限を設定することができます。

docs.aws.amazon.com

何が嬉しいのか

従来のバケットポリシーは、バケットに対して1つ設定するものだったので、アクセス要件が変わると既存のバケットポリシーを変更する必要がありました。
要件が追加されるたびにバケットポリシーが長く複雑になり、管理が大変になってしまいます。
さらに、既存のポリシーを変更するため、設定を誤ると影響範囲も広くなってしまいます。

アクセスポイントはバケットに対して複数作成することができ、アクセスポイントごとにポリシーを設定することができます。
そのため、アクセス要件ごとにポリシーを分けることができ、管理しやすくなり、影響範囲を最小限に抑えられます。

S3アクセスポイントを設定してみる

事前準備1:IAMユーザ作成

バケットにアクセスするためのIAMユーザを作成します。
アクセス権限は「AdministratorAccess」を付与します。
※テスト用なので実運用では最小権限にする。

事前準備2:バケット作成

バケットを作成して、ファイルを格納します。

アクセスポイント設定

バケットの設定画面から、「アクセスポイント」→「アクセスポイントの作成」を押下します。

アクセスポイント名を付け、ネットワークオリジンはインターネットを選択する。

アクセスポイントポリシーは、オブジェクトに対する「s3:GetObject」を許可します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<accountID>:user/testuser01"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:ap-northeast-1:<accountID>:accesspoint/ap-testuser01/object/*"
        }
    ]
}

アクセスポイントが作成されました。

アクセスポイント経由でアクセスしてみる

CloudShellから想定通りアクセスできました。

$ aws s3api get-object --bucket arn:aws:s3:ap-northeast-1:<accountID>:accesspoint/ap-testuser01 --key test.txt output.txt
{
    "AcceptRanges": "bytes",
    "LastModified": "2022-10-15T07:47:12+00:00",
    "ContentLength": 3,
    "ETag": "\"900150983cd24fb0d6963f7d28e17f72\"",
    "ContentType": "text/plain",
    "Metadata": {}
}

しかし、このままではアクセスポイントを経由しない場合もアクセスできてしまいます。

$ aws s3api get-object --bucket accesspoints-test-bucket --key test.txt output.txt 
{
    "AcceptRanges": "bytes",
    "LastModified": "2022-10-15T07:47:12+00:00",
    "ContentLength": 3,
    "ETag": "\"900150983cd24fb0d6963f7d28e17f72\"",
    "ContentType": "text/plain",
    "Metadata": {}
}

そこで、アクセスポイントを経由しないアクセスを拒否します。

バケットポリシーに以下を設定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::accesspoints-test-bucket/*",
            "Condition": {
                "StringNotEquals": {
                    "s3:DataAccessPointArn": "arn:aws:s3:ap-northeast-1:<accountID>:accesspoint/ap-testuser01"
                }
            }
        }
    ]
}

アクセスポイントを経由した場合のみアクセスできました。

$ aws s3api get-object --bucket arn:aws:s3:ap-northeast-1:<accountID>:accesspoint/ap-testuser01 --key test.txt output.txt
{
    "AcceptRanges": "bytes",
    "LastModified": "2022-10-15T07:47:12+00:00",
    "ContentLength": 3,
    "ETag": "\"900150983cd24fb0d6963f7d28e17f72\"",
    "ContentType": "text/plain",
    "Metadata": {}
}
$ aws s3api get-object --bucket accesspoints-test-bucket --key test.txt output.txt 

An error occurred (AccessDenied) when calling the GetObject operation: Access Denied

まとめ

バケットポリシーでのアクセス制御はポリシーが複雑になりがちでした。
アクセスポイントを利用することで、要件ごとにポリシーを分けることができるため、管理がしやすくなりました。

Amazon S3のアクセス制御

Amazon S3のアクセス制御について紹介します。

Amazon S3とは

S3はAWSが提供するオブジェクトストレージであり、様々なアクセス制御方法が用意されています。

docs.aws.amazon.com

アクセス制御方法

IAMポリシー

IAMユーザやグループに対して、どのバケットやフォルダに対してどのような操作が可能か定義する。

バケットポリシー

バケットに対して、どのAWSアカウントやIAMがどのような操作が可能か定義する。

ACL

バケットやオブジェクトに対して、どのAWSアカウントがどのような操作が可能か定義する。
現在AWSでは非推奨。

S3ブロックパブリックアクセス

バケットやオブジェクトへのパブリックアクセスをブロックする。
デフォルトで有効。

IAMポリシーとバケットポリシーを試す

事前準備1:IAMユーザ作成

バケットにアクセスするためのIAMユーザを作成します。
アクセス権限は未設定です。

事前準備2:バケット作成

バケットを作成して、ファイルを格納します。

ブロックパブリックアクセスはオンで、バケットポリシーは未設定です。

IAMユーザでバケットへアクセス

IAMポリシーもバケットポリシーも未設定なので、バケットへアクセスすることができません。

そこで、IAMポリシー「AmazonS3FullAccess」を付与してみます。

バケットとその配下のオブジェクトにアクセスすることができました。

バケットポリシーに以下を追加しても、オブジェクトにアクセスすることができます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<accountID>:user/testuser01"
            },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::access-controle-test-bucket",
                "arn:aws:s3:::access-controle-test-bucket/*"
            ]
        }
    ]
}

IAMポリシーとバケットポリシーの注意点

前述のようなバケットポリシーで特定ユーザを明示的に許可しても、他のユーザからもアクセスできてしまいます。
そのため、明示的にDenyポリシーも併せて利用するべきです。

IAMポリシーには読み取り専用として使われる、「ReadOnlyAccess」ポリシーというものがあります。

便利なポリシーですが、バケットからオブジェクトをダウンロードすることができてしまいます。
例えば、機密情報をバケットに格納しても、「ReadOnlyAccess」ポリシーがあればデータを持ち出されるリスクがあります。
そのため、以下のようなDenyポリシーも併せて利用するべきです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "s3:Get*",
            "Resource": "*"
        }
    ]
}

Denyポリシーでダウンロードが失敗した例です。

まとめ

今回は、IAMポリシーとバケットポリシーを紹介しました。
データ保管には便利なサービスですが、設定を誤ったために情報漏洩してしまうという事例が起きています。
設定が意図したとおりに動くか、しっかりとテストしておくことが重要です。
今一度、S3のセキュリティを見直してみるとよいかもしれません。