こんにちは。takada@福岡オフィスです。
ポケモンGOをやってます。深夜、近所のポケストップを一人で徘徊していると、カップルから「あの人、一人でポケモンGOやってる。ヤバくない」と指さされました。
家に返って「ヤバイ」辞書を調べたら、どうやら否定的な意味と、「凄い」「のめり込みそうなくらい魅力的」といった肯定的な意味の2つの意味があるらしく、「あーなるほど。あのカップルは後者の意味で使ってたのだ」と腑に落ちたのでした。そう、何事も調べることが大事。
今回は、VPCエンドポイント構成でS3バケットへのアクセスを制限する方法を調べてみました。
VPCエンドポイント is 何?
ブリを産んだ魚、じゃなくて人のブログに書かれております。ここ読めワンワン。
以下抜粋。
「VPCと別のAWSサービスとの間でプライベート接続を作成できるようになります。
つまり、S3にアクセスする際にも、インターネットを経由しなくてよくなるんですね。」
ほーほー。
VPCエンドポイント構成で、S3へのアクセス制限をかける意味
VPCエンドポイントのつかいどころとしては、当然VPCの内側からS3へのアクセスをするケースとなります。
多くの場合、以下のように、EC2からS3へのアクセスが利用用途となるでしょう。
例えば、特定のS3バケット「hoge」にVPC内のEC2からのみアクセスを許可したいケースを考えてみます。
EC2からS3へのアクセス制限をかける場合、S3バケットへのアクセスを許可したIAMポリシーを紐付けたIAMロールを作成し、EC2に付与するのがベストです。
理由は以下の2つです。
- EC2の内部に認証情報(IAMアカウントのシークレットアクセスキー)を保つ必要がない
- IAMポリシーは「デフォルト拒否」の動作となるため、実質的にこのバケットにアクセスできるのは、IAMロールを付与されたEC2のみとなる
ただし、これは、S3バケットへアクセスするEC2内で動作するアプリケーション("aws cli"など)がIAMロールに対応している場合に限ります。
IAMロールに対応していないアプリケーションからS3バケットへアクセスする場合は、やはり、IAMユーザーのシークレットアクセスキーを払い出して、EC2内部にもたせる必要があります。このケースですと、万が一、シークレットアクセスキーが漏れてしまった場合、S3バケット「hoge」にはインターネット側からもアクセスが可能となります。
これを防ぐため、払いだしたIAMユーザに対して接続元をVPC内に制限するポリシーを割り宛てる必要がでてきます。
送信元をVPCのCIDRで制限してみた。
こんな感じのIAMポリシーを作って、IAMユーザーに適応してみました。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "10.0.0.0/16"
}
}
},
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::hoge",
"arn:aws:s3:::hoge/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": "10.0.0.0/16"
}
}
}
]
}
結果、効きません。該当バケットにアクセスできない状態になります。なぜでしょう
答えはドキュメントに
書いてありました。辞書とドキュメントは調べるに限ります。
「Amazon S3 エンドポイントを使用する場合、バケットポリシーまたは IAM ポリシーを使用して VPC CIDR 範囲(プライベート IP アドレス範囲)からのアクセスを許可することはできません。VPC CIDR ブロックは重複または同じになる場合があり、それによって予期しない結果が発生する可能性があります。代わりに、バケットポリシーを使用して特定のエンドポイントまたは特定の VPC へのアクセスを制限するか、ルートテーブルを使用して、エンドポイント経由で Amazon S3 のリソースにアクセスできるインスタンスを制御できます。」
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/vpc-endpoints.html#vpc-endpoints-limitations
なるほど、VPC内部のプライベートアドレス帯はAWSアカウントごと、もしくはAWSアカウント内で重複して設定が可能なので、制限する条件となり得ないということですね。
代わりに、VPCエンドポイントIDもしくはVPC IDを使用して制限する必要があります。
マニュアルでは、「バケットポリシー」の例が記載されていますが、確認したところ、IAMポリシーを使用した制限も可能です。
ちなみに、IAMポリシーとバケットポリシーの違いですが、IAMポリシーは操作主体(IAMユーザあるいはEC2インスタンス)に付与するポリシーとなり、
バケットポリシーは、操作対象(S3バケット)に付与するポリシーとなります。バケットポリシーに設定した場合、操作主体(IAMユーザあるいはEC2インスタンス)を問わず、制御がかかることになります。
今回のケースですと、バケットポリシーで設定した場合は、S3バケットへのアクセスはいかなる操作主体(IAMユーザあるいはEC2インスタンス)であっても、VPC内部からしかアクセスできません。
一方、IAMポリシーの場合は、設定した"操作主体(IAMユーザあるいはEC2インスタンス)のみ、S3バケットへのアクセスがVPC内部のみに制限されることになります。
以下、前述のIAMポリシーをVPCエンドポイントIDを使用するように変更したものになります。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "arn:aws:s3:::*",
"Condition": {
"StringEquals": {
"aws:sourceVpce": [
"vpce-xxxxxxxx"
]
}
}
},
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::hoge",
"arn:aws:s3:::hoge/*"
],
"Condition": {
"StringEquals": {
"aws:sourceVpce": [
"vpce-xxxxxxxx"
]
}
}
}
]
}
まとめ
以下、まとめです。
VPCエンドポイント構成でEC2からS3バケットへのアクセス制限をかける場合は、
- IAMロールとIAMポリシーを使用するのがベストです。
- アクセスキーを使用する場合は、バケットポリシーもしくはIAMポリシーで、VPC IDかVPCエンドポイントIDで制限を行いましょう。
ちなみに、連日の深夜徘徊のおかげで、ポケモンGOのトレーナーレベルが22になりました。
決して、ヒマなのではありません。ではでは。