いわりょのBlog

IT関連で学んだことを書いていきます。

自作railsアプリをデプロイする 番外編 サイトをHTTPS化して通信を暗号化する

ryo10leo.hatenablog.com

上の記事を通して、以下のようなインフラを作成しました。↓

f:id:Ryo10Leo:20200113011243p:plain

EC2の中身はこんな感じです。↓

f:id:Ryo10Leo:20200115230205p:plain

今回はRailsアプリケーションをHTTPSで通信ができるようにして、セキュリティ面を向上させていきたいと思います。

HTTPS通信を軽く理解する

概要

HTTPS(Hypertext Transfer Protocol Secure)通信とは、ホームページなどの閲覧や、クライアントとサーバーと間でのデータをやりとりの際に「通信内容を暗号化して第三者からの盗聴や漏洩、改ざんを防止すること」です。

HTTPとは何が違うの?

HTTPは簡単にいうと、封がされていない手紙のような状態です。そのため誰でも閲覧することができ、改ざんも行えてしまう可能性があります。

HTTPと HTTPSの違いを図で理解する

f:id:Ryo10Leo:20200121141216p:plain

HTTP通信だと通信の内容が筒抜けなのに対して、、、

f:id:Ryo10Leo:20200121141332p:plain

HTTPS通信を使うことで「封がされた手紙のような状態」になり、内容を見られたり改ざんされる可能性が極めて低くなります。

HTTPS通信だけではセキュリティは強化できない!?

例えHTTPSで通信が暗号化されていたとしても、通信先が何かの拍子でネット犯罪者のパソコンやサーバーに誘導されてしまうことがあります。

その場合、結局のところ通信内容は盗まれてしまいます。

f:id:Ryo10Leo:20200121142155p:plain

そのため通信相手が本物であることが重要になっていきます。

そこで利用されるのが「SSL証明書」です。ここでは詳しくは書きませんが、これがあることによって通信相手が本物のサーバーであると保証されるようになっているわけです。

HTTPSをまとめると

HTTPS通信SSL証明書があることで、「通信相手が本物であると保証し、その通信を暗号化すること」でセキュリティを強化できます。

AWSでの実現方法

HTTPS通信の実現方法としては以下の記事を参考にさせていただくと、いくつかパターンがあります。↓

recipe.kc-cloud.jp

このなかで以下の方法が一番手軽にできるパターンなようです。↓

f:id:Ryo10Leo:20200121225146p:plain

簡単に説明すると、クライアントからHTTPS通信でWebサーバーのあるEC2インスタンスに通信しようとするとします。

そうすると、まずクライアントとALB(後述)間では「HTTPS通信」になります。

そして、ALBが「HTTP通信」に変換してからEC2インスタンスに通信内容を送るという動き(その逆も)です。

どうやら「ALB」というサービスを使えばHTTPS通信が実現できるようです。

これが手軽に実現できる理由としては、HTTPS通信に必要なリソースが全部 AWSで手に入れることができるからです。これは便利です。

今回はこちらのパターン使って実現して行こうと思います。

しかし実際にこの環境を作っていく前に、ある程度これから使うAWSサービスや用語などを理解してから作業に移っていきます。

ALBを軽く理解する

概要

ALB(Application Load Balancer)」とは、 AWS が提供するサービスの一つです。
主な役割としては、「複数の Web サーバーにアクセスを分散する」ことです。

ALB には複数の EC2 インスタンスを紐づけることができ、アクセスが来るたびに別のサーバに振り分けることで、負荷分散を実現します。

こう聞くと以下のように思ってしまいました。

「アクセスを分散する?それがHTTPS通信と関係ある?サーバーなんて複数運用してないし!」

しかし使いようによっては以下のようなことにも使えるようです。

HTTPS の終端として ALB を利用

Web サイトを HTTPS 化するときにも、ALB が使えます。

ALB で HTTPS を受け取り、ALB と Web サーバー間は HTTP 通信とする方法です。

このメリットは、Webサーバー側のHTTPS の暗号化処理が不要となり Web サーバーの負荷が下がることです。

なるほど、、、

Webサーバーの余計な負担も減らしてくれるんですね!

AWS Certificate Managerを軽く理解する

概要

AWS Certificate Manager(以下、ACM)とは、AWS上でSSLを利用することのできるサービスです。

普通だとSSLを利用するために、外部からSSL証明書を発行しようとすると手間やコストがかかります。

しかし AWSでは、ACMを利用することで無料で手軽にSSL証明書が発行できるため簡単に暗号化通信を実現することができます。

え?ということは、、、

「それならALB使わなくてEC2インスタンスのセキュリティグループをHTTPSにすればいいんじゃ...?」

しかしそうはいかないようです。↓

ELB,CloudFrontでのみ利用可

ACMの証明書の利用範囲は、ELB,CloudFrontでのみだそうです。

CloudFrontだと以下の記事でSSL証明書を利用しています。↓
ryo10leo.hatenablog.com

したがって、EC2インスタンスやオンプレミスサーバーに紐づけることもできません。

なるほど、、、もう一度、実現パターンの図を見ると、、、

f:id:Ryo10Leo:20200121225146p:plain

この構成なのも納得しました!

作成するものを図で理解する

実現パターンの紹介のところで何度か図を見たのでだいたいわかっていますが、インフラを全体的に見てに作るもの想像しておきます。↓

f:id:Ryo10Leo:20200121232011p:plain

ALBを設置してクライアントとの暗号化通信を担ってもらい、さらにHTTP通信に変換して、インスタンスに通信を送るのでした。

実際にHTTPS通信の設定をしてみる

前提

1. SSL証明書の発行手順は省略

SSL証明書の発行方法については、以前の「Cloud Front」の記事で取りあげたので今回は書略します。

SSL証明書については以下が参考になります。↓
blog.serverworks.co.jp

2.ドメイン取得済

今回はRoute53でドメインの設定も今回行っていきますが、ドメインも取得済でサイトとの紐付けも済んでいるので省略します。

こちらの記事のようにドメインは設定しました。↓
ryo10leo.hatenablog.com

3.VPC内にアベイラビリティーゾーンが異なるサブネットが2つ以上あること

ALBの設定で必須なので、1つしかない場合は作成しておきましょう。

ALBの設定

ダッシュボードから「ロードバランサー」→「ロードバランサーの作成」を選択。

f:id:Ryo10Leo:20200121234814p:plain

ALBの方の「作成」を選択。

f:id:Ryo10Leo:20200121235005p:plain

ALBの名前を入力。

f:id:Ryo10Leo:20200121235118p:plain

リスナーは「HTTPS」にします。ポート番号は自動で切り替わります。

f:id:Ryo10Leo:20200122000554p:plain

アベイラビリティーゾーンで2つ以上のサブネットを選択して、次へ

f:id:Ryo10Leo:20200122000741p:plain

証明書タイプは「ACM から証明書を選択する (推奨)」にして、
証明書の名前で「ACMで発行した証明書」を選択します。

f:id:Ryo10Leo:20200122004011p:plain

セキュリティグループは、「HTTPS」通信を許可します。

f:id:Ryo10Leo:20200122004359p:plain

ターゲットグループ名前を入力して次へ。

f:id:Ryo10Leo:20200122004739p:plain

ターゲットに作成したEC2インスタンスを登録します。
登録するインスタンスにチェックを入れて「登録済みに追加

次の確認画面で問題なければ「作成」をクリック。

f:id:Ryo10Leo:20200122005210p:plain

作成完了です。

Route53の設定

ryo10leo.hatenablog.com

上の記事ではホストゾーンを作成し、すでにAレコードも作成しています。

その状態を前提とし、そのAレコードに変更を加えることで設定は完了します。

Aレコードの編集画面を開きます。

f:id:Ryo10Leo:20200122010109p:plain

エイリアスを「はい」に変更し、エイリアスから先ほど作成したALBのターゲットを選択します。

そして「レコードの保存」。

全ての設定は完了です!!