CloudFrontのLambdaで特定パスのIP制限を行う話
まえがき
はじめまして!株式会社ウェイブで国内向けのコミック配信サイト ComicFesta の開発をしてるぴらふです。
今回やりたいこと
CloudFrontに付随するLambdaを使ってパスの制御をしていたのですが、新たに試験フェーズのパスを追加することになりました。ただし、このパスは社内の特定のユーザーしか閲覧できない状態にする必要がありました。
「IP制限をかけられないか?」という話になり、CloudFrontのLambda@Edgeで対応できそうだったので実装してみました。
CloudFrontのLambda@EdgeでIP制限
今回制限をかけたいパスは hoge/:id/huga です。このパスにアクセスできるのは、特定のIPアドレスからのみとしたかったので、Lambda@EdgeでIPフィルタリングを実装しました。
実装方法
-
IPアドレスのリストを定義
-
リクエスト時にアクセス元IPを取得
-
IPが許可リストに含まれているか判定
-
許可されていなければ403エラーを返す <- 必須ではない
'use strict';
exports.handler = async (event) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
const clientIP = headers['x-forwarded-for'][0].value.split(',')[0].trim();
// 許可するIPリスト
const allowedIPs = ["192.0.2.1", "192.0.2.2"];
if (!allowedIPs.includes(clientIP)) {
return {
status: '403',
statusDescription: 'Forbidden',
body: 'Access Denied'
};
}
return request;
};
最初、許可するパスのリストを配列として持って includes で検索していたのですが、hoge/:id/huga のようなパスパラメータを含む場合には includes では対応できませんでした。
そのため、許可するパスを正規表現で管理し、マッチングを行うようにしました。
const allowedPaths = [/^\/hoge\/\d+\/huga$/];
if (!allowedPaths.some(regex => regex.test(request.uri))) {
return {
status: '403',
statusDescription: 'Forbidden',
body: 'Access Denied'
};
}
さいご
CloudFront + Lambda@Edgeで柔軟な制御ができるので、今後も色々なユースケースで活用できそうです。
「インフラは難しい」と思っていたけど、触ってみると理解が深まりました。
同じように悩んでいる人がいたら、「まずは手を動かしてみること」をおすすめします!

株式会社ウェイブのエンジニアによるテックブログです。 弊社では、電子コミック、アニメ配信などのエンタメコンテンツを自社開発で運営しております! ve.jp/service/
Discussion