HTTPS化（Django+Gunicorn+Nginx+EC2編）〜後編：HTTPS化

# 概要
[前編：ロードバランサー作成](https://qiita.com/coconuts-harm/items/c4c95d73af2009c6d902) で、AWSのELBを利用してロードバランサーの作成までを実施しました。
後編では、新たに以下のAWSのサービスを用いて、EC2インスタンスで構築済のWebサーバーをHTTPS化していきます。

- AWS Certificate Manager：証明書の取得、管理（以降では「ACM」）
- Amazon Route 53：ドメインの取得、管理（以降では「Route53」）

流れとしては、freenomで取得したフリーのドメインを用いてACMでドメイン証明書を取得し、その証明書をALBに適用します。 ALBとEC2を紐付けてインターネットからはALBに対してHTTPSで通信を行い、ALBからEC2にはHTTPでトラフィックを転送するように構築していきます。

まずは、ドメインの取得からやっていきましょう。


## ドメインの取得
#### 1. ブラウザで [freenom](https://www.freenom.com/ja/index.html) を開き、登録したいドメイン名を入力後、「Check Availability」ボタンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/b00d38b2-0327-84a9-1556-d4000ae7e8b7.png)



#### 2. 「.tk」など、使用可能なTLDの一覧が表示されるので、先ほど入力したドメインの最後尾に好きなTLDを付加して再度入力後、「Check Availability」ボタンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/11b80f37-167b-b122-b3a2-66d4a57d58af.png)


#### 3. 一致するドメインがSelectedになっていることを確認し、「Checkout」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/0480a691-00d3-e0fb-a438-056743821838.png)


#### 4. 「Continue」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/59630154-e3dd-a585-5b0e-6e63ff8bc0f7.png)


#### 5. EmailまたはGoogleなどでメール認証を行う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/193e7350-b8d1-69ab-aacd-6ed14bd44a34.png)


#### 6. 必要な情報を入力後、同意を求めるチェックボックスにチェックを入れ「Complete Order」をクリック。
※押した後はレスポンスが遅いからといって余計なことはせず、しばらく待つこと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/8b68fb31-6f27-0303-32f8-6f9554863313.png)


#### 7. 「Service > My Domain」から、取得したドメインが確認できます。このドメインは後ほど使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/81894814-c456-68df-cd41-96e2989c5d4a.png)


## Route53　ホストゾーン作成
#### 1. AWSマネジメントコンソールにてRoute 53のダッシュボードを表示し、「ホストゾーンの作成」をクリック。　
※Learer Labから実行している場合は、ダッシュボードにエラーが表示されますが、気にしないでOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/993758d2-8f1a-489d-5c2c-86ca40ed5d5c.png)

#### 2. ホストゾーン設定画面の``ドメイン名``に取得したドメインを入力し、「ホストゾーンの作成」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/542660f6-5fba-266a-de3d-e1a0e70a54a2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/4fcaab7a-ff72-19f5-c6b8-0069bfaacb1a.png)


#### 3. ホストゾーン作成後に表示された[ホストゾーンの詳細]の``ネームサーバー``に記載の内容を控えておく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/2164721e-8f5f-3bec-ddce-e4a54c14d2b1.png)


## freenom ネームサーバー設定
#### 1. ブラウザで [freenom](https://www.freenom.com/ja/index.html) にログイン後、「Service > My Domain」から、取得したドメイン一覧を表示し、使用するドメインの行にある``Manage Domain``をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/d5a47e3a-0e9b-0a51-b9ff-68fab102cdfc.png)


#### 2. 「Management Tools > Nameserver」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/80adb2a4-d6d7-1cda-bb8a-af962d2dc543.png)


#### 3. Nameservers画面で、``Use custom nameservers``を選択後、Route 53のホストゾーン作成時に控えておいたネームサーバー名を入力する。（末尾のピリオドは不要）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/aa678178-1fc0-38eb-4d96-084b30fe6225.png)

#### 3. 「Change Nameservers」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/cc15c32e-1020-e505-9f77-6f10f9407288.png)

「Changes Saved Successfully!」が表示されることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/bb28c827-7c71-1e04-a95c-613d8a3140c1.png)

## SSL証明書の発行
#### 1. PuttyでEC2インスタンスに接続し、以下のコマンドで証明書発行に必要なツールをインストール。
```bash:コマンド
sudo amazon-linux-extras install epel
sudo yum install certbot
```

#### 2. nginx.confをviエディタで編集し、下記内容を追加。
```bash:コマンド
#　nginx.confを修正
sudo vi /etc/nginx/nginx.conf
```

```bash:nginx.conf
    :(省略)
    server {
        :(省略)
        # 2022/11/24追記 
        # server_nameに特定のIPアドレスを入れていると
        # SSL証明書発行でなぜかうまくいかない現象があったので、「_」に変更しました。
        server_name  _;

        :(省略)

        # ▼追加▼
        location /.well-known/acme-challenge {
                root /usr/share/nginx/html;
        }
        # ▲追加▲
        error_page 404 /404.html;
        location = /404.html {
        }
        :(省略)

```

#### 3. nginx.confの構文チェック
```bash:コマンド
sudo nginx -t
#下記のように出力されたらOK
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```
※エラーが出た場合は、エラー内容にしたがってnginx.confを修正する。

#### 4. Nginxの再起動
```bash:コマンド
# nginx再起動
sudo systemctl restart nginx.service
# 状態の確認
sudo systemctl status nginx.service
```


#### 5. SSL証明書発行（検証）
```bash:コマンド
sudo certbot certonly --webroot -w /usr/share/nginx/html -d 【ドメイン名】 -m 【連絡用メールアドレス】 --agree-tos --dry-run
```

「Some challenges have failed.」などと失敗した場合は、以下のコマンドで詳細を確認し、対処を行ってください。

```bash:コマンド
# 「-n」オプションの後の数値は出力する行数の指定
sudo tail -n 100 /var/log/letsencrypt/letsencrypt.log
```

#### 6. SSL証明書発行
```bash:コマンド
sudo certbot certonly --webroot -w /usr/share/nginx/html -d 【ドメイン名】 -m 【連絡用メールアドレス】 --agree-tos
```
**<font color="red">
※このコマンドを数回試行して「There were too many requests of a given type :: Error creating new order」このエラーが出てしまったら、１週間は該当ドメインの検証はできません。
なので、まずは前の手順の「--dry-run」のオプションを付けたコマンドで検証してからこの手順のコマンドを実行してください。
</font>**


実行すると以下のような結果が出力されます。
fullchain.pem、privkey.pemの場所が表示されていればOKです。

```bash:結果
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Requesting a certificate for 【ドメイン名】 
Performing the following challenges:
http-01 challenge for 【ドメイン名】 
Using the webroot path /usr/share/nginx/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges
Subscribe to the EFF mailing list (email: 【連絡用メールアドレス】).

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/【ドメイン名】/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/【ドメイン名】/privkey.pem
   Your certificate will expire on 2023-02-19. To obtain a new or
   tweaked version of this certificate in the future, simply run
   certbot again. To non-interactively renew *all* of your
   certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

```

#### 7. 以下の3ファイルの値を全て控えておく。
**※各ファイルの先頭の「-----BEGIN PRIVATE KEY-----」から「-----END CERTIFICATE-----」の終わりまでを控えておくこと。**
- 証明書本文
```bash:コマンド
sudo cat /etc/letsencrypt/live/【ドメイン名】/cert.pem
```
- 証明書のプライベートキー
```bash:コマンド
sudo cat /etc/letsencrypt/live/【ドメイン名】/privkey.pem
```
- 証明書チェーン
```bash:コマンド
sudo cat /etc/letsencrypt/live/【ドメイン名】/chain.pem
```


## ACMへの証明書登録
#### 1. AWSマネジメントコンソールにてAWS Certificate Manager (ACM)の証明書一覧を表示し、「インポート」をクリック。　
※Learer Labから実行している場合は、上部にエラーが表示されますが、気にしないでOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/6290442c-94bb-6dbd-d5dd-3781e9ea774e.png)


#### 2. SSL証明書発行で控えておいた3ファイルの値をそれぞれの欄に入力し、「次へ」をクリック。
**※各ファイルの先頭の「-----BEGIN PRIVATE KEY-----」から「-----END CERTIFICATE-----」の終わりまでを入力すること。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/c0b31899-d389-3925-6958-0e6a98961059.png)

#### 3. デフォルトのまま「次へ」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/a43f56d6-ba98-37da-4287-d2c67a6381d9.png)

#### 4. 確認画面が表示されるので、「インポート」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/b99a4ca8-53a2-b7dd-cd2c-fed2ea4a706e.png)


#### 5. インポート完了後、証明書一覧に「発行済み」のステータスで追加されていることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/11f51a0c-edd8-2ca6-a02e-6716f45392ea.png)



## Route53にAレコードを追加
#### 1. 作成したホストゾーンの「レコードを作成」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/952fd939-8064-e439-c072-e2b6f8c39494.png)


#### 2. 表示された画面にて、以下の通り入力し、「レコードを作成」をクリック。
- レコードタイプに「A - IPv4・・・」を選択。
- 「エイリアス」をON。
- トラフィックのルーティング先にて、「Application Load Balancerへのエイリアス」、ELBのあるリージョン、作成したELBを選択。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/31e13b95-53b2-83fd-f1f9-d88fc805500e.png)


#### 以下のようにAレコードが追加されたことを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/dad3dfe5-9391-9be7-8166-7ce798ccd448.png)



## ELBのリスナー設定
#### 1. AWSマネジメントコンソールにてEC2のダッシュボードに移動し、左側のメニューから「ロードバランサー」を選択し、一覧から作成したロードバランサーのNameリンクをクリック。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/cdeb91a0-9e45-0ea7-a0c0-6ef5ab9c5252.png)

#### 2. 「Add listener」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/af1edf7d-1b2d-4f67-dda6-8d76b679b8b1.png)

#### 3. Protocol：``HTTPS``、Port：``443``を入力、Default actionは``Forword``を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/d134fe39-221c-204f-6950-e4d6b1a0565b.png)


#### 4. Default actionのTarget groupより、作成したターゲットグループを選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/f96c72bc-4958-5082-34d4-d504b43ef4d7.png)


#### 5. [Default SSL/TLS certificate]で``From ACM``を選択し、先ほど登録したACMの証明書を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/4f628943-f28c-e662-e5a5-1f53a63f8312.png)


#### 6. 「Add」をクリック。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/147cef65-9906-45c1-f407-ae8428576fda.png)


#### 7. 左側のメニューから「ロードバランサー」を選択し、一覧から作成したロードバランサーのNameリンクをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/29b62084-f152-19c5-2ff7-be7f3b3d8e91.png)


#### 8. 画面下の「セキュリティ」タブを選択し、「Security Group ID」リンクをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/0618d404-6b67-7e8d-8307-1e883d57037f.png)


#### 9. 画面下の「インバウンドルール」の「インバウンドのルールを編集」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/0af14a7f-cb94-f235-06a1-0235f39b077c.png)


#### 10. 「ルールを追加」をクリック後、プロトコル：``HTTPS``、ポート範囲：``443``、ソース：``Anywhere-IPv4``を入力し、「ルールを保存」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/c9f28688-7467-6b32-4957-1e7fb9a5033b.png)


## HTTPS接続確認（Chrome）
#### 1. Chromeに``https://【取得したドメイン】``を入力。

#### 2. 以下のような画面が表示されるので、「詳細」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/52f41876-42b8-fc39-be73-03fc1f7a05cb.png)

#### 3. 「安全でないこのサイトにアクセス」のリンクをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/bb4ba9ef-b16f-377e-711e-4b2e6cf5622e.png)

**表示されたら無事完了**🙌🙌🙌
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/794f7bec-08a0-55ec-547c-453d2e6d2665.png)



## 最後に
セキュリティを高めるために、もう一度EC2インスタンスのセキュリティグループや、ELBのリスナーなどの確認を行い、必要ないポートを閉じることをお勧めします。

例えば以下は、ELBのリスナーですが、本番環境においては特段の理由がない限りはHTTPSでの接続のみで良いかと思います。その場合は、HTTP:80のリスナーを削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427357/d0a91275-64a9-b08b-ebbb-ec28c74c4157.png)

また、EC2インスタンスのセキュリティグループについても、不要なポートの削除や、SSHの接続元IPを指定するなど、攻撃の機会を与えないためにも、接続を限定しましょう。