BFT名古屋 TECH BLOG

日々の業務で得た知識を所属するエンジニアたちがアウトプットしていきます。

【AWS】S3バケットの閲覧・操作をVPC内のインスタンスからのみに制限する方法

こんにちは!
BFT名古屋支店の、佐野です。

今回は以前お送りした記事にて少しだけ触れた、S3バケットを閲覧・操作できる端末をVPC内のインスタンスのみに限定する方法についてお送りします。


はじめに

今回の内容は以前の記事「S3バケットの内容をプライベートなインスタンスから閲覧・操作する方法」で課題3.として挙げた
「 S3を閲覧・操作可能な端末を特定のEC2インスタンスのみに限定すること」
についてですが、その記事にて述べた通り今回紹介するのは実際の案件においてはボツとなった手法です。
テストはしていますが、実際に運用実績のあるものではありませんので、参考情報としてご覧ください。

また注意事項として、今回の手法を実施すると対象のS3バケットAWSマネジメントコンソールからの操作を受け付けなくなります。
もしお試しをする際は、テスト用のS3バケットを作成し、そちら上で実施することを強く推奨します。


前提条件および今回の手法の仕組みについて

S3バケットにはパブリックな接続を制限する「パブリックブロックアクセス」というアクセス制御の仕組みがありますが、今回は使用しません。
その代わり、他のAWSサービスにおけるポリシーと同じようにS3バケットに対して直接ポリシーを設定できる「バケットポリシー」を利用します。

今回の手法を具体的にすると「バケットポリシーに“特定のVPCエンドポイントを経由した接続以外を拒否する”という設定を記述する」というものになります。
ですので、前提としてS3へ接続を許可したいインスタンスがあるVPCに対し、VPCエンドポイントを作成する必要があります。
VPCエンドポイントの作成方法に関しては以前の記事となる以下を参照ください。

bftnagoya.hateblo.jp

構成およびアクセス許可のイメージについては以下の図の通りになります。

f:id:bftnagoya:20201202120721p:plain


パブリックブロックアクセスの無効と、バケットポリシーの設定

最初に以下の通りパブリックブロックアクセスを無効とします。
今回はバケットポリシーでのみ制限を行ない、その他の制限を無効化することで何が制限されているかを分かりやすくするためです。

パブリックブロックアクセスの無効化は、S3バケット内の「アクセス許可」タブから設定することができます。

f:id:bftnagoya:20201202120701p:plain

次に、バケットポリシーを編集します。
パブリックブロックアクセスと同様、S3バケット内の「アクセス許可」タブから設定することができます。

f:id:bftnagoya:20201202120653p:plain

記述するバケットポリシーの例は以下の通りです。

{
   "Version": "2012-10-17",
   "Id": "Policy1415115909152",
   "Statement": [
     {
       "Sid": "Access-to-specific-VPCE-only",
       "Action": "s3:*",
       "Effect": "Deny",
       "Resource": ["(S3バケットのARN)",
                    "(S3バケットのARN)/*"],
       "Condition": {
         "StringNotEquals": {
           "aws:sourceVpce": "(許可するVPCエンドポイントのエンドポイントID)"
         }
       },
       "Principal": "*"
     }
   ]
}

実際にVPCエンドポイントIDとS3バケットのARNを入れた例が以下となります。
VPCエンドポイントID、S3バケットARNともに架空のものとなります)

{
   "Version": "2012-10-17",
   "Id": "Policy1415115909152",
   "Statement": [
     {
       "Sid": "Access-to-specific-VPCE-only",
       "Action": "s3:*",
       "Effect": "Deny",
       "Resource": ["arn:aws:s3:::test2234",
                    "arn:aws:s3:::test2234/*"],
       "Condition": {
         "StringNotEquals": {
           "aws:sourceVpce": "vpce-0aaeeb2b20f4bcf4e"
         }
       },
       "Principal": "*"
     }
   ]
}

バケットポリシーを記述したら「変更の保存」を選択します。

これでパブリックブロックアクセスの無効と、バケットポリシーの設定は完了です。


結果

バケットポリシーの設定後、ポリシーを設定したS3が以下のように閲覧・操作できなくなっていれば、ポリシーは正しく動作しています。
AWSマネジメントコンソールは、ポリシーで指定したVPCエンドポイントを経由してS3バケットにアクセスしていないため、閲覧と操作を拒否されるという形になります。

f:id:bftnagoya:20201202120656p:plain

一方で、VPCエンドポイントを経由してのみS3にアクセスできるVPC内のインスタンスは、AWS CLIでこのS3バケットの内容を閲覧・操作することが可能になっているはずです。
勿論VPCエンドポイントを経由していなければVPC内のインスタンスでも弾いてしまいますので、もし疎通しなかった場合はそのインスタンスが属するルートテーブルのルーティングに指定のVPCエンドポイントが設定されているかを確認してください。

以上で「S3バケットを閲覧・操作できる端末をVPC内のインスタンスのみに限定する」設定が完了となります。


最後に

このように、VPC内のインスタンスのみにS3バケットを閲覧・操作させたい場合は、バケットポリシーを設定するのが早いと思います。
ただ、ここまで読んでくださった方はもしかすると、この手法がボツになった理由が分かるかもしれません。
何回か述べた通り、この手法だと本当にAWSマネジメントコンソールからの操作を一切受け付けなくなるので、管理がとても大変になってしまいます。
S3バケットの内容の閲覧・操作はともかく、一度設定したバケットポリシーの修正、S3バケットの削除などもすべてVPC内のインスタンスからAWS CLIによって行わなければならないためです。
利便性を取るかセキュリティを取るか、あるいは両立できる別の方法を探すか……

兎にも角にも、このようなケースもあった、という形で参考として記憶の隅に留めて頂けると幸いです。