LoginSignup
3
1

More than 1 year has passed since last update.

Laravelを本番環境時のみSSL化し、Route53とACMを利用してhttps接続を可能にする

Posted at

はじめに

この記事はプログラミング初学者による備忘録用の記事であり、また、少しでも他の初学者のお役に立てればと思い書いています。

今回は、AWSのEC2へデプロイしたLaravelアプリケーションを本番環境時のみSSL化し、Route53とACMを利用してhttpsでLaravelアプリケーションに接続する作業を行いましたので、備忘録としてまとめておきたいと思います。

間違いなどがございましたら、ご指摘のほどよろしくお願い致します。

環境変数の設定

AWSのEC2インスタンスへデプロイしたLaravelの.envファイルのAPP_ENVを確認してください。

.env
 APP_ENV=production

APP_ENVは、ローカル環境(開発環境)の場合はlocal、本番環境(デプロイ済)の場合はproductionである必要があります。

https化に対応する(Laravel側)

下記の手順に従って、https化してください。

1.AppServiceProvider.phpを編集する

AppServiceProvider.phpを下記のように編集して、本番環境時のみURLがhttpsになるようにしてください。

app/Providers/AppServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\URL; //追記

class AppServiceProvider extends ServiceProvider
{
    //略

    public function boot()
    {
        // 追記
        if (config('app.env') === 'production') {
            URL::forceScheme('https');
        }
    }
}

2.httpで接続された場合にhttpsにリダイレクトさせる

全ページをhttpsで接続されるようにするために、Middlewareを利用してhttpでの接続を全てhttpsにリダイレクトさせます。

php artisanコマンドを実行してリダイレクト用のmiddlewareを作成後、下記のように編集してください。

app/Http/Middleware/xxxx.php
<?php

namespace App\Http\Middleware;

use Closure;

class xxxx
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // 追記
        if (!$this->is_ssl() && config('app.env') === 'production') {
            return redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
        }

        return $next($request);
    }

    // 追記
    //Webサーバー毎にキーと値で判別する
    public function is_ssl()
    {
        if (isset($_SERVER['HTTPS']) === true) { // Apache
            return ($_SERVER['HTTPS'] === 'on' or $_SERVER['HTTPS'] === '1');
        }
        elseif (isset($_SERVER['SSL']) === true) { // IIS
            return ($_SERVER['SSL'] === 'on');
        }
        elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) === true) { // Reverse proxy
            return (strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https');
        }
        elseif (isset($_SERVER['HTTP_X_FORWARDED_PORT']) === true) { // Reverse proxy
            return ($_SERVER['HTTP_X_FORWARDED_PORT'] === '443');
        }
        elseif (isset($_SERVER['SERVER_PORT']) === true) {
            return ($_SERVER['SERVER_PORT'] === '443');
        }

        return false;
    }
}

3.Kernel.phpに登録する

作成したmiddlewareの内容を反映させるために、Kernel.phpのprotected $middlewareに追記します。

app/Http/Kernel.php
protected $middleware = [
        // 略
        \App\Http\Middleware\xxxx::class, // 追記
    ];

4.全プロキシを信用する

全プロキシを信用するために、TrustProxies.php*を追記します。

app\Http\Middleware\TrustProxies.php
protected $proxies = '*';

Amazon AWSや他の「クラウド」ロードバランサプロバイダを使用している場合は、実際のバランサのIPアドレスは分かりません。このような場合、全プロキシを信用するために、*を使います。
引用:Laravel6.x HTTPリクエスト

https化に対応する(AWS側)

AWS側の設定では、下記項目の設定を行う必要があります。

  • ACMでSSL証明書を作成
  • ターゲットグループの作成
  • ターゲットグループにターゲットを紐付ける
  • ロードバランサーの作成
  • Route53でホストゾーンの設定を変更する

※Route53を利用したドメイン等の設定は、リンク先を確認してください。

・1.ACMを利用してSSL証明書を作成する

1-1.証明書をリクエストする

パブリック証明書をリクエストを選択します。

スクリーンショット 2022-03-17 21.34.48(2).png

1-2.パブリック証明書のリクエストの必須項目を入力しリクエストを送る

~入力項目の説明~

・ドメイン名:
お名前.com等で購入したドメイン名を指定します。 ex)example.com

・検証方法を選択:
ドメインの所有権を検証する方法を選択してください。

今回は、DNS検証を利用します。

DNS検証を選択すると、DNSデータベースに追加する必要がある1つ以上のCNAMEレコードが自動生成されます。
これらのレコードは、ユーザーのドメインおよびアカウントに固有のものとして作成され、ドメインを制御する証拠となる一意のキーと値のペアが含まれています。
※レコードの値は、証明書を自動更新するためにACMが使用するAWSドメインを指すエイリアスです。

スクリーンショット 2022-03-17 21.42.52(2).png

リクエストを実行すると、下記のようなステータスが保留中の検証となっている証明書が発行されます。
この段階では、証明書のリクエストのみ完了しており、次のステップとして保留中の検証を実行します。

スクリーンショット 2022-03-17 21.44.08(2).png

1-3.DNS検証を実行してステータスを発行済みにする

DNS検証を実行してステータスを発行済みに変更するために、先ほどの画面でRoute53でレコードを作成を選択してください。

クリック後、下記のような画面が表示されるので、ドメイン、CNAME名、CNAME値に間違いがないか確認してください。
間違いがなければレコードを作成を選択してください。

スクリーンショット 2022-03-17 22.04.55(2).png

DNSレコードを作成後、証明書のステータスが下記のように発行済みと成功に変わっていれば証明書の発行は完了です。

スクリーンショット 2022-03-17 22.12.54(2).png

・2.ターゲットグループを作成する

2-1.ターゲットグループの作成を実行する

後ほど作成するロードバランサーで必要となるターゲットグループを作成します。

下記のような画面が表示されると思うので、Create target groupを選択して下さい。
ターゲットグループ.png

2-2.ターゲットグループ作成の必須項目を入力

下記のような画面で必須項目を入力してください。

~必要項目の説明~

・Choose a target type:
今回はEC2インスタンを利用しているので、インスタンスを選択します。

インスタンスは下記のような特徴があります。

  • 特定のVPC内のインスタンスへのロードバランシングをサポートします。
  • Amazon EC2 Auto Scalingを使用して、EC2容量を管理およびスケーリングすることを容易にします。

インスタンスIDを使用してターゲットを指定すると、トラフィックはインスタンスのプライマリネットワークインターフェイスで指定されたプライマリプライベートIPアドレスを使用して、インスタンスにルーティングされます。

・Target group name:
特定のターゲットグループ名を入力してください。

・Protocol Port:
Protocol = HTTPPort = 80を選択してください。

デフォルトでは、ロードバランサーはターゲットグループの作成時に指定したプロトコルポート番号を使用して、リクエストをターゲットにルーティングするので、プロトコルはHTTP or HTTPS、ポート番号は1 ~ 65535を選択して下さい。

・VPC:
利用するVPCを選択してください。

・Protocol version:
デフォルトでは、Application Load BalancerはHTTP/1.1を使用してターゲットにリクエストを送信します。

スクリーンショット 2022-03-17 22.26.20(2).png

・Health checks:
ヘルスチェックを実行する際のプロトコルを選択してください。

ロードバランサーは、登録されたターゲットに対して、以下の設定に従って定期的にリクエストを送信し、その状態をテスト(Health checks)します。

スクリーンショット 2022-03-17 22.26.54(2).png

上記の項目を入力後、作成を実行してください。

・3.ターゲットグループと、インスタンスを紐付ける

ターゲットグループ作成画面でNextを選択すると下記のような画面に遷移し、利用可能なインスタンスIDを指定してターゲットとして登録する必要があります。

ターゲットとなるインスタンスIDを選択して、Include as pending belowをクリックしてください。

スクリーンショット 2022-03-17 22.55.22(2).png

クリック後、ターゲット(インスタンスID)が登録実行の一覧に追加されていることを確認して、Register pending targetsをクリックしてターゲットグループとインスタンスの紐付けを実行してください。

スクリーンショット 2022-03-17 22.56.04(2).png

実行後、ターゲットグループの詳細画面で下記のように指定したインスタンスIDが登録されていることを確認して下さい。
LBにターゲットグループを登録していないのでステータスはunusedとなっています。

スクリーンショット 2022-03-17 22.57.21(2).png

・4.ロードバランサーの作成

ロードバランサーは、セキュリティポリシーとして知られているSecure Socket Layer (SSL)ネゴシエーションの設定を使用して、クライアントとSSL接続をネゴシエート(交渉)します。

4-1.Application Load Balancerを選択

EC2のメニューからロードバランサーを選択してロードバランサーの作成をクリックします。

クリック後、下のような画面が表示されるのでApplication Load Balancerを選択して下さい。
詳細は、Application Load Balancer とは?をご確認下さい。

ロードバランサー.png

4-2.基本的な設定

~入力項目の説明~

・Load balancer name:
一意なロードバランサーの名前を入力してください。

・Scheme:
今回はインターネット用ロードバランサーを作成するので、Internet-facingを選択します。

ロードバランサーの作成時に、内部用ロードバランサーにするかインターネット用ロードバランサーにするか選択する必要があります。
※ロードバランサーの作成後にスキームを変更することはできません。

・IP address type:
今回はIPv4を選択しています。

クライアントが IPv4 アドレスを使用してロードバランサーと通信する場合は IPv4 を選択し、クライアントが IPv4 と IPv6 の両方のアドレスを使用してロードバランサーと通信する場合はDualstackを選択します。
ロードバランサーが内部ロードバランサーである場合は、IPv4を選択する必要があります。

スクリーンショット 2022-03-17 23.12.07(2).png

4-3.ネットワークマッピングの設定

ネットワークマッピングでは、EC2インスタンス(ターゲット)用の仮想プライベートクラウド(VPC)を選択後、ターゲットに使用するアベイラビリティゾーンを決定し、利用するパブリックサブネットを選択します。

・VPC:
今回ターゲットとなるEC2インスタンス用の仮想プライベートクラウド(VPC)を選択します。

注意点
※ インターネットゲートウェイを持つVPCのみ選択が可能です。
※ ターゲットが使用する各アベイラビリティゾーンに、少なくとも1つのパブリックサブネットを持つ仮想プライベートクラウド(VPC) である必要があります。

・Mappings:
アベイラビリティゾーンの選択では、アプリケーションの耐障害性を高めるために、ロードバランサーで2つ以上のアベイラビリティゾーンを有効にする必要があります。

Subnetの選択では、ゾーンごとに1つのパブリックネットを選択します。
※インターネットに面したロードバランサーのサブネットには、インターネットゲートウェイへのルート が必要です。

スクリーンショット 2022-03-17 23.30.48(2).png

4-4.セキュリティーグループの選択

ロードバランサー用に新しいセキュリティグループを作成し、
ポート80で0.0.0.0/0, ::/0を許可、ポート443で0.0.0.0/0, ::/0を許可する設定を行ってください。

ロードバランサーにリスナーを追加したり、ターゲットグループのヘルスチェックポートを更新したりする際は、ロードバランサーに関連付けられたセキュリティグループが、新しいポートでのトラフィックを両方向に許可していることを確認する必要があります。

作成後、デフォルトのセキュリティグループを削除して作成したセキュリティグループを選択します。

スクリーンショット 2022-03-17 23.13.07(2).png

4-5.リスナーとルーティングの設定

Application Load Balancerの使用を開始する前に、1つまたは複数のリスナーを追加する必要があります。
リスナーとは、設定したプロトコルとポートを使用して接続リクエストをチェックするプロセスです。リスナーに対して定義したルールにより、ロードバランサーが登録済みターゲットにリクエストをルーティングする方法が決まります。

アプリケーションロードバランサーのリスナーは、次のプロトコルとポートをサポートします。

  • Protocols: HTTP, HTTPS
  • Ports: 1-65535

従って、今回はリスナーとしてHTTP:80HTTPS:443を選択しています。
デフォルトアクションでは、使用するターゲットグループを選択してターゲットグループにリクエストをルーティングします。

※各リスナーにはデフォルトのルールがあり、オプションで追加のルールを定義できます。
追加のルール設定に関する情報はリンク先を確認して下さい。

注意点
リスナーとしてHTTPS:443を選択した場合、セキュリティポリシーを設定する必要があります。

・Secure listener settings:
Secure listener settingsでは、フロントエンド接続に使用するセキュリティポリシーを選択します。(バックエンド接続には、常に ELBSecurityPolicy-2016-08 セキュリティポリシーが使用されます。)

今回は、公式で推奨されている ELBSecurityPolicy-2016-08を選択しています。

Elastic Load Balancing は、Secure Sockets Layer (SSL) ネゴシエーション設定 (セキュリティポリシーと呼ばれます) を使用して、クライアントとロードバランサー間の SSL 接続をネゴシエートします。
セキュリティポリシーはプロトコルと暗号の組み合わせです。プロトコルは、クライアントとサーバーの間の安全な接続を確立し、クライアントとロードバランサーの間で受け渡しされるすべてのデータのプライバシーを保証します。暗号とは、暗号化キーを使用してコード化されたメッセージを作成する暗号化アルゴリズムです。
プロトコルは、複数の暗号を使用し、インターネットを介してデータを暗号化します。接続ネゴシエーションのプロセスで、クライアントとロードバランサーでは、それぞれサポートされる暗号とプロトコルのリストが優先される順に表示されます。デフォルトでは、サーバーのリストで最初にクライアントの暗号と一致した暗号が安全な接続用に選択されます。
引用:Application Load Balancer 用の HTTPS リスナーを作成する セキュリティポリシー

・Default SSL certificate:
AWS Certificate Managerを使用して証明書を作成またはインポートした場合は、From ACM (ACMから) を選択して、証明書を選択します。

今回は、ACMを使用して証明書を作成したのでFrom ACMを選択します。

スクリーンショット 2022-03-17 23.19.10(2).png

上記の必要事項を入力後、作成を実行し下のような画面が表示された場合はロードバランサーの作成は成功です。

スクリーンショット 2022-03-17 23.34.03(2).png

4-6.ロードバランサーの作成後の確認

ロードバランサーの作成後、ターゲットグループ一覧に移動して対象となるターゲットグループの詳細を確認してください。
下記のように、Health statusがhealthyになっていれば大丈夫です。

スクリーンショット 2022-03-19 12.48.38(2).png

・5. Route53のホストゾーンを編集する

ホストゾーンの詳細を開き、Aレコードを編集します。

CloudFrontディストリビューションやAmazon S3バケットなど、選択したAWSリソースにトラフィックをルーティングしたい場合や、ホストゾーン内のあるレコードから別のレコードにトラフィックをルーティングしたい場合に、エイリアスを選択します。

編集画面でエイリアスを有効にし、下記項目を編集して下さい。

・エイリアスの選択:
Application Load BalancerとClassic Load Balancerへのエイリアスを選択します。

・アベイラビリティーゾーンの選択:
ap-northeast-1を選択します。

・ロードバランサーの選択:
自動予測で表示されるロードバランサーを選択します。
例)dualstack.ロードバランサー名.以下略と表示されているはずです。

・ルーティングポリシーの選択:
レコードを作成するときは、Amazon Route 53がクエリに応答する方法を決定するルーティングポリシーを選択します。
ルーティングポリシーは、Route 53がリソースにトラフィックをルーティングする方法を選択することができます。

今回は、ドメインで特定の機能を実行するリソース(EC2インスタンス上のwebサーバー)が単一なので、シンプルルーティングポリシーを使用します。

シンプルルーティングでは、Route 53 の特殊な加重ルーティングやレイテンシールーティングを使用せずに、標準のDNSレコードを設定できます。
また、通常1つのリソース (ウェブサイトのウェブサーバーなど) にトラフィックをルーティングします。

スクリーンショット 2022-03-17 23.49.50(2).png

特定のドメインを入力してhttpsで接続できることを確認する

ブラウザ上で特定のドメインを入力し、下のように鍵マークが付きhttps://でアクセスできていれば今回の作業は成功です。

スクリーンショット 2022-03-19 18.54.05.png

参考文献

DNS検証
Application Load Balancer のターゲットグループ
Application Load Balancer とは?
Application Load Balancer 用の HTTPS リスナーを作成する
Application Load Balancer のリスナー
ルーティングポリシーの選択
シンプルなエイリアスレコードに固有の値を指定する
レコードを使用する

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1