独自ドメインを取得し、Route53 と ELB を使ってEC2上のWebアプリをHTTPS(SSL)通信に対応させてみる

こんにちは。今回は AWS の EC2 で構築しているアプリに HTTPS でアクセスできるようにしてみたいと思います。

## 前提

- EC2 上でアプリが動作していること
- nginx を使っていること

またすべて自己責任でお願いします。

## 全体像のイメージ

<img src="https://s3-ap-northeast-1.amazonaws.com/soundoflaravel/2019/09/22 22:38:49.png"> . 

## Domainを取得する
僕はこちらのサイトでドメインを取得しました。  

https://my.freenom.com/

使用したいドメインを検索して、利用できるドメインを選択します。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+16.44.59.png" alt="Domainを検索" />  


<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+16.46.03.png" alt="Domainを選択" />  
僕は無料のモノにしました。

その後、チェックアウトします。チェックアウトが完了したら右上のServicesからMy Domainsを選択します。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+16.49.57.png" alt="ドメインを確認する" /> . 

自分が登録したドメインが表示されていればOKです！

## Route53 にドメインを登録する

まずは Route53 に取得したドメインを設定していきます。
AWS のサービスから Route53 を開きます。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+16.35.27.png" alt="Route53の選択" />    

左のメニューからホストゾーンを選択し、ホストゾーンの作成をクリック。  

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+16.38.26.png" alt="ホストゾーンの選択" />

取得しておいたドメインをドメイン名に入力して、作成をクリックします。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+16.53.57.png" alt="ホストゾーンの作成" />

そうするとこんな感じでドメインが設定されていると思います。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+17.02.46.png" alt="ドメインの確認" /> . 

タイプがNSになっている4つの値を先ほどドメインを取得したサイトであるfreenom上に設定してあげます。My Domains > Manage Domainをクリック。その後、上のタブバーからManagement Toolsをクリックし、Nameserversを選択する。Route53に表示されていた4つの値をこんな感じで設定してあげます。このときに末尾のピリオドは取り除いてください。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+17.08.39.png" alt="NSの設定"/>

手元のPCのターミナル上から次のようなコマンドを入力して、次のような応答があればOKです。このときまで、IPアドレスは返ってきません。EC2上のアプリとドメインを関連づけていないので。

```
$ dig sample-domain.gq

; <<>> DiG 9.10.6 <<>> sample-domain.gq
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29220
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;sample-domain.gq.		IN	A

;; AUTHORITY SECTION:
sample-domain.gq.	900	IN	SOA	ns-951.awsdns-54.net. awsdns-hostmaster.amazon.com. 1 7200 900 1209600 86400

;; Query time: 213 msec
;; SERVER: 192.168.1.1#53(192.168.1.1)
;; WHEN: Sun Sep 22 17:10:24 JST 2019
;; MSG SIZE  rcvd: 129
```

これでネームサーバーにドメインを設定することができました。
次にドメインとEC2上のアプリを関連づけていきます。
AWSのEC2のダッシュボードを開き、左側のElasticIPをクリックします。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+17.14.42.png" alt="ElasticIPの選択"/> . 

左上の新しいアドレスの割り当てをクリックし、割り当てをクリックします。その後、一覧画面に新しく割り当てられたElasticIPが表示されるので、右上のアクションからアドレスの関連付けを選択して、Webアプリを構築しているインスタンスを選択します。
ElasticIPの値をメモしておきます。

次の手順でドメインを用いてアクセスすることができます。
再度Route53を開き、レコードセットの作成をクリック。
名前は空で、タイプはA-IPv4アドレスを選択しておきます。
そして値のところに先ほどメモしたElasticIPの値を貼り付けて作成をクリックします。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+17.22.19.png" alt="レコードセットの作成"/>

これでブラウザにそのドメインを入力すると、アクセスすることができると思います。

## SSL 証明書の取得
さあ、次にSSL 証明書を取得していきます。
AWS のサービスより Certificate Manager を検索します。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+16.30.53.png" alt="ACMの選択"/>

証明書のリクエストをクリックして、パブリック証明書のリクエストを選択します。
次の画面でドメイン名のところにさきほど取得したドメイン名を入力します。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+17.27.33.png" alt="ドメイン名の追加"/>

次はDNSの検証を選択して確認をクリックします。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+17.29.02.png" alt="DNSの検証を選択"/>

次画面の確定とリクエストをクリックして、続行をクリックするとこんな感じで検証未完了の画面になると思います。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+17.32.12.png" alt="検証未完了"/>

▶︎マークをクリックして、Route53でのレコードの作成をクリックします。
その後、Route53にドメインがCNAMEが追加されます。

これをALBを使ってHTTPS通信できるようにしていきます。
EC2のダッシュボードの左側のメニューからロードバランサーを選択し、ロードバランサーの作成をクリックします。
一番左側のApplication Load Balancerを作成します。
リスナーのところにHTTPとHTTPSを設定します。これによりクライアントからのHTTPSとHTTP通信を受け付けます。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+17.37.58.png" alt="リスナーの設定"/>

アベイラビリティーゾーンのところはすべてチェックします。僕は最初2つしかチェックせずに、このあと作成するターゲットと位置するアベイラビリティーゾーンが事なってしまったため、503エラーに悩まされましたので。。。ターゲットのアベイラビリティーゾーンとロードバランサーのアベイラビリティーゾーンを合わせれば２つでも問題ないかと思います。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+17.42.19.png" alt="証明書の選択"/>

証明書の選択のところで先ほど準備した証明書を選択して次へ進みます。
セキュリティグループは新しいセキュリティグループを作成するを選択して次のように設定します。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+18.09.04.png" alt="セキュリティグループの作成"/>

ターゲットグループは名前のところだけ、適当に入力して次に進みます。
<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+17.45.22.png" alt="ターゲットグループの設定"/>

次の画面では下の一覧表に表示されているインスタンスからWebアプリを構築しているインスタンスを選択して、登録済みに追加し、次に進みます。確認画面で問題がなければ作成をクリックします。
ロードバランサーの画面で状態がactiveになっていればOKです！
またターゲットグループ画面のしたのターゲットタブをクリックし、登録済みターゲットのステータスがhealthyになっていることも確認しておきましょう。僕はここがunsetになっていて、503エラーで半日悩んだので。。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+17.50.29.png" alt="ターゲットのステータスの確認"/>

インスタンスのセキュリティグループに先ほど作成したロードバランサーのセキュリティグループを追加していきます。
インスタンス一覧から該当のインスタンスを選択して、右スクロールしていくと、セキュリティグループという項目があると思うので、クリックします。下のインバウンドタブを選択して、編集画面をクリックします。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+18.13.55.png" alt="ターゲットのステータスの確認"/>

さていよいよ最後です。Route53で取得したドメインにきたリクエストをこのロードバランサーに振り分けてあげるように設定していきます。
Route53の先ほど作成したホストゾーンのページから最初に作成したタイプAのレコードを選択し、
エイリアスをオンにして、ターゲット名の入力のところから、ELB Application Load Balancerのところにある先ほど設定したロードバランサーを選択して、作成をクリックします。

<img src="https://soundoflaravel.s3-ap-northeast-1.amazonaws.com/2019/09/SS+2019-09-22+18.21.16.png" alt="Route53とALBの関連付け"/>

これで

https://www.ドメイン名

でアクセスしてあげれば表示されるかと思います。

ちなみにhttpでアクセスがきた場合httpsにリダイレクトするにはnginxを次のように設定して上げる必要があります。

/etc/nginx/nginx.conf

```
    if ($http_x_forwarded_proto = 'http'){
    return 301 https://$host$request_uri;
    }
```

https通信に対応するために１日以上かかってしまいましたがなんとかできるようになってよかったです。

## 参考サイト
「AWSでWebサイトをHTTPS化 その1：ELB(+ACM発行証明書)→EC2編」  
https://recipe.kc-cloud.jp/archives/11084

「EC2とELBでかんたんhttps環境構築メモ」  
http://developers.goalist.co.jp/entry/2018/09/26/170000

「AWSで独自ドメインを無料で簡単にSSL化！」  
https://daichan.club/aws/78593

「AWSでドメイン、SSL証明書の取得、設定 AWS EC2」  
https://qiita.com/masch/items/a5ef84998fb7784f9115

「ALBのヘルスチェックの豆知識」  
http://blog.serverworks.co.jp/tech/2017/02/08/alb-tagert-health-status/