S3静的ウェブホスティング+CloudFront+Lambda@EdgeでBasic認証をかける
先日、Yahoo!ジオシティーズが、2019年3月31日でサービス終了するとのことが公式サイトで発表された。
このニュースに対して、ネットでは、
「ジオシティーズが終わると大量の黒歴史が消える」
「たくさんの黒歴史が闇に葬られることになりそう」
「35歳周辺の人々、黒歴史がインターネットから消滅するのでホッとしてるのでは」
などの声が上がっていた。
【黒歴史】Yahoo!ジオシティーズがサービスを終了 「黒歴史しか残ってない」「ホッとしてるのでは」 : まとめダネ!
そんな状況を見て、
21年も続いたサービスが終了しちゃうのは寂しい感じがするな。ふーん。黒歴史ねぇ……。
なんて思って見ていたのだが……。
あーーーっ!!そういえば、大学生の頃、ジオシティーズ使ってたわ!……まだ残ってたりするんだろうか……
と思い出してしまった。
それで、ちょっと見に行ったら。なんと残っていたのだ。
当時のまま。ある意味、これは「黒歴史」と言えるのかもしれない。
これを社内のLT、通称MLT(MMM Lightning Talk)で話をしたら、思いの外チームメンバーに受けてしまい、
「世界遺産として保護すべきコンテンツ」
「S3に移行するべき」
だとか言われたり、こんな Slack のカスタムリアクションが作られてしまった。
(サイト名に「見聞録」が入っていたため)
懐かしい思いもあるので、保存しておこうとは思うが、「黒歴史」なので、アクセス制限をしなくては!
ということで、前フリが長くなったが、今回は、 S3
の静的ウェブホスティング + CloudFront
の環境に、 Lambda@Edge
を使ってBasic認証をかける手順を簡単にまとめていく。
S3にバケット作成、アップロード
まずは、S3にバケットを作成する。そして、保存したいファイルをアップロードする。
今回は、ジオシティーズからダウンロードしてきたファイルをそのまま全部突っ込んだ。
次に、静的ウェブホスティングを有効にする。
CloudFront のディストリビューション作成
CloudFront のディストリビューションを作成する。Origin Domain Name
には、先程有効にした静的ウェブホスティングのエンドポイントのURLを入力する。
Lambda@Edge 作成
続いて Lambda@Edge
を作成する。
ここでのポイントは、 Lambda
を作成するリージョンは、 米国東部(バージニア北部) リージョン としないといけないこと。
Lambda
を実行するロールは、「テンプレートから新しいロールを作成」を選択、「基本的な Lambda@Edge のアクセス権限(CloudFront トリガーの場合)」を選ぶ。
コードは下記の通り。
'use strict';
exports.handler = (event, context, callback) => {
// Get request and request headers
const request = event.Records[0].cf.request;
const headers = request.headers;
// Configure authentication
const authUser = 'hiroshi'; // ユーザー
const authPass = 'yujin'; // パスワード
// Construct the Basic Auth string
const authString = 'Basic ' + new Buffer(authUser + ':' + authPass).toString('base64');
// Require Basic authentication
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'}]
},
};
callback(null, response);
}
// Continue request processing if authentication passed
callback(null, request);
};
Lambda
関数の制限としては、下記のようなものがあるので注意が必要。
(公式ドキュメントより抜粋)
nodejs6.10
またはnodejs8.10
ランタイムプロパティを使用して関数を作成する必要があります。- VPC 内のリソースにアクセスするように
Lambda
関数を設定することはできません。 - 別の AWS アカウントによって所有されている
CloudFront
ディストリビューションにLambda
関数を関連付けることはできません。 - デッドレターキュー (DLQ) はサポートされていません。
- 環境変数はサポートされていません。
環境変数は使えないので、Basic認証の、ユーザー、パスワードもべた書きしないといけない。
Lambda トリガー設定
関数を保存したら、トリガーの設定を行う。
「トリガーの追加」項目から、 CloudFront
を選ぶ。
下部に、「Lambda@Edge へのデプロイ」が出るので、クリック。
ダイアログが出てくるので、先ほど作成した CloudFront
のディストリビューションを選択。
ここでのポイントは、「CloudFront イベント」に、「ビューアーリクエスト」を選択すること。
「デプロイ」をクリックして、デプロイする。
ちなみに、「ビューアーリクエスト」とは、CloudFront
がビューワーからリクエストを受信した後のタイミングとなる。
他のリクエストについては、下記の通りとなっているので、 Lambda
関数を実行したい適切なタイミングを指定すること。
あとは、CloudFront
の、Status
が Deployed
になるのを待ってアクセスをしてみる。
無事、Basic認証が有効になった。
(ง°`ロ°)งヨッシャ‼
CloudWatch Logs
Lambda
のログを確認する際の注意点としては、
Lambda は、関数が実行される場所に最も近い CloudWatch Logs リージョンで CloudWatch Logs ログストリームを作成する
ということ。Lambda
を作成するのは、米国東部(バージニア北部) リージョン。
ログはアクセス元に近いリージョン。
なので、焦らないように。
各ログストリームの名前の形式は、下記のようになる。
/aws/lambda/us-east-1.function-name
まとめ
いくつかの制限はあるものの、 Lambda
関数を使うと、公式ドキュメントの関数例にも記載があるとおり、Basic認証だけではなくて、かなり幅広いことができるので、今後も機会があれば積極的に使っていきたい。
最後に、一応「黒歴史」に興味ある奇特な方のために、今回設定した CloudFront
のURLを置いておく。
http://d34uznjcq34cw.cloudfront.net
Username: コードを見て
Password: コードを見て
【参考URL】
Lambda@Edge - AWS Lambda
Lambda@Edge 関数の例 - Amazon CloudFront
Lambda 関数の要件と制限 - Amazon CloudFront
Serverless: password protecting a static website in an AWS S3 bucket
CloudfrontとS3でBasic認証をかける
S3 + CloudFront + Lambda@Edge でBasic認証