この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
AWSチームのすずきです。
静的ウェブサイトホスティング用に設定したAmazon S3、 バケットポリシーでUserAgent判定を行い、特定のCloudFront以外からのアクセスを制限する機会がありましたので、紹介させていただきます。
設定
CloudFront
オリジン設定で、CloudFront標準のUserAgentに任意の文字列を追加する指定を行いました。
- HeadersHeader : User-Agent
- NameValue : Amazon CloudFront <任意文字列>
S3
S3バケットポリシーとして、任意の文字列が付与された CloudFrontのみアクセス(GetObject)を許可する指定を行いました。
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<S3バケット>/*",
"Condition": {
"StringEquals": {
"aws:UserAgent": "Amazon CloudFront <任意文字列>"
}
}
}
]
}
動作確認
参照可能
- UserAgentに特定文字を設定したCloudFrontは参照可能です。
参照不可
- S3の直接参照は403 Forbiddenとなりました
- UserAgentがデフォルトのCloudFront経由のアクセスは 403 Forbiddenとなりました。
まとめ
S3のウェブサイトホスティングを採用したシンプルなWebサイトだが、 開発中のコンテンツが第三者に参照される事は望ましくないため、CloudFrontへのアクセスは、AWS WAFや、Lambda@Edge などで 実施する場合、 オリジンのS3のアクセス制限する手段として、今回の設定をお試しください。
尚、S3の静的ウェブサイトホスティングをCloudFrontのカスタムオリジンで利用する場合、通信プロトコルはHTTPとなります。 CloudFront、S3間の通信はAWS内で完結する事が期待できますが、全てのグローバルIPを利用した通信で暗号化通信が必要な場合、S3オリジン+OAIでの利用をお勧めします。
CloudFormation
再現用のCloudFormationテンプレートです。
AWSTemplateFormatVersion: '2010-09-09'
Description: S3 web hosting with access settings limited to CloudFront
Parameters:
UseragentToken:
Description: Token to add to user agent
Type: String
Default: hogehoge
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Sub '${AWS::StackName}-${AWS::Region}-${AWS::AccountId}'
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: error.html
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: false
IgnorePublicAcls: true
RestrictPublicBuckets: false
S3BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref 'S3Bucket'
PolicyDocument:
Statement:
- Action: s3:GetObject
Effect: Allow
Resource:
- !Sub 'arn:aws:s3:::${S3Bucket}/*'
Principal: '*'
Condition:
StringEquals:
aws:UserAgent: !Sub 'Amazon CloudFront ${UseragentToken}'
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- Id: CustumOrigin
DomainName: !Sub '${AWS::StackName}-${AWS::Region}-${AWS::AccountId}.s3-website-${AWS::Region}.amazonaws.com'
CustomOriginConfig:
HTTPPort: 80
OriginProtocolPolicy: http-only
OriginCustomHeaders:
- HeaderName: User-Agent
HeaderValue: !Sub 'Amazon CloudFront ${UseragentToken}'
Enabled: 'true'
DefaultRootObject: index.html
DefaultCacheBehavior:
TargetOriginId: CustumOrigin
ForwardedValues:
QueryString: false
ViewerProtocolPolicy: redirect-to-https
DefaultTTL: 300
MaxTTL: 300
MinTTL: 300