CloudFrontとLambda@Edge ( Nodejs )とS3で静的ページにIPアドレス制限とBasic認証を設定する
はじめに
今回はLambda@Edge( Nodejs14 )を使ってBasic認証とIP制限を設定しました。 本記事ではLambda@Edgeについてしか触れないので、構成やCloudFront、Lambda@Edgeの設定については下記の記事に記載しています。 下記の記事はPython3で実装しており、本記事はそれのNodejs版になります。
Lambda@Edgeについて
Basic認証とIP制限について
Nodejsでbase64デコードする処理は以下のサイトを参考にしています。 docs.aws.amazon.com
- basicauth.js
'use strict'; var errorResponse = { status: '401', statusDescription: 'Unauthorized', body: 'Authentication Failed', headers: { 'www-authenticate': [ { key: 'WWW-Authenticate', value: 'Basic' } ] }, } var allowIp = ['X.X.X.X', 'X.X.X.X'] var allowUsers = { "admin": "pass1", "dev": "pass2" } exports.handler = (event, context, callback) => { const request = event.Records[0].cf.request; const headers = request.headers; const clientIp = request.clientIp if (validateClientIp(clientIp)) { callback(null, request) } if (! typeof headers.authorization) { callback(null, errorResponse) } let encodeAuth = headers.authorization[0].value.split(" "); let decodeAuth = Buffer.from(encodeAuth[1], 'base64').toString('ascii').split(":"); const requestUser = decodeAuth[0]; const requestPassword = decodeAuth[1]; if (validateAuth(requestUser, requestPassword)) { callback(null, request) } else { callback(null, errorResponse) } }; function validateAuth(user, password) { let exist_flag = false for (let key in allowUsers) { if (user === key && password === allowUsers[key]) { exist_flag = true return true; } } if (exist_flag === false) { return false; } } function validateClientIp(clientIp) { if (allowIp.indexOf(clientIp) !== -1) { return true } else { return false } }
動作確認について
CloudFrontを用意してクライアントから動作確認しなくても、CloudFrontから受け取る eventデータを Lambda@Edgeの テストイベント
に設定して確認ができます。
動作確認で設定するのは、 clientIp
にIPアドレスを、authorization
に user:password
をbasic64をエンコードした値を動作確認したい内容に応じて適宜設定します。
❯ echo -n dev:pass2 | base64 ZGV2OnBhc3My
{ "Records": [ { "cf": { "config": { "distributionId": "EXAMPLE" }, "request": { "headers": { "host": [ { "key": "Host", "value": "d123.cf.net" } ], "authorization": [ { "value": "Basic ZGV2OnBhc3My" } ], "user-name": [ { "key": "User-Name", "value": "CloudFront" } ] }, "clientIp": "0.0.0.0", "uri": "/index.html", "method": "GET" }, "response": { "status": "200", "statusDescription": "OK", "headers": { "x-cache": [ { "key": "X-Cache", "value": "Hello from Cloudfront" } ] } } } } ] }