0
Help us understand the problem. What are the problem?

posted at

updated at

CloudFrontによる静的Webホスティング+署名付きURLの生成

目的

LambdaでCloudFrontの署名付きURLを生成し、S3オブジェクトのキャッシングを実装。

S3とCloudFrontの直接参照は不可とする。

参考記事

【AWS】CloudFrontで署名付きURLの設定方法(プライベートコンテンツの配信)

S3

  • 新規でバケットを作成し、ファイルをアップロード
  • アクセス許可:パブリックアクセスを全てブロック
  • 静的ウェブサイトホスティング:無効

CloudFront

  • 新規ディストリビューションを作成
  • オリジンドメイン:作成したS3バケット
  • S3バケットアクセス:
    • OAIを使用(新規で作成)
    • バケットポリシー:自動更新

キーペアを生成後、「ビューアーのアクセスを制限する」を変更

キーペアの作成

今回はOpenSSLで生成

openssl genrsa -out private_key.pem 2048
openssl rsa -pubout -in private_key.pem -out public_key.pem

public_keyをAWSにアップロード

  • CloudFrontの左メニューから「パブリックキー」を選択
  • 新規で作成し、名前と内容を入力
  • メニューから「キーグループ」を選択
  • 新規で作成し、名前と、上記で作成したパブリックキーを選択し紐付ける

CloudFront Behavior

  • 作成したCloudFrontディストリビューションを選択し編集
  • 「ビヘイビア」メニューから作成済みのものを選択
  • 「ビューアーのアクセスを制限する」を設定
    • アクセスを制限する:YES
    • 信頼された認可タイプ:Trusted key groups(recommended)
    • キーグループを追加:作成したキーグループを選択

署名付きURLの発行【Lambda】

今回はNode.jsを使用

以下の手順でファイルを作成し、モジュールをzip形式でまとめる

mkdir modules
cd modules
npm i async
npm i aws-cloudfront-sign
  • modulesディレクトリに「キーペアの作成」で作成したプライベートキーと、以下のファイルを設置
index.js
exports.handler = async(event) => {
 const cloudFrontSign = require('aws-cloudfront-sign')
 const expire = new Date();
 expire.setTime(currentDate.getTime() + 24*60*60*1000);
 const signedUrl = cloudFrontSign.getSignedUrl(
  'CloudFrontのオリジンURL',
  {
   keypairId: 'キーペアID'
   privateKeyPath: '.private_key.pem',
  },
  expire
 );

 return {JSON.stringify(signedUrl)}
 
}
  • zip化
zip -r modules index.js private_key.pem node_modules/
  • 新規でLambda関数を作成
  • 「コード」メニューの「アップロード元」から、作成したzipファイルをアップロード後、デプロイ

APIゲートウェイ

  • 新規でAPIゲートウェイを作成し、メソッドを定義
  • 作成したLambda関数をAPIゲートウェイと紐付ける

動作確認

GETメソッドであればブラウザのURLから直接パスを入力して呼び出してもよし、そうでなければPostman等を使用するもよし。

返却されたURLを叩いてS3オブジェクトが参照できれば完了。

あとがき

  • 使用しているモジュールのaws-cloudfront-signが暫くサポートされていないため、aws-sdkAWS.CloudFront.Signerを使用するべき
  • Lambdaに秘密鍵を設置するのはセキュリティ的に好ましくないため、パラメータストアシークレットマネージャーを使用するべき(aws-sdkのSignerであれば、秘密鍵の情報をファイル指定ではなく文字列で渡せる

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
0
Help us understand the problem. What are the problem?