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

CloudFront FunctionsでIP制限を実装する

0
Posted at

1. CloudFront Functionsとは

概要

  • CloudFrontのエッジロケーションで実行される軽量JavaScriptランタイム
  • ビューワーリクエスト/レスポンスのタイミングで処理が走る
  • 実行時間 < 1ms、メモリ 2MB という超軽量設計

特徴

  • エッジロケーションで実行されるため、超低レイテンシで処理が完結する
  • コードサイズの上限は 10KB
  • CIDR表記によるIPレンジ指定はネイティブで非対応
  • event.viewer.ip はIPv6形式で返ってくる場合がある
  • 関数内からの外部通信(HTTPリクエスト・外部API呼び出し)は不可
  • コードの保存後、必ず 「発行(Publish)」 操作が必要

2. CloudFront Functionsを選んだ理由

要件の整理

  • 単純なIPアドレスの許可・拒否のみ
  • レイテンシを最小限にしたい
  • コストを抑えたい

類似技術の説明

Lambda@Edge

  • CloudFrontと連携して動作するAWSのサーバーレス関数実行サービス
  • ビューワーリクエスト/レスポンス・オリジンリクエスト/レスポンスなど4つのフェーズで実行可能
  • 外部APIへのネットワークアクセスや複雑なロジックの実装が可能
  • 実行時間が最大30秒と長く、柔軟性が高い反面、CloudFront Functionsと比較してコストが高め

AWS WAF

  • AWSが提供するマネージド型のWebアプリケーションファイアウォール
  • IPセットを使ったIP制限をGUIから直感的に設定でき、CIDRやIPv6にもネイティブ対応
  • SQLインジェクションやXSSなど多様なセキュリティルールも適用可能
  • WebACLの維持だけで月$5〜のコストが発生するため、単純なIP制限のみの用途にはコストが見合わないケースがある

類似技術との比較

項目 CloudFront Functions Lambda@Edge AWS WAF
実行タイミング ビューワーリクエスト/レスポンス ビューワー+オリジン全4フェーズ リクエスト受信時
実行時間 最大1ms 最大30秒 -
ネットワークアクセス ❌ 不可 ✅ 可能 -
CIDR対応 ❌ 自前実装が必要 ✅ 可能 ✅ ネイティブ対応
IPv6対応 ⚠️ 要正規化処理 ✅ 可能 ✅ 可能
コスト ✅ 安価 ⚠️ やや高め ❌ 高め(WebACL $5~/月)
ユースケース 軽量な変換・制御 複雑なロジック 多様なセキュリティルール

→ CloudFront Functionsが最適だった理由

シンプルなIP制限ロジック × 低コスト × 低レイテンシの三拍子が揃っていたため

3. 前提のアーキテクチャ

構成図

CloudfrontFunctionQiita①.png

前提条件

  • AWSアカウント取得済み
  • CloudFrontディストリビューション作成済み
  • 制限したいIPアドレス(CIDR)が確定している

4. 実装手順

Step 1: CloudFront Functionsのコードを作成

function handler(event) {
    var request = event.request;
    var clientIp = event.viewer.ip;

    var allowedIps = [
       "192.168.0.0"
    ];

    if (allowedIps.indexOf(clientIp) === -1) {
        return {
            statusCode: 403,
            statusDescription: "Forbidden",
            headers: {
                "content-type": { value: "text/plain; charset=UTF-8" }
            },
            body: "Access denied"
        };
    }

    return request;
}

Step 2: AWSコンソールからFunctionをデプロイ

  1. AWSコンソール → CloudFront → Functions → 「関数を作成」

CloudfrontFunctionQiita③.png

  1. 関数名を入力(例:IPrestriction_Function)→ 「関数を作成」

CloudfrontFunctionQiita②.png

  1. Functions → 関数名(本例ではIPrestriction_Function) → Step1で作成したコードを貼り付け → 「変更を保存」

CloudfrontFunctionQiita④.png

Step 3: CloudFrontディストリビューションに関連付け

  1. AWSコンソール → CloudFront → ディストリビューション → 対象のCloudFrontディストリビューションを選択

  2. 「ビヘイビア」タブ → 対象ビヘイビア(初期で存在する優先順位が0のもの)を選択し編集

CloudfrontFunctionQiita⑤.png

  1. 「関数の関連付け - オプション」→ 関数タイプ:CloudFrontFunctions、関数ARN/名前:作成した関数名(本例ではIPrestriction_Function) → 「変更を保存」

CloudfrontFunctionQiita⑥.png

  1. 変更を保存してデプロイ完了を待つ(数分程度)

5. 注意点・躓いたポイント

⚠️ CIDR表記には非対応

CloudFront Functionsは標準でCIDR(192.168.0.0/24など)のレンジ判定ができない。
IPレンジで制限したい場合は、数値変換ロジックを自前で実装する必要がある。

// CIDR判定の実装例(IPv4のみ)
function ipToInt(ip) {
  return ip.split('.').reduce(function(acc, octet) {
    return (acc << 8) + parseInt(octet, 10);
  }, 0) >>> 0;
}

function isInCidr(ip, cidr) {
  var parts = cidr.split('/');
  var base = ipToInt(parts[0]);
  var mask = ~(Math.pow(2, 32 - parseInt(parts[1])) - 1) >>> 0;
  return (ipToInt(ip) & mask) === (base & mask);
}

⚠️ デプロイ反映に時間がかかる

CloudFrontのディストリビューション更新は全エッジへの反映に数分かかる。
テスト時は反映完了を待ってから確認すること。


6. まとめ

観点 内容
向いているケース 静的なIPリストで単純な許可/拒否制御
向いていないケース 動的IPリスト取得・CIDR多数・IPv6混在
コスト感 WAFと比較して大幅に安価

シンプルなIP制限であればCloudFront Functionsは非常に有力な選択肢であると感じた。


参考リンク

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?