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. 前提のアーキテクチャ
構成図
前提条件
- 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をデプロイ
- AWSコンソール → CloudFront → Functions → 「関数を作成」
- 関数名を入力(例:
IPrestriction_Function)→ 「関数を作成」
- Functions → 関数名(本例では
IPrestriction_Function) → Step1で作成したコードを貼り付け → 「変更を保存」
Step 3: CloudFrontディストリビューションに関連付け
-
AWSコンソール → CloudFront → ディストリビューション → 対象のCloudFrontディストリビューションを選択
-
「ビヘイビア」タブ → 対象ビヘイビア(初期で存在する優先順位が0のもの)を選択し編集
- 「関数の関連付け - オプション」→ 関数タイプ:CloudFrontFunctions、関数ARN/名前:作成した関数名(本例では
IPrestriction_Function) → 「変更を保存」
- 変更を保存してデプロイ完了を待つ(数分程度)
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は非常に有力な選択肢であると感じた。





