Let's EncryptをCloudFront+S3で利用する

こんにちは。12月4日分の投稿を12月5日の夕方に書いています。

今日のネタはPublic BetaになったLet's Encryptを使って無料の証明書を作ってCloudFront+S3で運用されているサイトを独自ドメインHTTPSに対応してみたいと思います。

※CloudFront+S3でのサイトを構築する方法については、こちらを参考にしていただければと思います。(今回はS3バケット自体は公開しないので、ちょっとやり方が違いますが)

Amazon Web Services実践入門 (WEB+DB PRESS plus)

Amazon Web Services実践入門 (WEB+DB PRESS plus)

今回の記事で参考にしたのはこちら。
SSL setup with Let's Encrypt on AWS CloudFront and S3

S3バケットを準備する

S3のバケットを適当なリージョンに適当な名前で作成します。そして公開用コンテンツを配置しておきます。今回は前回の記事で利用したconfig_monitor_botの画像を配置しています。

f:id:matetsu:20151205163735p:plain

CloudFrontの設定をする

CloudFrontのDistributionを作成するときに「Restrict Bucket Access」を「Yes」にして、「Grant Read Permissions on Bucket」を「Yes」にしておくと、CloudFrontからOriginのS3バケットへのアクセス権を自動で設定してくれます(*1)。「Viewer Protocol Policy」は「HTTP and HTTPS」にしておいてください。

f:id:matetsu:20151205164918p:plain

CNAMEsには公開に利用したい独自ドメイン名を入力しましょう。SSL証明書の設定ですが、まずはデフォルトの *.cloudfront.net ドメインでの利用としておいてください。証明書の作成完了後に変更します。

f:id:matetsu:20151205164741p:plain

「Default Root Object」はとりあえずは画像しか無いので、その画像をしておけば良いと思います。あとは「Cretate Distribution」ボタンでDistributionが作成されます。実際にアクセスできるようになるまでは少々時間ががかるので、それまでには別の準備を進めます。

1で述べたとおり、Distributionを作成すると下のようなBucket PolicyがS3バケットに設定されます。

{
	"Version": "2008-10-17",
	"Id": "PolicyForCloudFrontPrivateContent",
	"Statement": [
		{
			"Sid": "1",
			"Effect": "Allow",
			"Principal": {
				"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity XXXXXXXXXXXXXX"
			},
			"Action": "s3:GetObject",
			"Resource": "arn:aws:s3:::BUCKETNAME/*"
		}
	]
}

Route 53でDNSの設定をする

公開に使うドメインをCloudFrontに向けるように設定をします。Route 53以外のDNSサーバではCNAMEレコードとしてさきほど作成したDistributionの「Domain Name」の欄にあるドメイン名を指定しますが、Route 53ではAレコードALIASとして指定します。Route 53でのDNS設定についてもうえで紹介した本が(ry

f:id:matetsu:20151205171343p:plain

設定が完了したら、digコマンドやhostコマンドを使って正しく設定できていることを確認して、さらにcurlなどでアクセスできることを確認してみてください。

サーバ証明書を作成する

それでは本題です。letsencrytコマンドはMac OS Xはvery experimentalとのことだし、必要なパッケージが勝手にインストールされたりするとのことで、Dockerでやることにしました(といいつつ、参考にしたサイトでもそうなっている)。

$ mkdir -p ~/tmp/le/{etc,lib}
$ docker run -it --rm --name letsencrypt \
  -v "/Users/matetsu/tmp/le/etc:/etc/letsencrypt" \
  -v "/Users/matetsu/tmp/le/lib:/var/lib/letsencrypt" \
  quay.io/letsencrypt/letsencrypt:latest \
  --agree-dev-preview \
  --server  https://acme-v01.api.letsencrypt.org/directory \
  -a manual \
  auth

なにやらTUIの画面が。emailアドレスを入れて、OK。

f:id:matetsu:20151205190955p:plain

次の画面では規約に同意するかとのことなので、規約を読んでOK。

次は証明書を発行する対象となるドメイン名をコンマ区切りか空白区切りで入力する。

f:id:matetsu:20151205191156p:plain

お主のマシンのIPアドレスを登録するけど良いかと聞かれるので、Yesとする。

次にTUIが終了して、ターミナル上にドメイン所有確認を行うための手順が記されるのでそれに従う。「Press ENTER to continue」と出ているが、準備が整うまではEnterを押さないようにしましょう。手順というのは、よくある対象ドメインの指定されたパスに指定された内容のファイルを置いて公開しておけというものです。今回は支持に従ってS3にファイルをアップロードして閲覧できるようにしておきました。

Enterを押すと、「できたでー」といった内容が表示されるので、早速確認して見る。dockerにマウントさせておいたディレクトリを確認してみましょう。

$ ls -1 /Users/matetsu/tmp/le/etc/live/DOMAIN_NAME/
.
..
cert.pem
chain.pem
fullchain.pem
privkey.pem

何やらできている感じですね。CloudFrontに設定してみましょう。まずは作成された証明書などをCloudFrontで利用できるようにアップロードします。

$ aws iam upload-server-certificate \
 --server-certificate-name CERTIFICATE_NAME \
 --certificate-body file:///Users/matetsu/tmp/le/etc/live/DOMAIN_NAME/cert.pem \
 --private-key file:///Users/matetsu/tmp/le/etc/live/DOMAIN_NAME/privkey.pem \
 --certificate-chain file:///Users/matetsu/tmp/le/etc/live/DOMAIN_NAME/chain.pem \
 --path /cloudfront/ 

そして、SNIでHTTPSが使えるようにDistributionの設定変更をします。

f:id:matetsu:20151205194353p:plain

これで設定変更を完了して、しばらく待ちましょう。

確認して見る

さて、CloudFrontのStatusがIn ProgressからDeployedになったらブラウザから確認して見ましょう(In Progressでもアクセスしているエッジによっては確認できます)。

f:id:matetsu:20151205195706p:plain

キタ━━━━(゚∀゚)━━━━!!きたきたきたー!問題なさそうですね。

おわりに

無料で簡単にSSL/TLS証明書を手に入れることができるようになってきていますね。現在有料で提供されているドメイン認証型の証明書を無料化するという話も出ているようですす、ますます総HTTPS化が捗りそうですね。あとはSNI非対応なブラウザが完全に滅びていただければ。。。

ふぅ

4日目も無事に(!?)終えることができましたので、急いで5日目に取り掛かりたいと思います。