2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CloudFront Functionsによるアクセス制御

Last updated at Posted at 2023-08-10

はじめに

以前、AWS WAF によるアクセス制限(IP制限)に関して投稿した際、比較対象として2021年にリリースされたCloudFront Functions(以降 CF Functions)を取り上げました。

・昨年リリースされた新機能。Lambdaに比べ簡易なjavascriptしか書けませんが、その分低コスト、高速処理が売り。そして、スクリプトを利用することで柔軟な対応が可能。
本件ですとRequest Headerより送信元IPを判別し、任意の宛先へリダイレクトさせることも出来るかと思います。
(apacheのように時間設定も出来そうです。こちら近い内に試してみたく思います)

現在CF経由のアクセス制御にはWAFでもLambda@Edgeでもなく、全面的にCF Functionsを利用しています。そこで今回、どのように利用しているかをご紹介致します。

メリット

🔵 コストパフォーマンスがよい

◎ 引用

・前回の記事より
5-1. 本WAFの月額利用料
5-2. CloudFront Functionsの料金と比較

◎ CF Functionの利用料金

公式DocよりCF Functionsの料金 の [エッジコンピューティング][無料利用枠]より

■ 無料利用枠

2,000,000 件の CloudFront Function 呼び出し

■ 利用料金

100 万件の呼び出しあたり 0.10 USD

◎ AWS WAFとの比較

条件 : アクセス制御対象が 200万Req/mon だった場合
比較結果 : CF Functionsならば無料枠だけで対処可能。WAFだとシンプルな設定内容(※)でも 9.20USD/mon 掛かる
(※) IPアクセス制限を適用した場合。詳細は上述した前回の投稿を参照ください

◎ Lambda@Edgeとの比較

条件 : (同上)
比較結果 : CF Functionsの場合、無料で利用可。Lambda@Edgeの場合、1.2 USD + メモリ使用量別の実行時間課金

▽ 補足
Lambda@Edgeの料金

リクエスト料金は、リクエスト 100万件あたり 0.60USD
時間は、1 GB-秒の使用につき 0.00005001USD
現在、Lambda@Edge に無料利用枠はありません。

🔵 機能が充実かつ使いやすい

・CloudFrontへのアクセス(HTTP Request)制御であれば充分な機能が備わっています

  1. Serverless
    -> Lambda@Edge そして AWS WAFも同様ですね

  2. 簡易言語であるJavaScript対応 (正確にはECMAScript 5.1準拠)

  3. 処理が早い
    CloudFront Functions を使用したエッジでのカスタマイズより

    CloudFront Functions の runtime 環境は、起動時間が 1 ミリ秒未満、毎秒数百万のリクエストを処理するようにすぐにスケールでき、高い安全性を誇ります

  4. 開発が容易
    ・build/deploy不要。コンソールよりソースコード直接記入でもOK
    ※ AWS CLIによる CF Functions作成からソースコード・アップロードも可(参照)

  5. CI/CDに関して、IaCとの統合管理も可能
    ・ちなみにTerraformの一部として私は管理しています

  6. 簡易テスト機能
    ・直感的かつシンプルにテストが実施可能

  7. CWログ出力あり
    ・標準で N.Virginia の CW logsに[/aws/cloudfront/function/(Function名)] としてログが出力される

デメリット

🟣 機能面

  1. 簡易スクリプトのみ対応のため、利用できる関数や定義に制限がある

  2. 対象はCFへの Viewer Request/Viewer Responseに限られる(Origin Req/Resは対象外)

実装例

では実際にCFへのリクエスト(viewer request)に対し行っている制御を挙げます

機能一覧

  1. Basic Authentication(ベーシック認証)
  2. Path Completion(パス補完)
  3. Maintenance Mode with time control(メンテナンスモード切り替え、時間指定付き)
  4. IP restriction(アクセス元IPアドレスによる制御)
  5. referer restriction(アクセス元refererによる制御)
  6. URI(path) check(アクセス先による制御)

概要図

全体構成図

CF Functionsによるアクセス制御-全体構成(一部).png

CF Functionsによるアクセス制御部

・上記全体構成よりCF Functionsの箇所をピックアウト
CF Functionsによるアクセス制御-アクセス制御.png

コーディング

要点

・HTTP Request/Responseは、json形式のeventととしてCF Functionsで受け取ります。
そして、受け取ったオブジェクトを活用して制御していくことになります。

公式よりイベントオブジェクトの例

{
  "version": "1.0",
  "context": {
    "distributionDomainName": "d111111abcdef8.cloudfront.net",
    "distributionId": "EDFDVBD6EXAMPLE",
    "eventType": "viewer-response",
    "requestId": "EXAMPLEntjQpEXAMPLE_SG5Z-EXAMPLEPmPfEXAMPLEu3EqEXAMPLE=="
  },
  "viewer": {
    "ip": "198.51.100.11"
  },
  "request": {
    "method": "GET",
    "uri": "/media/index.mpd",
    "querystring": {
      "ID": {
        "value": "42"
      },
      "TTL": {
        "value": "1440"
      },
      (省略)
    },
    "headers": {
      "host": {
        "value": "video.example.com"
      },
      "user-agent": {
        "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0"
      },
      "accept": {
        "value": "application/json",
        "multiValue": [
          {
            "value": "application/json"
          },
          (省略)
        ]
      },
      "accept-language": {
        "value": "en-GB,en;q=0.5"
      },
      "accept-encoding": {
        "value": "gzip, deflate, br"
      },
      "origin": {
        "value": "https://website.example.com"
      },
      "referer": {
        "value": "https://website.example.com/videos/12345678?action=play"
      },
      "cloudfront-viewer-country": {
        "value": "GB"
      }
    },
    "cookies": {
      "Cookie1": {
        "value": "value1"
      },
    (省略)
    }
  },

サンプルコード

サンプルコード(私のGitHubより)

補足説明

  1. Basic Authentication(ベーシック認証)
    ・特定のRequestに対して、Basic認証をかけています

  2. Path Completion(パス補完)
    ・ファイル指定のないRequest(/で終わる)の場合、index.htmlを参照させるようにしています

  3. Maintenance Mode with time control(メンテナンスモード切り替え、時間指定付き)
    ・指定時間にメンテナンスモード(=メンテナンスページへリダイレクト)へ切り替え、指定時間に解除されるよう実装しています

  4. IP restriction(アクセス元IPアドレスによる制御)
    ・よりセキュアなアクセス領域の制限として、アクセス元のIPアドレスを評価しています

  5. referer restriction(アクセス元refererによる制御)
    ・図にありますとおり、メインサイトからのみアクセスを許可したいOriginがある場合に適用しています

  6. URI(path) check(アクセス先による制御)
    ・特定のURI(パス)への制御になります

リダイレクトにquerystringを含める場合

  1. サンプルスクリプトには含めていませんが、パスおよびqueryをリダイレクト先に引き継ぎたい場合、URIおよびquerystringもリダイレクト先に含める必要があることご注意ください。
    例)
    https://abc.example.com/index.html?region=ap-southeast-1
         ↓ (redirect)
    https://def.example.com/index.html?region=ap-southeast-1
    
  2. またquerystringが複数ある場合、それを判定し処理する必要があることも合わせてご注意ください。

参考

[aws-samples/amazon-cloudfront-functions]の issuesより

Tips

リダイレクト処理の注意点
・メンテナンスやエラー画面へのリダイレクト処理に関しまして
解除後にCFおよびブラウザのキャッシュにより、想定通りの挙動とならないことがあります。その対処方法としまして、リダイレクト先のパスをCF Behaviorとして登録。そして、object cachingをしない様に設定しておくとスムースに切り替えることが出来るかと思います。
behavior no caching.png
図. behaviorにて特定パス(リダイレクト先)ではcacheしないよう設定

2
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?