CloudFront+Lambda@Edgeでエッジコンピューティングする

GA technologies / イタンジの中村です。

技術者寄りのプロダクトマネージャーとして、プロダクト企画・開発からリサーチ・営業まで浅く広く何でも屋をしています。

CloudFrontでエッジコンピューティング?

今日は小ネタとして、n番煎じですがLambda@Edgeを利用してCloudFrontにbasic認証を掛ける方法を紹介します。 検証環境にてCloudFrontで配信する、Publicにしたくないコンテンツに何らかのアクセス制限を掛けるためには、大きく2つの方法があります。

  1. CloudFront + WAFを利用して、IPレベルの制限を掛ける
  2. CloudFront + Lambda@EdgeでBasic認証を掛ける

IPレベルでの制限を掛けた方が一般的にはより突破しにくい一方で、客先で検証中の機能をデモしたり、実際のユーザーの環境をシミュレートしたいケースでは後者を用いたいことがあります。 その場合Basic認証はHTTPとして定義されている仕様なので、コンテンツ配信を行うCloudFrontで認証を行う必要があります。

これを実現する丁度良い仕組みにCloudFrontの拡張仕様のLambda@Edgeがあります。 これを利用すると、CDNのエッジサーバでRequestをトリガーに任意のFunctionを起動する、 ある意味エッジコンピューティングが可能になります。

まず、以下のスクリプトをlambdaにdeployします。 この時、regionをus-east-1にしてください。

exports.handler = async (event) => {
    const request = event.Records[0].cf.request;
    const headers = request.headers;

    const authUser = 'user';
    const authPass = 'pass';

    const authString = 'Basic ' + new Buffer(authUser + ':' + authPass).toString('base64');

    if (typeof headers.authorization === 'undefined' || headers.authorization[0].value !== authString) {
        const body = 'Unauthorized';
        const response = {
            status: '401',
            statusDescription: 'Unauthorized',
            body: body,
            headers: {
                'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
            },
        };
        return response;
    }

    // 認証を突破したら通常のコンテンツ配信フローに戻ります
    return request;
};

次に、CloudFrontのLambda Function Associationsに対して、CloudFront EventをViewer Requestに指定して上記のlambdaのARNを設定します。 arn:aws:lambda:us-east-1:{accountId}:function:{functionName}:1 のように、デプロイバージョンまで指定してください。

以上で設定完了です。 CloudFrontに対するBasic認証なので、OriginがS3でもALBでも対応が可能です。 逆に言えば、上記でOriginへのアクセスが制限される訳ではないので、そちらはまた別の対処を行う必要がある点に留意ください。

今回はLambda@Edgeの割と一般的な用途であるbasic認証に利用しましたが、任意のスクリプトを実行できるため計算処理をエッジ側に移し、オリジンにリクエストを通さずレスポンスを行う事も可能なので是非お試しください。

参考

CloudFront Lambda@Edge での AWS Lambda の使用

Authorization@Edge using cookies: Protect your Amazon CloudFront content from being downloaded by unauthenticated users

Basic HTTP Authentication for CloudFront with Lambda@Edge