「AWS無料相談会」をオンラインで開催中

Lambda@Edgeでアクセス元の国を判別してリダイレクト

あるお客様からのご相談

つい先日お客様から、

「特定のパスに対して、特定の国からのアクセスがあった場合に、別のパスに転送することは可能か?」

というご相談をいただいた。

今回は、このケースについて、 Lambda@Edge で行う方法が AWS 公式のドキュメントに例として上がっていたので、実際に試してみる。

【参考URL】
国またはデバイスタイプヘッダー別のパーソナライズ - 例

下準備

Amazon S3 で静的ウェブサイト作成

まずは、検証用のウェブサイトを Amazon S3 でサクッと設定する。

mmm-eugene-test バケットを作成して、そこに

index.html
english/index.html
german/index.html

を置く形にしてみた。

続いて静的ウェブホスティングの設定をする。
http://mmm-eugene-test.s3-website-ap-northeast-1.amazonaws.com/ でアクセスできるようになったことを確認。

Amazon CloudFront 設定

続いて Amazon CloudFront を設定する。

Origin には、先ほど作成した静的なウェブサイト、 http://mmm-eugene-test.s3-website-ap-northeast-1.amazonaws.com/ を設定する。

今回のポイントとしては、

  • CloudFront-Viewer-Country ヘッダーに基づいてキャッシュするようにディストリビューションを設定する必要がある

ということ。

設定例としては、下記のとおり、 Cache Based on Selected Request HeadersWhitelist を選択した上で、 CloudFront-Viewer-Country をホワイトリストに追加する。

Route53

せっかくなので、 Amazon Route 53 も合わせて設定する。

genetest.test.mmmcorp.co.jp と設定してみた。

海外からアクセスするために、プロキシサーバー構築

今回は、ドイツからのアクセスだけ、別のパスに転送してみたいので、 eu-central-1 (フランクフルトリージョン)に Amazon EC2 のインスタンスを作成する。

そこに、 Squid を使ってプロキシサーバーを構築。

Chrome のプロキシサーバー切り替え拡張にて、上記で構築したプロキシサーバーの設定を追加する。

Lambda@Edge 設定

【参考URL】
国またはデバイスタイプヘッダー別のパーソナライズ - 例

に記載のある例をベースに、今回は

http://genetest.test.mmmcorp.co.jp/ 来たアクセスを、

するように変更して設定。

今回は、 Lambda@Edge を利用するので、 us-east-1 (バージニア北部リージョン)に設定が必要なので要注意。

'use strict';

/* This is an origin request function */
exports.handler = (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const headers = request.headers;
    console.log(request.uri);

    if (request.uri !== '/') {
        callback(null, request);
    };

    let url = 'http://genetest.test.mmmcorp.co.jp/english/';
    if (headers['cloudfront-viewer-country']) {
        const countryCode = headers['cloudfront-viewer-country'][0].value;
        console.log(countryCode);
        if (countryCode === 'DE') {
            url = 'http://genetest.test.mmmcorp.co.jp/german/';
        }
    }

    const response = {
        status: '302',
        statusDescription: 'Found',
        headers: {
            location: [{
                key: 'Location',
                value: url,
            }],
        },
    };

    callback(null, response);
};

ドキュメントに

この例を使用するには、オリジンリクエストイベントのトリガーを作成する必要があります。

とあるとおり、 CloudFrontOrigin Request に設定する。

動作確認

まずは、普通に http://genetest.test.mmmcorp.co.jp/ にアクセスする。

次に、プロキシサーバー経由で、 http://genetest.test.mmmcorp.co.jp/ にアクセスする。

念の為、 Amazon CloudWatch Logs で出力を確認する。

普通にアクセスした場合

プロキシサーバー経由

ちゃんと国が判別できていることを確認。

よしっ (๑•̀ㅂ•́)و✧