LoginSignup
0
0

More than 1 year has passed since last update.

CloudFront+S3サイトをMozilla ObservatoryでA+評価にする方法(2021)

Last updated at Posted at 2021-06-15

はじめに

S3+CloudFront+Route53+ACMで静的Webサイトの記事があったのでリンクを追加。まずこの方法でサイトを構築するとMozilla ObservatoryだとF評価なので、セキュリティヘッダーを追加しよう、またSPAのルーティングの場合はどうするのが良いか。という記事です。
追記(2021/6/18)

セキュリティヘッダー

CloudFrontではセキュリティ系のヘッダーが指定されないのでこれらをCloudFront Functionsで追加すること。まずはAWS sampleの値をベースに厳しい方向へ。現実的にはバックエンドのAPIを呼び出すことが殆どだと思うので Content Security Policy (CSP) のconnect-srcにアクセス先を指定したり、SPAフレームワーク側などの実装に合わせてprefetch-src 'self';の追加とかstyle-src 'self' 'unsafe-hashes' 'unsafe-inline';への変更が必要。ここらへんは実際のアプリケーションの実装に合わせてデベロッパーツールを見ながら対処。

Google の Web Fundamentals 解説とChromeデベロッパーツールでの手順なんかが参考になる。

ルーティング(オプション)

多くの場合SPAでもルーティングさせることになると思うので、

Terraformでの設定

基本的なCloudFrontとS3の設定を除き、これらをTerraformで実現すると次の部分の追加になる。いや、viewer-responseviewer-requestを間違って動かなかったのでそれをメモしときたかったのが本題。あとマネージメントコンソールで複数の関数を関連付けできるように、function_associationを並べればよい。

resource "aws_cloudfront_distribution" "example" {
  # 省略
  default_cache_behavior {
    # 省略
    function_association {
      event_type   = "viewer-response" # ヘッダーはresponse側で
      function_arn = aws_cloudfront_function.security_headers.arn
    }

    function_association {
      event_type   = "viewer-request"  # ルーティングはrequest時点で
      function_arn = aws_cloudfront_function.spa_routing.arn
    }
  # 省略
}

#
# ヘッダーの追加
# security-headers.jsはaws-samplesの
# https://github.com/aws-samples/amazon-cloudfront-functions/tree/main/add-security-headers
# をベースにカスタマイズ
#
resource "aws_cloudfront_function" "security_headers" {
  name    = "security-headers"
  runtime = "cloudfront-js-1.0"
  comment = "HTTP security headers"
  publish = true
  code    = file("${path.module}/security-headers.js")
}

#
# SPAのルーティング
# spa-routing.jsはaws-samplesの
# https://github.com/aws-samples/amazon-cloudfront-functions/tree/main/url-rewrite-single-page-apps
# をベースにカスタマイズ
resource "aws_cloudfront_function" "spa_routing" {
  name    = "spa-routing"
  runtime = "cloudfront-js-1.0"
  comment = "URI rewrite for SPA"
  publish = true
  code    = file("${path.module}/spa-routing.js")
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0