S3をWebサーバーにしてコンテンツを公開する④（CloudFront署名付きURL編）

S3をWebサーバーにして静的コンテンツを公開する方法を紹介します。

1. [S3パブリック編](https://qiita.com/morikaz/items/8d196844aed38d0d8d0b)
2. [S3署名付きURL編](https://qiita.com/morikaz/items/0d9d69e21e0863204b8e)
3. [CloudFrontパブリック編](https://qiita.com/morikaz/items/04c053ead497e2a7c86c)
4. [CloudFront署名付きURL編](https://qiita.com/morikaz/items/f3159562caa133916bce)　←コレ！
5. [CloudFront署名付きCookie編](https://qiita.com/morikaz/items/741fc1073dff746f7089)

# 手順

今回の手順は、[CloudFrontパブリック編](https://qiita.com/morikaz/items/04c053ead497e2a7c86c)の続きで実施します。
またコンテンツは以下のような構成とします。

```
/
│  index.html　　　　　←パブリック公開
│
└─private
        index.html　　←署名付きURLで公開
```

## キーペアの作成

CloudShellでキーペアを作成します。

まずはCloudShell環境にOpenSSLをインストールします。

```console
sudo yum install openssl -y
```

次にプライベートキーを作成し、

```console
openssl genrsa -out private_key.pem 2048
```

プライベートキーの中からパブリックキーを抽出します。

```console
openssl rsa -pubout -in private_key.pem -out public_key.pem
```

作成が終わったら、public_key.pemをCloudShell環境からダウンロードします。
ダウンロードは「Actions」メニューの「Download file」から実行できます。ファイル名を指定するところに「public_key.pem」を指定しましょう。

![ap-northeast-1.console.aws.amazon.com_cloudshell_home_region=ap-northeast-1(iPad) (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180441/fdbc7c4a-2e4f-2df1-c39d-78e97b273132.png)

## キーペアをCloudFrontに登録

CloudFrontのマネジメントコンソールにもどり、左のめにゅーから「Public keys」を選択します。
そして、「Add public key」を選択します。

![console.aws.amazon.com_cloudfront_home_region=ap-northeast-3(iPad) (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180441/c60df757-cbd0-ccfa-670d-49db4219c03c.png)

「Key name」には好きな名前を、「Key Value」に先程ダウンロードしたpublic_key.pemの内容を`-----BEGIN PUBLIC KEY-----`から`-----END PUBLIC KEY-----`まですべて貼り付けます。改行などもそのままでOKです。
「Comment」は空白でも構いません。
すべて入力できたら「Add」をクリックします。

![console.aws.amazon.com_cloudfront_home_region=ap-northeast-3(iPad) (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180441/cb0717e9-558a-ac82-d84c-eea9e3b67530.png)

登録が終わると、一意のIDが生成されます。このIDは後で使うので、メモっておきましょう。

次に左のメニューの「Key groups」を選択します。
「Add key groups」をクリックします。

![console.aws.amazon.com_cloudfront_home_region=ap-northeast-3(iPad) (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180441/acbc99d9-a628-e0aa-04ff-e54a47482788.png)

「Key group name」に名前を入れ、「Public keys」の中から先程登録したキーを選択し、右の「Add」をクリックします。
すると、下の表に追加されますので、その状態で「Create key group」をクリックします。

![console.aws.amazon.com_cloudfront_home_region=ap-northeast-3(iPad) (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180441/b5e0a013-f8a6-5449-34b8-f4c1facfc62b.png)

これでキーの登録は完了です。

## ディストリビューションの設定
CloudFrontパブリック編で作成したディストリビューションの詳細設定画面を開き、「Behaviors」を選択します。
「Create Behavior」をクリックします。

![console.aws.amazon.com_cloudfront_home_region=ap-northeast-3(iPad) (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180441/d20d84fc-4d61-e5cd-664e-c07f3d953469.png)

「Path Pattern」に「private/*」と入力します。

![console.aws.amazon.com_cloudfront_home_region=ap-northeast-3(iPad) (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180441/59cd135d-646b-1dea-40f6-bff4741580da.png)

「Restrict Viewer Access」をYesにし、「Trusted Key Groups」で先程作成したKey groupを選択し、右の「Add」をクリックします。
画面最下部の「Create」をクリックします。

![console.aws.amazon.com_cloudfront_home_region=ap-northeast-3(iPad) (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180441/1fd56814-54d2-7b01-84af-2a665085028d.png)

CloudFrontの設定は以上で完了です。

## 署名付きURLの発行

うまく設定ができていれば以下の様になっているはずです。

| URL | 状態 |
| --- | --- |
| index.html | パブリックアクセス可能 |
| private/index.html | パブリックアクセス不可。署名付きURLでのみアクセス可 |

試しに署名なしでprivate/index.htmlにアクセスすると以下のエラーが表示されました。

![_d168j73yp42rht.cloudfront.net_private_index.html(iPad).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180441/c27b8885-7f36-1698-80d9-9a11f1637534.png)

うまく行っているようなので、CloudShellで署名付きURLを生成したいと思います。

```console
aws cloudfront sign \
    --url https://d168j73yp42rht.cloudfront.net/private/index.html \
    --key-pair-id K2DS05WM1UJB8K \
    --private-key file://private_key.pem \
    --date-less-than 2021-03-31
```

生成されたURLには以下のパラメーターが付与されていることがわかります。

```
Expires=XXXXXXXXXX
Signature=XXXXXXXXXX
Key-Pair-Id=XXXXXXXXXX
```