CloudFrontで独自ドメインSSL設定


## やりたいこと

S3に静的コンテンツをあげていて、S3へのアクセスを独自ドメインなHTTPSアクセスにしたかったんだけど...

### 調べてわかったこと

S3は現時点でSSL(HTTPS)対応していなく、CloudFrontを経由でアクセスする方法があるみたいでした。

また、 **執筆時点(2015/7/22)でCloudFrontにSSL証明書をアップロードするにはCLIツール経由でアップロードする必要がある**みたいでした。

> 別の方法がある場合教えて欲しいです汗

## 手順

ということで手順です。

* 1. AWS CLI(コマンドラインツール)のインストール&セットアップ
* 2. SSL証明書の作成
* 3. AWS CLI経由でSSL証明書をアップロード
* 4. CloudFrontの設定

こんな感じでほぼほぼターミナル(CLI)作業になります。

## 1. AWS CLI(コマンドラインツール)のインストール&セットアップ

[AWS CLIのインストールから初期設定メモ](http://qiita.com/n0bisuke/items/1ea245318283fa118f4a)を見てください〜

## 2. SSL証明書の作成

今回はGlobalSignで登録しました。

こちらの記事([ELBにSSLを設定してみる](http://qiita.com/higehiki/items/a86748984025ffc75582))がすごく参考になりました。

> 弊社のまろCの記事もオススメです ([AWSのELBでSSLの証明書を設定する方法（2015年5月版）](http://liginc.co.jp/web/programming/server/164756))

* SSL証明書の申請が終わったら、管理画面から「PKCS#12」ファイルをダウンロードします。

`hogehoge.pfx`をダウンロードしたとします。以下のコマンドで鍵ファイルを作成します。

パスワードを聞かれますが、GlobalSignの場合は「申請時に登録した文字列」+「GlobalSignさんで発行された文字列」です。

```mac
$ openssl pkcs12 -in hogehoge.pfx -nocerts -nodes -out server.key
$ openssl pkcs12 -in hogehoge.pfx -clcerts -nodes -out server.crt
$ openssl pkcs12 -in hogehoge.pfx -cacerts -nokeys -out server.ca-bundle
```

> ELBに登録する場合はserver.keyのパスフレーズを削除する作業があるみたいですが、CloudFrontへの登録はこのままで大丈夫です。

確認します。

```
$ ls
hogehoge.pfx server.ca-bundle   server.key   server.crt        
```

こんな感じで.pfxから３つの鍵ファイルが生成されます。

* server.key 秘密鍵
* server.crt SSL証明書
* server.ca-bundle 中間証明書

## 3. AWS CLI経由でSSL証明書をアップロード

先ほどの3つの情報をAWS CLIでアップロードします。AWS CLIはセットアップを済ませておきましょう。

ここがハマりポイントみたいですね。

> 参考: [AWS CloudFront用にSSL証明書をアップロードする](http://qiita.com/syuhei/items/83cfbf29a32785c8bbc6)
> 参考: [devrel.jpをCloudFront NSIを使ってHTTPS化するまでの流れ](https://devrel.jp/blog/2015/04/S3-SSL/)

コマンドはこんな感じです。IAMを使う必要があるみたいですね。

```コマンド
$ aws iam upload-server-certificate --server-certificate-name 任意の名前 --path /cloudfront/ --private-key file://秘密鍵のパス --certificate-body file://SSL証明書のパス --certificate-chain file://中間証明書のパス
```

`file://`の後に各鍵ファイルのパスを記述します。

↑で生成したファイル名でそのまま実行するとこんな感じ↓のコマンドになります。

```
$ aws iam upload-server-certificate --server-certificate-name ssl.corona --path /cloudfront/ --private-key file://server.key --certificate-body file://server.crt --certificate-chain file://server.ca-bundle
```

これでアップロード完了です。 `ssl.corona`という名前で登録しました。

### おまけ: エラー発生

私の場合ここでエラーが発生しました。

```
A client error (MalformedCertificate) occurred when calling the UploadServerCertificate operation: Certificate body is invalid. The body must not contain a private key.
```

こんな感じのエラー内容です。調べてもイマイチ情報は見つけられなかったのですが、どうやら **`server.crt`の中身に`private key`の情報が含まれているみたいで、それが問題っぽいです。**

エディタでserver.crtを編集しました。

```server.crt
Bag Attributes
    localKeyID: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX 
Key Attributes: <No Attributes>
-----BEGIN RSA PRIVATE KEY-----
・
・
・
(省略)
・
・
・
-----END RSA PRIVATE KEY-----

Bag Attributes
    localKeyID: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX 
subject=xxxxx
issuer=xxx
-----BEGIN CERTIFICATE-----
・
・
・
(省略)
```

みたいな感じのファイルになっているのですが、`private key`の情報が含まれているのがまずいみたいなので、このうち **テキストの最初から`-----END RSA PRIVATE KEY-----`までを削除**しました。

```編集後のserver.crt
Bag Attributes
    localKeyID: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX 
subject=xxxxx
issuer=xxx
-----BEGIN CERTIFICATE-----
・
・
・
(省略)
```

編集後に再度コマンドを実行したらエラーなくSSL証明書の情報がアップロードされました。

## 4. CloudFrontの設定

> ここに来て執筆に力尽きたので、端折りたいのですが、

CloudFrontの管理画面でSSLの設定項目があるのですが、これはAWS CLIからSSL証明書情報のアップロードをする前だと独自ドメイン設定の`Custom SSL Certificate`の項目が選択出来ないようになっています。
![](http://i.gyazo.com/a6300834d56347ba97865139d9d5c945.png)

↑の3の手順で証明書アップロードが終わると

![](http://i.gyazo.com/a772b7fc4602989ba1ec3b527b1eec44.png)

こんな感じで設定出来ます。

S3側の設定は ~~(執筆に)力尽きたので~~ 参考サイト([[CloudFront + S3]特定バケットに特定ディストリビューションのみからアクセスできるよう設定する](http://dev.classmethod.jp/cloud/aws/cloudfront-s3-origin-access-identity/))を参照してください。

##まとめ

CloudFrontで独自ドメインのSSLを使う場合にちょっとハマったってところも含めたメモでした。
CLIからじゃないと登録できないって部分はいずれ改善されると思います。