SCP を利用して S3 署名付き URL の利用を HTTPS のみに制限してみた

2022.03.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、大前です。

詳細は以下ブログを参照したいただければと思いますが、S3 署名付き URL は、生成された URL を利用してアップロードやダウンロードを行う際に、権限に関する評価が行われます。

上記の仕様をもとに、SCP を利用して S3 署名付き URL の利用に対する制限を行えるのかを試してみました。具体的には、S3 署名付き URL を利用する際には HTTPS のみに限定する様なポリシーを SCP で適用してみたいと思います。

やってみた

SCP なしでの S3 署名付き URL 利用

まずは SCP の設定なしで S3 署名付き URL を利用し、コンテンツのアップロードとダウンロードを試してみます。

前提として、AWS 上で操作を行なっているユーザは Administrator 相当の権限を持ち、今回利用する S3 バケットはパブリックアクセス禁止かつバケットポリシーは無しの状態となっています。

S3 署名付き URL を利用したダウンロード

S3 にアップロード済みの sample_file というファイルを S3 署名付き URL を利用してダウンロードします。ダウンロード用の署名付き URL はコンソールから生成します。

取得した URL を利用すると、コンテンツのダウンロードができます。("THIS IS SAMPLE FILE" は sample_file 内に記載されたテキストです)

curl -X GET "https://<ダウンロード元バケット>.s3.ap-northeast-1.amazonaws.com/sample_file

THIS IS SAMPLE FILE

ちなみに、取得した URL を http に変更しても変わらずコンテンツが取得できます。後ほど、SCP を利用して https のみの利用に制限できるか試してみます。

curl -X GET "http://<ダウンロード元バケット>.s3.ap-northeast-1.amazonaws.com/sample_file

THIS IS SAMPLE FILE

S3 署名付き URL を利用したアップロード

続いて、アップロードです。S3 署名付き URL を利用したアップロードを試すにあたり、具体的な方法については以下ブログを参考にしました。ブログ内の記載に従えば、Lambda を利用してアップロード用の S3 署名付き URL を生成できます。

生成された URL を利用し、sample_file_2 というファイルをアップロードします。

curl -X PUT --upload-file sample_file_2 "https://<アップロード先バケット>.s3.amazonaws.com/sample_file_2

S3 にアップロードできました。

ダウンロードと同様に、払い出された URL を http に変更しても問題なくアップロードできます。これについてもダウンロードと同じく、後ほど SCP を利用して http でのアップロードを制限できるか試してみます。

curl -X PUT --upload-file sample_file_2 "http://<アップロード先バケット>.s3.amazonaws.com/sample_file_2

SCP で https のみ利用可能なポリシーを追加

制限がない状態だと http/https ともに S3 署名付き URL の利用が可能であることがわかったため、SCP にポリシーを追加し、意図した通りに制限がかけられるか確認してみます。

S3 が存在する AWS アカウント(もしくはアカウントが所属する OU)に対して、以下の SCP を適用します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
        "Sid": "Statement1",
        "Effect": "Deny",
        "Action": [
            "s3:GetObject",
            "s3:PutObject"
        ],
        "Resource": "arn:aws:s3:::*",
        "Condition": {
            "Bool": {
                "aws:SecureTransport": "false"
            }
        }
        }
    ]
}

S3 署名付き URL のアップロード/ダウンロードに対応するアクションは GetObject/PutObject であるため、アクションとしてはこの 2つを指定しています。また、Condition 句で aws:SecureTransport に関する条件を追加することで、HTTP リクエストを許可しない形にしています。Resource は全ての S3 バケットが対象になっていますが、特定の S3 バケットのみを指定しても良いと思います。

参考 : s3-bucket-ssl-requests-only の S3 バケットポリシーを作成する


SCP を追加したので、再度 S3 署名付き URL を利用した際の動作を確認してみます。

S3 署名付き URL を利用したダウンロード(SCP 制限あり)

先ほどと同様に、sample_file に対して S3 署名付き URL を生成し、ダウンロードを試みてみます。

# HTTPS
curl -X GET "https://<ダウンロード元バケット>.s3.ap-northeast-1.amazonaws.com/sample_file

THIS IS SAMPLE FILE
# HTTP
curl -X GET "http://<ダウンロード元バケット>.s3.ap-northeast-1.amazonaws.com/sample_file

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>xxxx</RequestId><HostId>xxxx</HostId></Error>

HTTP のリクエストのみ AccessDenied となったため、SCP が効いていることがわかります。


S3 署名付き URL を利用したアップロード(SCP 制限あり)

同様に、アップロードについても確認します。

# HTTPS
curl -X PUT --upload-file sample_file_2 "https://<アップロード先バケット>.s3.amazonaws.com/sample_file_2
# HTTPS
curl -X PUT --upload-file sample_file_2 "https://<アップロード先バケット>.s3.amazonaws.com/sample_file_2

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>xxxx</RequestId><HostId>xxxx</HostId></Error>

アップロードについても、HTTP のリクエストが弾かれました。


(その他) S3 署名付き URL を使わないパブリックアクセス

SCP を適用した状態で、S3 バケットのアクセス許可を変更し、パブリックにコンテンツにアクセスできる様にしてみました。

この状態で、署名付き URL を利用せずにコンテンツをダウンロードしてみます。

# HTTPS
curl -X GET https://<ダウンロード元バケット>.s3.ap-northeast-1.amazonaws.com/sample_file

THIS IS SAMPLE FILE
# HTTP
curl -X GET https://<ダウンロード元バケット>.s3.ap-northeast-1.amazonaws.com/sample_file

THIS IS SAMPLE FILE

S3 署名付き URL を利用しないパブリックアクセスの場合は HTTP でもアクセスできており、SCP が影響していないことがわかります。SCP が影響する範囲は IAM ユーザーとロールのみであるため、IAM エンティティを利用しないパブリックアクセスに対して制限をかけたい場合はリソースベースのポリシー(バケットポリシー)を利用する必要があります。

参考 : サービスコントロールポリシー (SCPs) - AWS Organizations

おわりに

SCP を利用し、S3 署名付き URL の利用に関する制限をかけてみました。

多分制限かけられるよな・・・?とは思いつつも、自信がなかったので実際に試して動作を確認することができてよかったです。

Organizations によるマルチアカウント環境などでは、個々の S3 バケットにポリシーをアタッチするのではなく、SCP といった中央集約可能な制御方法を利用したい場合もあるかと思います。そういった場合に、SCP で何をどこまで縛れるのか知っておくと役に立つかと思います。

以上、AWS 事業本部の大前でした。

参考