【備忘録】AWS(EC2)へデプロイしたアプリをSSL化し、セキュリティを担保する手順（Let's Encryptを使用）（ALBは使わない）

# はじめに
- 本記事は、備忘録としてまとめたものになります。
- 他の方の参考になる可能性も踏まえて、一般公開も行なっております。
- また記載内容はすべて、正しい内容が記載されているとは限りません。
- 誤った内容を見つけた場合は、ご指摘をお願いいたします。

# この記事は誰向けの記事か？
- AWS(EC2)で稼働させているアプリをSSL化したい人
- TechCampのポートフォリオ作成で、SSL化したいが困っている人
- 費用を抑えつつ、SSL化したい人
- AWS(ALB)を用いず、SSL化したい人（ALBは稼働に相当費用がかかるため、Let’s Encryptを用いたい人）

# 背景
- 自分のアプリ（ポートフォリオ）を、SSL化したいと思ったことがきっかけで実装することになった。
- TechCampへ参加し、オリジナルアプリを、Herokuにデプロイしていたが、その有料化に伴い、RenderやAWSを使うことになった。
- AWS(EC2)にアプリをデプロイしたが、通信プロトコルがHTTPSではなく、HTTPがデフォルトだった。
- プロトコルがHTTPだった場合、クリップボードへのコピー機能が正常に動かないなど、実装や運用に影響があった。
- メール機能を用いたお問い合わせフォームなどを実装したとしても情報流出の恐れがあったため、セキュリティ面でユーザーの不安が拭えなかった。
- 以上の背景から、AWS(EC2)で稼働させているアプリを、SSL化することとなった。ただし条件として低予算で行うことを条件として、行なった。

# 開発環境
OS：MAC
ブラウザ：GoogleChrome
開発言語：Ruby on Rails
開発環境：AWS(EC2、Route53）、Nginx
その他：Let's Encrypt

# 今回、行なったこと（実績）
- ドメインの購入
IPアドレスだけではSSL化できないため、任意のドメインを取得する必要がありました。そのため今回は、AWS上で購入しました。（AWS以外のサイトでも入手可能でAWSより安価の可能性もあります）
- DNS登録
ドメイン名とIPアドレスを紐付け、名前解決させる必要があったため、Route53へ実装しました。
- Let’s Encryptの導入
SSL化するにあたり、フリーで自動化されたオープンな認証局を導入しました。
- 443番ポートの解放
通常のHTTPでは80番ポートを使用しているのに対し、HTTPSでは443番ポートを使用しようします。そのため443番ポートで通信ができるように、ポートの穴あけを行いました。より厳密には、EC2のインバウンドルールを設定しました。
- Webサーバー(Ngixn)の設定を変更
Nginxの設定値を設定し直し、HTTPSのプロトコルで通信ができるように変更した。

# ドメインの購入
参考ページ
https://blog.serverworks.co.jp/route53-domain-registration
https://dev.classmethod.jp/articles/route53-domain-2019/
https://qiita.com/NaokiIshimura/items/89e104dd2d8dd950780e
https://hiyowa-na-engineer.com/aws-get-domain/
私は、[~~~.link]のドメインを購入し、年間5ドルの費用が掛かっています。

# DNS登録
参考ページ
https://qiita.com/yuichi1992_west/items/e842d8ee50c4afd88775
https://zenn.dev/banana/articles/96b5373114b3d1
Route53上で、EC2とドメインを紐付けします。最後に、ドメイン名にアクセスし、アプリが使えることを確認してください。なおRoute53は月額0.5ドルの費用が掛かり、アクセス数に応じて料金が少しずつ加算されていきます。

# Let's Encryptの導入
参考ページ
https://www.youtube.com/watch?v=13NTn6WiQvU&list=LL&index=35&t=467s
- certbotのインストール
- SSL証明書の取得
- 443ポートの解放
- 証明書の自動更新設定
こちらの動画を参考にさせていただきました　。動画では、Nginxではなく、Appachを使用しているので、少し注意が必要です。なおALB（アプリケーションロードバランサー）を使用してSSL化させる方法もあるらしいですが、ALBを使用した場合、料金が予算オーバーすることに気づいたので、急遽Let's Encryptを導入する方針に変えました。

# Webサーバー(Ngixn)の設定を変更
以下のように、Ngixnの設定を変更して対応しました。特に設定を変更していなければ、/etc/nginx/nginx.confにファイルがあると思います。
※一部、セキュリティに関わる箇所があるため、改変しています。TechCampへ参加している人であれば、何を記述すれば良いか、分かると思います。


    upstream app_server2 {
        server unix:/var/www/アプリ名/shared/tmp/sockets/unicorn.sock;
    }

    server {
        server_name  取得したドメイン名;
        root         /var/www/アプリ名/public;

        include /etc/nginx/default.d/*.conf;

        client_max_body_size 2g;

        location ^~ /assets/ {
          ※非公開
          root /var/www/アプリ名/current/public;
          }

        try_files $uri/index.html $uri @unicorn;

        location @unicorn {
           ※非公開
        }

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/ドメイン名/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/ドメイン名/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

# 費用に関して
今回、SSL化するにあたり、以下のような感じで費用が掛かっています。なお消費税の分がかかるので少し注意が必要です。
- ドメインの取得:年間5ドルの契約
- Route53の使用料：月額0.5ドル＋アクセス数に応じた課金額
- 税金分：月額0.05ドル程度

ざっくり計算ですが、年間2500円程度かかるくらいですかね？
ドメイン料金：5ドル ＋ Route53料金：月額1ドルと仮定 × 12ヶ月 = 約17ドル = 約2400円
※AWSの無料枠の期間だったので、それらにかかる費用は無視しています。
![スクリーンショット 2023-02-12 23.05.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/d4017279-86be-0f81-5733-65735a9ef4eb.png)
![スクリーンショット 2023-02-12 23.09.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/eca66de0-41a3-948a-2d4e-915a351049c9.png)